Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, 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 : // EnergyPlus Headers
52 : #include <EnergyPlus/Autosizing/Base.hh>
53 : #include <EnergyPlus/BranchNodeConnections.hh>
54 : #include <EnergyPlus/CurveManager.hh>
55 : #include <EnergyPlus/Data/EnergyPlusData.hh>
56 : #include <EnergyPlus/DataEnvironment.hh>
57 : #include <EnergyPlus/DataHVACGlobals.hh>
58 : #include <EnergyPlus/DataIPShortCuts.hh>
59 : #include <EnergyPlus/DataLoopNode.hh>
60 : #include <EnergyPlus/DataSizing.hh>
61 : #include <EnergyPlus/FluidProperties.hh>
62 : #include <EnergyPlus/General.hh>
63 : #include <EnergyPlus/GlobalNames.hh>
64 : #include <EnergyPlus/HeatPumpWaterToWaterSimple.hh>
65 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
66 : #include <EnergyPlus/NodeInputManager.hh>
67 : #include <EnergyPlus/OutputProcessor.hh>
68 : #include <EnergyPlus/OutputReportPredefined.hh>
69 : #include <EnergyPlus/Plant/DataPlant.hh>
70 : #include <EnergyPlus/Plant/PlantLocation.hh>
71 : #include <EnergyPlus/PlantComponent.hh>
72 : #include <EnergyPlus/PlantUtilities.hh>
73 : #include <EnergyPlus/UtilityRoutines.hh>
74 :
75 : namespace EnergyPlus::HeatPumpWaterToWaterSimple {
76 :
77 : // MODULE INFORMATION:
78 : // AUTHOR Kenneth Tang
79 : // DATE WRITTEN March 2005
80 : // MODIFIED Brent Griffith, plant upgrades, fluid properties
81 :
82 : // PURPOSE OF THIS MODULE:
83 : // This module simulates a Water-to-Water Heat Pump Simple (Equation-Fit Model)
84 :
85 : // METHODOLOGY EMPLOYED:
86 : // This simulation is based on a set of coefficients in quadlinear curves generated from
87 : // the manufacturer catalog data using the generalized least square method
88 :
89 : // REFERENCES:
90 : // (1) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
91 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
92 : // Oklahoma State University. (downloadable from http://www.hvac.okstate.edu/)
93 : // (2) Murugappan, Arun. 2002. Implementing Ground Source Heat Pump and Ground
94 : // Loop Heat Exchanger Models in the EnergyPlus Simulation Environment,
95 : // M.S. Thesis, Department of Mechanical and Aerospace Engineering,
96 : // Oklahoma State University. (downloadable from http://www.hvac.okstate.edu/)
97 :
98 : // MODULE PARAMETER DEFINITIONS
99 : std::string const HPEqFitHeating = "HeatPump:WatertoWater:EquationFit:Heating";
100 : std::string const HPEqFitHeatingUC = "HEATPUMP:WATERTOWATER:EQUATIONFIT:HEATING";
101 : std::string const HPEqFitCooling = "HeatPump:WatertoWater:EquationFit:Cooling";
102 : std::string const HPEqFitCoolingUC = "HEATPUMP:WATERTOWATER:EQUATIONFIT:COOLING";
103 :
104 8 : GshpSpecs *GshpSpecs::factory(EnergyPlusData &state, DataPlant::PlantEquipmentType wwhp_type, std::string_view eir_wwhp_name)
105 : {
106 8 : if (state.dataHPWaterToWaterSimple->GetInputFlag) {
107 2 : GshpSpecs::GetWatertoWaterHPInput(state);
108 2 : state.dataHPWaterToWaterSimple->GetInputFlag = false;
109 : }
110 :
111 : auto thisObj =
112 8 : std::find_if(state.dataHPWaterToWaterSimple->GSHP.begin(),
113 8 : state.dataHPWaterToWaterSimple->GSHP.end(),
114 12 : [&eir_wwhp_name, &wwhp_type](const GshpSpecs &myObj) { return (myObj.Name == eir_wwhp_name && myObj.WWHPType == wwhp_type); });
115 8 : if (thisObj != state.dataHPWaterToWaterSimple->GSHP.end()) return thisObj;
116 :
117 0 : ShowFatalError(state, format("EquationFit_WWHP factory: Error getting inputs for wwhp named: {}", eir_wwhp_name));
118 0 : return nullptr;
119 : }
120 :
121 136170 : void GshpSpecs::simulate(EnergyPlusData &state,
122 : const PlantLocation &calledFromLocation,
123 : bool const FirstHVACIteration,
124 : Real64 &CurLoad,
125 : [[maybe_unused]] bool const RunFlag)
126 : {
127 136170 : if (this->WWHPType == DataPlant::PlantEquipmentType::HPWaterEFCooling) {
128 68085 : if (calledFromLocation.loopNum == this->LoadPlantLoc.loopNum) { // chilled water loop
129 34043 : this->InitWatertoWaterHP(state, this->WWHPType, this->Name, FirstHVACIteration, CurLoad);
130 34043 : this->CalcWatertoWaterHPCooling(state, CurLoad);
131 34043 : this->UpdateGSHPRecords(state);
132 34042 : } else if (calledFromLocation.loopNum == this->SourcePlantLoc.loopNum) { // condenser loop
133 34042 : PlantUtilities::UpdateChillerComponentCondenserSide(state,
134 : this->SourcePlantLoc.loopNum,
135 : this->SourcePlantLoc.loopSideNum,
136 : DataPlant::PlantEquipmentType::HPWaterEFCooling,
137 : this->SourceSideInletNodeNum,
138 : this->SourceSideOutletNodeNum,
139 : this->reportQSource,
140 : this->reportSourceSideInletTemp,
141 : this->reportSourceSideOutletTemp,
142 : this->reportSourceSideMassFlowRate,
143 : FirstHVACIteration);
144 : } else {
145 0 : ShowFatalError(state, format("SimHPWatertoWaterSimple:: Invalid loop connection {}, Requested Unit={}", HPEqFitCooling, this->Name));
146 : }
147 68085 : } else if (this->WWHPType == DataPlant::PlantEquipmentType::HPWaterEFHeating) {
148 68085 : if (calledFromLocation.loopNum == this->LoadPlantLoc.loopNum) { // chilled water loop
149 34043 : this->InitWatertoWaterHP(state, this->WWHPType, this->Name, FirstHVACIteration, CurLoad);
150 34043 : this->CalcWatertoWaterHPHeating(state, CurLoad);
151 34043 : this->UpdateGSHPRecords(state);
152 34042 : } else if (calledFromLocation.loopNum == this->SourcePlantLoc.loopNum) { // condenser loop
153 34042 : PlantUtilities::UpdateChillerComponentCondenserSide(state,
154 : this->SourcePlantLoc.loopNum,
155 : this->SourcePlantLoc.loopSideNum,
156 : DataPlant::PlantEquipmentType::HPWaterEFHeating,
157 : this->SourceSideInletNodeNum,
158 : this->SourceSideOutletNodeNum,
159 34042 : -this->reportQSource,
160 : this->reportSourceSideInletTemp,
161 : this->reportSourceSideOutletTemp,
162 : this->reportSourceSideMassFlowRate,
163 : FirstHVACIteration);
164 : } else {
165 0 : ShowFatalError(state, format("SimHPWatertoWaterSimple:: Invalid loop connection {}, Requested Unit={}", HPEqFitCooling, this->Name));
166 : }
167 : } else {
168 0 : ShowFatalError(state, "SimHPWatertoWaterSimple: Module called with incorrect GSHPType");
169 : } // TypeOfEquip
170 136170 : }
171 :
172 40 : void GshpSpecs::onInitLoopEquip(EnergyPlusData &state, [[maybe_unused]] const PlantLocation &calledFromLocation)
173 : {
174 40 : bool initFirstHVAC = true;
175 40 : Real64 initCurLoad = 0.0;
176 :
177 40 : this->InitWatertoWaterHP(state, this->WWHPType, this->Name, initFirstHVAC, initCurLoad);
178 40 : if (this->WWHPType == DataPlant::PlantEquipmentType::HPWaterEFCooling) {
179 20 : this->sizeCoolingWaterToWaterHP(state);
180 20 : } else if (this->WWHPType == DataPlant::PlantEquipmentType::HPWaterEFHeating) {
181 20 : this->sizeHeatingWaterToWaterHP(state);
182 : }
183 40 : }
184 :
185 40 : void GshpSpecs::getDesignCapacities(EnergyPlusData &state, const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
186 : {
187 40 : if (calledFromLocation.loopNum == this->LoadPlantLoc.loopNum) {
188 20 : if (this->WWHPType == DataPlant::PlantEquipmentType::HPWaterEFCooling) {
189 10 : MinLoad = 0.0;
190 10 : MaxLoad = this->RatedCapCool;
191 10 : OptLoad = this->RatedCapCool;
192 10 : } else if (this->WWHPType == DataPlant::PlantEquipmentType::HPWaterEFHeating) {
193 10 : MinLoad = 0.0;
194 10 : MaxLoad = this->RatedCapHeat;
195 10 : OptLoad = this->RatedCapHeat;
196 : } else {
197 0 : ShowFatalError(state, "SimHPWatertoWaterSimple: Module called with incorrect GSHPType");
198 : }
199 : } else {
200 20 : MinLoad = 0.0;
201 20 : MaxLoad = 0.0;
202 20 : OptLoad = 0.0;
203 : }
204 40 : }
205 :
206 8 : void GshpSpecs::getSizingFactor(Real64 &sizingFactor)
207 : {
208 8 : sizingFactor = this->sizFac;
209 8 : }
210 :
211 2 : void GshpSpecs::GetWatertoWaterHPInput(EnergyPlusData &state)
212 : {
213 :
214 : // SUBROUTINE INFORMATION:
215 : // AUTHOR Kenneth Tang
216 : // DATE WRITTEN March 2005
217 :
218 : // PURPOSE OF THIS SUBROUTINE:
219 : // Obtain input from IDF and store them in data structures
220 :
221 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
222 : int NumAlphas; // Number of elements in the alpha array
223 : int NumNums; // Number of elements in the numeric array
224 : int IOStat; // IO Status when calling get input subroutine
225 :
226 2 : bool ErrorsFound = false;
227 :
228 2 : int NumCoolCoil = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HPEqFitCoolingUC);
229 2 : int NumHeatCoil = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HPEqFitHeatingUC);
230 2 : state.dataHPWaterToWaterSimple->NumGSHPs = NumCoolCoil + NumHeatCoil;
231 :
232 2 : if (state.dataHPWaterToWaterSimple->NumGSHPs <= 0) {
233 0 : ShowSevereError(state, "GetEquationFitWaterToWater Input: No Equipment found");
234 0 : ErrorsFound = true;
235 : }
236 :
237 2 : if (state.dataHPWaterToWaterSimple->NumGSHPs > 0) {
238 2 : state.dataHPWaterToWaterSimple->GSHP.allocate(state.dataHPWaterToWaterSimple->NumGSHPs);
239 2 : state.dataHPWaterToWaterSimple->HeatPumpWaterUniqueNames.reserve(state.dataHPWaterToWaterSimple->NumGSHPs);
240 : }
241 :
242 : // Load data structure for cooling coil
243 4 : for (int HPNum = 1; HPNum <= NumCoolCoil; ++HPNum) {
244 :
245 2 : auto &thisGSHP = state.dataHPWaterToWaterSimple->GSHP(HPNum);
246 :
247 4 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
248 : HPEqFitCoolingUC,
249 : HPNum,
250 2 : state.dataIPShortCut->cAlphaArgs,
251 : NumAlphas,
252 2 : state.dataIPShortCut->rNumericArgs,
253 : NumNums,
254 : IOStat,
255 2 : state.dataIPShortCut->lNumericFieldBlanks,
256 2 : state.dataIPShortCut->lAlphaFieldBlanks);
257 2 : GlobalNames::VerifyUniqueInterObjectName(
258 2 : state, state.dataHPWaterToWaterSimple->HeatPumpWaterUniqueNames, state.dataIPShortCut->cAlphaArgs(1), HPEqFitCoolingUC, ErrorsFound);
259 2 : thisGSHP.WWHPType = DataPlant::PlantEquipmentType::HPWaterEFCooling;
260 2 : thisGSHP.Name = state.dataIPShortCut->cAlphaArgs(1);
261 2 : thisGSHP.RatedLoadVolFlowCool = state.dataIPShortCut->rNumericArgs(1);
262 2 : if (thisGSHP.RatedLoadVolFlowCool == DataSizing::AutoSize) {
263 1 : thisGSHP.ratedLoadVolFlowCoolWasAutoSized = true;
264 : }
265 2 : thisGSHP.RatedSourceVolFlowCool = state.dataIPShortCut->rNumericArgs(2);
266 2 : if (thisGSHP.RatedSourceVolFlowCool == DataSizing::AutoSize) {
267 1 : thisGSHP.ratedSourceVolFlowCoolWasAutoSized = true;
268 : }
269 2 : thisGSHP.RatedCapCool = state.dataIPShortCut->rNumericArgs(3);
270 2 : if (thisGSHP.RatedCapCool == DataSizing::AutoSize) {
271 1 : thisGSHP.ratedCapCoolWasAutoSized = true;
272 : }
273 2 : thisGSHP.RatedPowerCool = state.dataIPShortCut->rNumericArgs(4);
274 2 : if (thisGSHP.RatedPowerCool == DataSizing::AutoSize) {
275 1 : thisGSHP.ratedPowerCoolWasAutoSized = true;
276 : }
277 2 : thisGSHP.CoolCapCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(6));
278 2 : thisGSHP.CoolPowCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(7));
279 2 : if (thisGSHP.CoolCapCurveIndex > 0) {
280 2 : ErrorsFound |= Curve::CheckCurveDims(
281 : state, thisGSHP.CoolCapCurveIndex, {4}, "GetWatertoWaterHPInput", HPEqFitCoolingUC, thisGSHP.Name, "Cooling Capacity Curve Name");
282 : }
283 2 : if (thisGSHP.CoolPowCurveIndex > 0) {
284 2 : ErrorsFound |= Curve::CheckCurveDims(state,
285 : thisGSHP.CoolPowCurveIndex,
286 : {4},
287 : "GetWatertoWaterHPInput",
288 : HPEqFitCoolingUC,
289 : thisGSHP.Name,
290 : "Cooling Compressor Power Curve Name");
291 : }
292 :
293 2 : if (NumNums > 4) {
294 1 : if (!state.dataIPShortCut->lNumericFieldBlanks(5)) {
295 1 : thisGSHP.refCOP = state.dataIPShortCut->rNumericArgs(5);
296 : } else {
297 0 : thisGSHP.refCOP = 8.0;
298 : }
299 :
300 : } else {
301 1 : thisGSHP.refCOP = 8.0;
302 : }
303 :
304 : // calculate reference COP if hard sized
305 2 : if (!thisGSHP.ratedPowerCoolWasAutoSized && !thisGSHP.ratedCapCoolWasAutoSized && thisGSHP.RatedPowerCool > 0.0) {
306 1 : thisGSHP.refCOP = thisGSHP.RatedCapCool / thisGSHP.RatedPowerCool;
307 : }
308 :
309 2 : if (NumNums > 5) {
310 1 : if (!state.dataIPShortCut->lNumericFieldBlanks(6)) {
311 1 : thisGSHP.sizFac = state.dataIPShortCut->rNumericArgs(6);
312 : } else {
313 0 : thisGSHP.sizFac = 1.0;
314 : }
315 : } else {
316 1 : thisGSHP.sizFac = 1.0;
317 : }
318 :
319 2 : thisGSHP.SourceSideInletNodeNum = GetOnlySingleNode(state,
320 2 : state.dataIPShortCut->cAlphaArgs(2),
321 : ErrorsFound,
322 : DataLoopNode::ConnectionObjectType::HeatPumpWaterToWaterEquationFitCooling,
323 2 : state.dataIPShortCut->cAlphaArgs(1),
324 : DataLoopNode::NodeFluidType::Water,
325 : DataLoopNode::ConnectionType::Inlet,
326 : NodeInputManager::CompFluidStream::Primary,
327 : DataLoopNode::ObjectIsNotParent);
328 :
329 2 : thisGSHP.SourceSideOutletNodeNum = GetOnlySingleNode(state,
330 2 : state.dataIPShortCut->cAlphaArgs(3),
331 : ErrorsFound,
332 : DataLoopNode::ConnectionObjectType::HeatPumpWaterToWaterEquationFitCooling,
333 2 : state.dataIPShortCut->cAlphaArgs(1),
334 : DataLoopNode::NodeFluidType::Water,
335 : DataLoopNode::ConnectionType::Outlet,
336 : NodeInputManager::CompFluidStream::Primary,
337 : DataLoopNode::ObjectIsNotParent);
338 :
339 2 : thisGSHP.LoadSideInletNodeNum = GetOnlySingleNode(state,
340 2 : state.dataIPShortCut->cAlphaArgs(4),
341 : ErrorsFound,
342 : DataLoopNode::ConnectionObjectType::HeatPumpWaterToWaterEquationFitCooling,
343 2 : state.dataIPShortCut->cAlphaArgs(1),
344 : DataLoopNode::NodeFluidType::Water,
345 : DataLoopNode::ConnectionType::Inlet,
346 : NodeInputManager::CompFluidStream::Secondary,
347 : DataLoopNode::ObjectIsNotParent);
348 :
349 2 : thisGSHP.LoadSideOutletNodeNum = GetOnlySingleNode(state,
350 2 : state.dataIPShortCut->cAlphaArgs(5),
351 : ErrorsFound,
352 : DataLoopNode::ConnectionObjectType::HeatPumpWaterToWaterEquationFitCooling,
353 2 : state.dataIPShortCut->cAlphaArgs(1),
354 : DataLoopNode::NodeFluidType::Water,
355 : DataLoopNode::ConnectionType::Outlet,
356 : NodeInputManager::CompFluidStream::Secondary,
357 : DataLoopNode::ObjectIsNotParent);
358 :
359 : // Test node sets
360 4 : BranchNodeConnections::TestCompSet(state,
361 : HPEqFitCoolingUC,
362 2 : state.dataIPShortCut->cAlphaArgs(1),
363 2 : state.dataIPShortCut->cAlphaArgs(2),
364 2 : state.dataIPShortCut->cAlphaArgs(3),
365 : "Condenser Water Nodes");
366 4 : BranchNodeConnections::TestCompSet(state,
367 : HPEqFitCoolingUC,
368 2 : state.dataIPShortCut->cAlphaArgs(1),
369 2 : state.dataIPShortCut->cAlphaArgs(4),
370 2 : state.dataIPShortCut->cAlphaArgs(5),
371 : "Chilled Water Nodes");
372 :
373 2 : if (NumAlphas > 7 && !state.dataIPShortCut->lAlphaFieldBlanks(8)) {
374 1 : thisGSHP.companionName = state.dataIPShortCut->cAlphaArgs(8);
375 : }
376 :
377 : // CurrentModuleObject='HeatPump:WatertoWater:EquationFit:Cooling'
378 4 : SetupOutputVariable(state,
379 : "Heat Pump Electricity Energy",
380 : Constant::Units::J,
381 2 : thisGSHP.reportEnergy,
382 : OutputProcessor::TimeStepType::System,
383 : OutputProcessor::StoreType::Sum,
384 2 : thisGSHP.Name,
385 : Constant::eResource::Electricity,
386 : OutputProcessor::Group::Plant,
387 : OutputProcessor::EndUseCat::Cooling);
388 4 : SetupOutputVariable(state,
389 : "Heat Pump Load Side Heat Transfer Energy",
390 : Constant::Units::J,
391 2 : thisGSHP.reportQLoadEnergy,
392 : OutputProcessor::TimeStepType::System,
393 : OutputProcessor::StoreType::Sum,
394 2 : thisGSHP.Name);
395 4 : SetupOutputVariable(state,
396 : "Heat Pump Source Side Heat Transfer Energy",
397 : Constant::Units::J,
398 2 : thisGSHP.reportQSourceEnergy,
399 : OutputProcessor::TimeStepType::System,
400 : OutputProcessor::StoreType::Sum,
401 2 : thisGSHP.Name);
402 : }
403 :
404 : // Load data structure for heating coil
405 4 : for (int HPNum = 1; HPNum <= NumHeatCoil; ++HPNum) {
406 :
407 2 : int GSHPNum = NumCoolCoil + HPNum;
408 2 : auto &thisGSHP = state.dataHPWaterToWaterSimple->GSHP(GSHPNum);
409 :
410 4 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
411 : HPEqFitHeatingUC,
412 : HPNum,
413 2 : state.dataIPShortCut->cAlphaArgs,
414 : NumAlphas,
415 2 : state.dataIPShortCut->rNumericArgs,
416 : NumNums,
417 : IOStat,
418 2 : state.dataIPShortCut->lNumericFieldBlanks,
419 2 : state.dataIPShortCut->lAlphaFieldBlanks);
420 2 : GlobalNames::VerifyUniqueInterObjectName(
421 2 : state, state.dataHPWaterToWaterSimple->HeatPumpWaterUniqueNames, state.dataIPShortCut->cAlphaArgs(1), HPEqFitHeatingUC, ErrorsFound);
422 2 : thisGSHP.WWHPType = DataPlant::PlantEquipmentType::HPWaterEFHeating;
423 2 : thisGSHP.Name = state.dataIPShortCut->cAlphaArgs(1);
424 2 : thisGSHP.RatedLoadVolFlowHeat = state.dataIPShortCut->rNumericArgs(1);
425 2 : if (thisGSHP.RatedLoadVolFlowHeat == DataSizing::AutoSize) {
426 1 : thisGSHP.ratedLoadVolFlowHeatWasAutoSized = true;
427 : }
428 2 : thisGSHP.RatedSourceVolFlowHeat = state.dataIPShortCut->rNumericArgs(2);
429 2 : if (thisGSHP.RatedSourceVolFlowHeat == DataSizing::AutoSize) {
430 1 : thisGSHP.ratedSourceVolFlowHeatWasAutoSized = true;
431 : }
432 2 : thisGSHP.RatedCapHeat = state.dataIPShortCut->rNumericArgs(3);
433 2 : if (thisGSHP.RatedCapHeat == DataSizing::AutoSize) {
434 1 : thisGSHP.ratedCapHeatWasAutoSized = true;
435 : }
436 2 : thisGSHP.RatedPowerHeat = state.dataIPShortCut->rNumericArgs(4);
437 2 : if (thisGSHP.RatedPowerHeat == DataSizing::AutoSize) {
438 1 : thisGSHP.ratedPowerHeatWasAutoSized = true;
439 : }
440 :
441 2 : thisGSHP.HeatCapCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(6));
442 2 : thisGSHP.HeatPowCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(7));
443 2 : if (thisGSHP.HeatCapCurveIndex > 0) {
444 2 : ErrorsFound |= Curve::CheckCurveDims(
445 : state, thisGSHP.HeatCapCurveIndex, {4}, "GetWatertoWaterHPInput", HPEqFitHeatingUC, thisGSHP.Name, "Heating Capacity Curve Name");
446 : }
447 2 : if (thisGSHP.HeatPowCurveIndex > 0) {
448 2 : ErrorsFound |= Curve::CheckCurveDims(state,
449 : thisGSHP.HeatPowCurveIndex,
450 : {4},
451 : "GetWatertoWaterHPInput",
452 : HPEqFitHeatingUC,
453 : thisGSHP.Name,
454 : "Heating Compressor Power Curve Name");
455 : }
456 2 : if (NumNums > 4) {
457 1 : if (!state.dataIPShortCut->lNumericFieldBlanks(5)) {
458 1 : thisGSHP.refCOP = state.dataIPShortCut->rNumericArgs(5);
459 : } else {
460 0 : thisGSHP.refCOP = 7.5;
461 : }
462 :
463 : } else {
464 1 : thisGSHP.refCOP = 7.5;
465 : }
466 :
467 : // calculate reference COP if hard sized
468 2 : if (!thisGSHP.ratedPowerHeatWasAutoSized && !thisGSHP.ratedCapHeatWasAutoSized && thisGSHP.RatedPowerHeat > 0.0) {
469 1 : thisGSHP.refCOP = thisGSHP.RatedCapHeat / thisGSHP.RatedPowerHeat;
470 : }
471 :
472 2 : if (NumNums > 5) {
473 1 : if (!state.dataIPShortCut->lNumericFieldBlanks(6)) {
474 1 : thisGSHP.sizFac = state.dataIPShortCut->rNumericArgs(6);
475 : } else {
476 0 : thisGSHP.sizFac = 1.0;
477 : }
478 : } else {
479 1 : thisGSHP.sizFac = 1.0;
480 : }
481 :
482 2 : thisGSHP.SourceSideInletNodeNum = GetOnlySingleNode(state,
483 2 : state.dataIPShortCut->cAlphaArgs(2),
484 : ErrorsFound,
485 : DataLoopNode::ConnectionObjectType::HeatPumpWaterToWaterEquationFitHeating,
486 2 : state.dataIPShortCut->cAlphaArgs(1),
487 : DataLoopNode::NodeFluidType::Water,
488 : DataLoopNode::ConnectionType::Inlet,
489 : NodeInputManager::CompFluidStream::Primary,
490 : DataLoopNode::ObjectIsNotParent);
491 :
492 2 : thisGSHP.SourceSideOutletNodeNum = GetOnlySingleNode(state,
493 2 : state.dataIPShortCut->cAlphaArgs(3),
494 : ErrorsFound,
495 : DataLoopNode::ConnectionObjectType::HeatPumpWaterToWaterEquationFitHeating,
496 2 : state.dataIPShortCut->cAlphaArgs(1),
497 : DataLoopNode::NodeFluidType::Water,
498 : DataLoopNode::ConnectionType::Outlet,
499 : NodeInputManager::CompFluidStream::Primary,
500 : DataLoopNode::ObjectIsNotParent);
501 :
502 2 : thisGSHP.LoadSideInletNodeNum = GetOnlySingleNode(state,
503 2 : state.dataIPShortCut->cAlphaArgs(4),
504 : ErrorsFound,
505 : DataLoopNode::ConnectionObjectType::HeatPumpWaterToWaterEquationFitHeating,
506 2 : state.dataIPShortCut->cAlphaArgs(1),
507 : DataLoopNode::NodeFluidType::Water,
508 : DataLoopNode::ConnectionType::Inlet,
509 : NodeInputManager::CompFluidStream::Secondary,
510 : DataLoopNode::ObjectIsNotParent);
511 :
512 2 : thisGSHP.LoadSideOutletNodeNum = GetOnlySingleNode(state,
513 2 : state.dataIPShortCut->cAlphaArgs(5),
514 : ErrorsFound,
515 : DataLoopNode::ConnectionObjectType::HeatPumpWaterToWaterEquationFitHeating,
516 2 : state.dataIPShortCut->cAlphaArgs(1),
517 : DataLoopNode::NodeFluidType::Water,
518 : DataLoopNode::ConnectionType::Outlet,
519 : NodeInputManager::CompFluidStream::Secondary,
520 : DataLoopNode::ObjectIsNotParent);
521 :
522 2 : if (NumAlphas > 7 && !state.dataIPShortCut->lAlphaFieldBlanks(8)) {
523 1 : thisGSHP.companionName = state.dataIPShortCut->cAlphaArgs(8);
524 : }
525 :
526 : // Test node sets
527 4 : BranchNodeConnections::TestCompSet(state,
528 : HPEqFitHeatingUC,
529 2 : state.dataIPShortCut->cAlphaArgs(1),
530 2 : state.dataIPShortCut->cAlphaArgs(2),
531 2 : state.dataIPShortCut->cAlphaArgs(3),
532 : "Condenser Water Nodes");
533 4 : BranchNodeConnections::TestCompSet(state,
534 : HPEqFitHeatingUC,
535 2 : state.dataIPShortCut->cAlphaArgs(1),
536 2 : state.dataIPShortCut->cAlphaArgs(4),
537 2 : state.dataIPShortCut->cAlphaArgs(5),
538 : "Hot Water Nodes");
539 :
540 : // CurrentModuleObject='HeatPump:WatertoWater:EquationFit:Heating'
541 4 : SetupOutputVariable(state,
542 : "Heat Pump Electricity Energy",
543 : Constant::Units::J,
544 2 : thisGSHP.reportEnergy,
545 : OutputProcessor::TimeStepType::System,
546 : OutputProcessor::StoreType::Sum,
547 2 : thisGSHP.Name,
548 : Constant::eResource::Electricity,
549 : OutputProcessor::Group::Plant,
550 : OutputProcessor::EndUseCat::Heating);
551 4 : SetupOutputVariable(state,
552 : "Heat Pump Load Side Heat Transfer Energy",
553 : Constant::Units::J,
554 2 : thisGSHP.reportQLoadEnergy,
555 : OutputProcessor::TimeStepType::System,
556 : OutputProcessor::StoreType::Sum,
557 2 : thisGSHP.Name);
558 4 : SetupOutputVariable(state,
559 : "Heat Pump Source Side Heat Transfer Energy",
560 : Constant::Units::J,
561 2 : thisGSHP.reportQSourceEnergy,
562 : OutputProcessor::TimeStepType::System,
563 : OutputProcessor::StoreType::Sum,
564 2 : thisGSHP.Name);
565 : }
566 :
567 : // now process companion coils, if any
568 6 : for (int GSHPNum = 1; GSHPNum <= state.dataHPWaterToWaterSimple->NumGSHPs; ++GSHPNum) {
569 4 : auto &thisGSHP = state.dataHPWaterToWaterSimple->GSHP(GSHPNum);
570 4 : if (!thisGSHP.companionName.empty()) {
571 2 : thisGSHP.companionIndex = Util::FindItemInList(thisGSHP.companionName, state.dataHPWaterToWaterSimple->GSHP);
572 2 : if (thisGSHP.companionIndex == 0) {
573 0 : ShowSevereError(state,
574 0 : format("GetEquationFitWaterToWater Input: did not find companion heat pump named '{}' in heat pump called {}",
575 0 : thisGSHP.companionName,
576 0 : thisGSHP.Name));
577 0 : ErrorsFound = true;
578 : } else {
579 2 : thisGSHP.companionIdentified = true;
580 : }
581 : }
582 : }
583 :
584 2 : if (ErrorsFound) {
585 0 : ShowFatalError(state, "Errors found in processing input for Water to Water Heat Pumps");
586 : }
587 :
588 6 : for (int GSHPNum = 1; GSHPNum <= state.dataHPWaterToWaterSimple->NumGSHPs; ++GSHPNum) {
589 4 : auto &thisGSHP = state.dataHPWaterToWaterSimple->GSHP(GSHPNum);
590 : // setup output variables
591 8 : SetupOutputVariable(state,
592 : "Heat Pump Electricity Rate",
593 : Constant::Units::W,
594 4 : thisGSHP.reportPower,
595 : OutputProcessor::TimeStepType::System,
596 : OutputProcessor::StoreType::Average,
597 4 : thisGSHP.Name);
598 8 : SetupOutputVariable(state,
599 : "Heat Pump Load Side Heat Transfer Rate",
600 : Constant::Units::W,
601 4 : thisGSHP.reportQLoad,
602 : OutputProcessor::TimeStepType::System,
603 : OutputProcessor::StoreType::Average,
604 4 : thisGSHP.Name);
605 8 : SetupOutputVariable(state,
606 : "Heat Pump Source Side Heat Transfer Rate",
607 : Constant::Units::W,
608 4 : thisGSHP.reportQSource,
609 : OutputProcessor::TimeStepType::System,
610 : OutputProcessor::StoreType::Average,
611 4 : thisGSHP.Name);
612 8 : SetupOutputVariable(state,
613 : "Heat Pump Load Side Outlet Temperature",
614 : Constant::Units::C,
615 4 : thisGSHP.reportLoadSideOutletTemp,
616 : OutputProcessor::TimeStepType::System,
617 : OutputProcessor::StoreType::Average,
618 4 : thisGSHP.Name);
619 8 : SetupOutputVariable(state,
620 : "Heat Pump Load Side Inlet Temperature",
621 : Constant::Units::C,
622 4 : thisGSHP.reportLoadSideInletTemp,
623 : OutputProcessor::TimeStepType::System,
624 : OutputProcessor::StoreType::Average,
625 4 : thisGSHP.Name);
626 8 : SetupOutputVariable(state,
627 : "Heat Pump Source Side Outlet Temperature",
628 : Constant::Units::C,
629 4 : thisGSHP.reportSourceSideOutletTemp,
630 : OutputProcessor::TimeStepType::System,
631 : OutputProcessor::StoreType::Average,
632 4 : thisGSHP.Name);
633 8 : SetupOutputVariable(state,
634 : "Heat Pump Source Side Inlet Temperature",
635 : Constant::Units::C,
636 4 : thisGSHP.reportSourceSideInletTemp,
637 : OutputProcessor::TimeStepType::System,
638 : OutputProcessor::StoreType::Average,
639 4 : thisGSHP.Name);
640 8 : SetupOutputVariable(state,
641 : "Heat Pump Load Side Mass Flow Rate",
642 : Constant::Units::kg_s,
643 4 : thisGSHP.reportLoadSideMassFlowRate,
644 : OutputProcessor::TimeStepType::System,
645 : OutputProcessor::StoreType::Average,
646 4 : thisGSHP.Name);
647 8 : SetupOutputVariable(state,
648 : "Heat Pump Source Side Mass Flow Rate",
649 : Constant::Units::kg_s,
650 4 : thisGSHP.reportSourceSideMassFlowRate,
651 : OutputProcessor::TimeStepType::System,
652 : OutputProcessor::StoreType::Average,
653 4 : thisGSHP.Name);
654 : }
655 2 : }
656 :
657 68126 : void GshpSpecs::InitWatertoWaterHP(EnergyPlusData &state,
658 : DataPlant::PlantEquipmentType const GSHPTypeNum, // Type of GSHP
659 : [[maybe_unused]] std::string const &GSHPName, // User Specified Name of GSHP
660 : [[maybe_unused]] bool const FirstHVACIteration,
661 : Real64 const MyLoad // Demand Load
662 : )
663 : {
664 :
665 : // SUBROUTINE INFORMATION:
666 : // AUTHOR Kenneth Tang
667 : // DATE WRITTEN March 2005
668 :
669 : // PURPOSE OF THIS SUBROUTINE:
670 : // This subroutine is for initializations of the Water-to-Water HP Simple
671 :
672 : // METHODOLOGY EMPLOYED:
673 : // Uses the status flags to trigger initializations.
674 :
675 : // REFERENCES:
676 : // (1) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
677 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
678 : // Oklahoma State University. (downloadable from http://www.hvac.okstate.edu/)
679 : // (2) Murugappan, Arun. 2002. Implementing Ground Source Heat Pump and Ground
680 : // Loop Heat Exchanger Models in the EnergyPlus Simulation Environment,
681 : // M.S. Thesis, Department of Mechanical and Aerospace Engineering,
682 : // Oklahoma State University. (downloadable from http://www.hvac.okstate.edu/)
683 :
684 : // SUBROUTINE PARAMETER DEFINITIONS:
685 : static constexpr std::string_view RoutineName("InitGshp");
686 :
687 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
688 : int LoadSideInletNode; // Load Side Inlet Node
689 : int SourceSideInletNode; // Source Side Inlet Node
690 : Real64 rho; // local fluid density
691 :
692 68126 : this->MustRun = true; // Reset MustRun flag to TRUE
693 68126 : LoadSideInletNode = this->LoadSideInletNodeNum;
694 68126 : SourceSideInletNode = this->SourceSideInletNodeNum;
695 :
696 68126 : if (this->MyPlantScanFlag) {
697 4 : bool errFlag = false;
698 12 : PlantUtilities::ScanPlantLoopsForObject(
699 8 : state, this->Name, this->WWHPType, this->SourcePlantLoc, errFlag, _, _, _, this->SourceSideInletNodeNum, _);
700 12 : PlantUtilities::ScanPlantLoopsForObject(
701 8 : state, this->Name, this->WWHPType, this->LoadPlantLoc, errFlag, _, _, _, this->LoadSideInletNodeNum, _);
702 :
703 4 : if (!errFlag) {
704 4 : PlantUtilities::InterConnectTwoPlantLoopSides(state, this->LoadPlantLoc, this->SourcePlantLoc, this->WWHPType, true);
705 : }
706 :
707 4 : if (errFlag) {
708 0 : ShowFatalError(state, "GetWatertoWaterHPInput: Program terminated on scan for loop data");
709 : }
710 4 : this->MyPlantScanFlag = false;
711 : }
712 :
713 68126 : if (this->MyEnvrnFlag && state.dataGlobal->BeginEnvrnFlag) {
714 : // Initialize all report variables to a known state at beginning of simulation
715 :
716 24 : this->reportPower = 0.0;
717 24 : this->reportEnergy = 0.0;
718 24 : this->reportQLoad = 0.0;
719 24 : this->reportQLoadEnergy = 0.0;
720 24 : this->reportQSource = 0.0;
721 24 : this->reportQSourceEnergy = 0.0;
722 24 : this->reportLoadSideMassFlowRate = 0.0;
723 24 : this->reportLoadSideInletTemp = 0.0;
724 24 : this->reportLoadSideOutletTemp = 0.0;
725 24 : this->reportSourceSideMassFlowRate = 0.0;
726 24 : this->reportSourceSideInletTemp = 0.0;
727 24 : this->reportSourceSideOutletTemp = 0.0;
728 24 : this->IsOn = false;
729 24 : this->MustRun = true;
730 :
731 24 : if (this->WWHPType == DataPlant::PlantEquipmentType::HPWaterEFHeating) {
732 12 : rho = FluidProperties::GetDensityGlycol(state,
733 12 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
734 : Constant::HWInitConvTemp,
735 12 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
736 : RoutineName);
737 12 : this->LoadSideDesignMassFlow = this->RatedLoadVolFlowHeat * rho;
738 12 : rho = FluidProperties::GetDensityGlycol(state,
739 12 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidName,
740 : Constant::CWInitConvTemp,
741 12 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidIndex,
742 : RoutineName);
743 12 : this->SourceSideDesignMassFlow = this->RatedSourceVolFlowHeat * rho;
744 12 : } else if (this->WWHPType == DataPlant::PlantEquipmentType::HPWaterEFCooling) {
745 12 : rho = FluidProperties::GetDensityGlycol(state,
746 12 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
747 : Constant::CWInitConvTemp,
748 12 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
749 : RoutineName);
750 12 : this->LoadSideDesignMassFlow = this->RatedLoadVolFlowCool * rho;
751 12 : rho = FluidProperties::GetDensityGlycol(state,
752 12 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidName,
753 : Constant::HWInitConvTemp,
754 12 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidIndex,
755 : RoutineName);
756 12 : this->SourceSideDesignMassFlow = this->RatedSourceVolFlowCool * rho;
757 : }
758 :
759 24 : PlantUtilities::InitComponentNodes(state, 0.0, this->LoadSideDesignMassFlow, this->LoadSideInletNodeNum, this->LoadSideOutletNodeNum);
760 :
761 24 : PlantUtilities::InitComponentNodes(state, 0.0, this->SourceSideDesignMassFlow, this->SourceSideInletNodeNum, this->SourceSideOutletNodeNum);
762 :
763 24 : if (state.dataLoopNodes->Node(this->SourceSideOutletNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue)
764 16 : state.dataLoopNodes->Node(this->SourceSideOutletNodeNum).TempSetPoint = 0.0;
765 24 : state.dataLoopNodes->Node(this->SourceSideInletNodeNum).Temp = state.dataLoopNodes->Node(this->SourceSideOutletNodeNum).TempSetPoint + 30;
766 :
767 24 : this->MyEnvrnFlag = false;
768 : }
769 : // Reset the environment flag
770 68126 : if (!state.dataGlobal->BeginEnvrnFlag) this->MyEnvrnFlag = true;
771 :
772 68126 : if (MyLoad > 0.0 && GSHPTypeNum == DataPlant::PlantEquipmentType::HPWaterEFHeating) {
773 17232 : this->MustRun = true;
774 17232 : this->IsOn = true;
775 50894 : } else if (MyLoad < 0.0 && GSHPTypeNum == DataPlant::PlantEquipmentType::HPWaterEFCooling) {
776 16346 : this->MustRun = true;
777 16346 : this->IsOn = true;
778 : } else {
779 34548 : this->MustRun = false;
780 34548 : this->IsOn = false;
781 : }
782 :
783 : //*******Set flow based on "flowlock" and "run" flags**********
784 : // Set flows if the heat pump is not running
785 68126 : if (!this->MustRun) {
786 34548 : this->reportLoadSideMassFlowRate = 0.0;
787 34548 : this->reportSourceSideMassFlowRate = 0.0;
788 :
789 34548 : PlantUtilities::SetComponentFlowRate(
790 34548 : state, this->reportLoadSideMassFlowRate, this->LoadSideInletNodeNum, this->LoadSideOutletNodeNum, this->LoadPlantLoc);
791 34548 : PlantUtilities::SetComponentFlowRate(
792 34548 : state, this->reportSourceSideMassFlowRate, this->SourceSideInletNodeNum, this->SourceSideOutletNodeNum, this->SourcePlantLoc);
793 34548 : PlantUtilities::PullCompInterconnectTrigger(state,
794 34548 : this->LoadPlantLoc,
795 34548 : this->CondMassFlowIndex,
796 34548 : this->SourcePlantLoc, // IS THIS RIGHT?
797 : DataPlant::CriteriaType::MassFlowRate,
798 : this->reportSourceSideMassFlowRate);
799 : // Set flows if the heat pump is running
800 : } else { // the heat pump must run
801 :
802 33578 : this->reportLoadSideMassFlowRate = this->LoadSideDesignMassFlow;
803 33578 : this->reportSourceSideMassFlowRate = this->SourceSideDesignMassFlow;
804 : // now check against and request in plant
805 33578 : PlantUtilities::SetComponentFlowRate(
806 33578 : state, this->reportLoadSideMassFlowRate, this->LoadSideInletNodeNum, this->LoadSideOutletNodeNum, this->LoadPlantLoc);
807 33578 : PlantUtilities::SetComponentFlowRate(
808 33578 : state, this->reportSourceSideMassFlowRate, this->SourceSideInletNodeNum, this->SourceSideOutletNodeNum, this->SourcePlantLoc);
809 : // if there's no flowin one, turn the entire "heat pump off"
810 33578 : if (this->reportLoadSideMassFlowRate <= 0.0 || this->reportSourceSideMassFlowRate <= 0.0) {
811 :
812 6 : this->reportLoadSideMassFlowRate = 0.0;
813 6 : this->reportSourceSideMassFlowRate = 0.0;
814 6 : this->MustRun = false;
815 :
816 6 : PlantUtilities::SetComponentFlowRate(
817 6 : state, this->reportLoadSideMassFlowRate, this->LoadSideInletNodeNum, this->LoadSideOutletNodeNum, this->LoadPlantLoc);
818 6 : PlantUtilities::SetComponentFlowRate(
819 6 : state, this->reportSourceSideMassFlowRate, this->SourceSideInletNodeNum, this->SourceSideOutletNodeNum, this->SourcePlantLoc);
820 6 : PlantUtilities::PullCompInterconnectTrigger(state,
821 6 : this->LoadPlantLoc,
822 6 : this->CondMassFlowIndex,
823 6 : this->SourcePlantLoc,
824 : DataPlant::CriteriaType::MassFlowRate,
825 : this->reportSourceSideMassFlowRate);
826 6 : return;
827 : }
828 33572 : PlantUtilities::PullCompInterconnectTrigger(state,
829 33572 : this->LoadPlantLoc,
830 33572 : this->CondMassFlowIndex,
831 33572 : this->SourcePlantLoc,
832 : DataPlant::CriteriaType::MassFlowRate,
833 : this->reportSourceSideMassFlowRate);
834 : }
835 :
836 : // Get inlet temps
837 68120 : this->reportLoadSideInletTemp = state.dataLoopNodes->Node(LoadSideInletNode).Temp;
838 68120 : this->reportSourceSideInletTemp = state.dataLoopNodes->Node(SourceSideInletNode).Temp;
839 :
840 : // Outlet variables
841 68120 : this->reportPower = 0.0;
842 68120 : this->reportEnergy = 0.0;
843 68120 : this->reportQLoad = 0.0;
844 68120 : this->reportQLoadEnergy = 0.0;
845 68120 : this->reportQSource = 0.0;
846 68120 : this->reportQSourceEnergy = 0.0;
847 68120 : this->reportLoadSideOutletTemp = 0.0;
848 68120 : this->reportSourceSideOutletTemp = 0.0;
849 : }
850 :
851 20 : void GshpSpecs::sizeCoolingWaterToWaterHP(EnergyPlusData &state)
852 : {
853 :
854 : // do sizing related calculations and reporting for cooling heat pumps
855 20 : bool errorsFound(false);
856 : static constexpr std::string_view RoutineName("sizeCoolingWaterToWaterHP");
857 20 : Real64 tmpLoadSideVolFlowRate = this->RatedLoadVolFlowCool;
858 : Real64 tmpSourceSideVolFlowRate;
859 20 : Real64 tmpCoolingCap = this->RatedCapCool;
860 20 : Real64 tmpPowerDraw = this->RatedPowerCool;
861 :
862 : // if companion heating coil known, update info from that
863 20 : if (this->companionIdentified) {
864 10 : this->RatedLoadVolFlowHeat = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).RatedLoadVolFlowHeat;
865 10 : this->ratedLoadVolFlowHeatWasAutoSized = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).ratedLoadVolFlowHeatWasAutoSized;
866 10 : this->RatedSourceVolFlowHeat = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).RatedSourceVolFlowHeat;
867 10 : this->ratedSourceVolFlowHeatWasAutoSized = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).ratedSourceVolFlowHeatWasAutoSized;
868 10 : this->RatedCapHeat = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).RatedCapHeat;
869 10 : this->ratedCapHeatWasAutoSized = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).ratedCapHeatWasAutoSized;
870 10 : this->RatedPowerHeat = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).RatedPowerHeat;
871 10 : this->ratedPowerHeatWasAutoSized = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).ratedPowerHeatWasAutoSized;
872 : }
873 :
874 20 : int pltLoadSizNum = state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).PlantSizNum;
875 20 : if (pltLoadSizNum > 0) {
876 10 : if (state.dataSize->PlantSizData(pltLoadSizNum).DesVolFlowRate > HVAC::SmallWaterVolFlow) {
877 8 : tmpLoadSideVolFlowRate = state.dataSize->PlantSizData(pltLoadSizNum).DesVolFlowRate * this->sizFac;
878 : // now compare to companion coil and take higher
879 8 : if (this->companionIdentified) {
880 8 : tmpLoadSideVolFlowRate = max(tmpLoadSideVolFlowRate, this->RatedLoadVolFlowHeat);
881 : // store flow rate right away regardless of PlantFirstSizesOkayToFinalize so that data are available
882 8 : this->RatedLoadVolFlowCool = tmpLoadSideVolFlowRate;
883 : }
884 8 : Real64 rho = FluidProperties::GetDensityGlycol(state,
885 8 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
886 : Constant::CWInitConvTemp,
887 8 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
888 : RoutineName);
889 8 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
890 8 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
891 : Constant::CWInitConvTemp,
892 8 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
893 : RoutineName);
894 8 : tmpCoolingCap = Cp * rho * state.dataSize->PlantSizData(pltLoadSizNum).DeltaT * tmpLoadSideVolFlowRate;
895 2 : } else if (this->companionIdentified && this->RatedLoadVolFlowHeat > 0.0) {
896 0 : tmpLoadSideVolFlowRate = this->RatedLoadVolFlowHeat;
897 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
898 0 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
899 : Constant::CWInitConvTemp,
900 0 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
901 : RoutineName);
902 0 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
903 0 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
904 : Constant::CWInitConvTemp,
905 0 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
906 : RoutineName);
907 0 : tmpCoolingCap = Cp * rho * state.dataSize->PlantSizData(pltLoadSizNum).DeltaT * tmpLoadSideVolFlowRate;
908 0 : } else {
909 2 : if (this->ratedCapCoolWasAutoSized) tmpCoolingCap = 0.0;
910 2 : if (this->ratedLoadVolFlowCoolWasAutoSized) tmpLoadSideVolFlowRate = 0.0;
911 : }
912 10 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
913 2 : if (this->ratedCapCoolWasAutoSized) {
914 2 : this->RatedCapCool = tmpCoolingCap;
915 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
916 1 : BaseSizer::reportSizerOutput(
917 : state, "HeatPump:WaterToWater:EquationFit:Cooling", this->Name, "Design Size Nominal Capacity [W]", tmpCoolingCap);
918 : }
919 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
920 0 : BaseSizer::reportSizerOutput(
921 : state, "HeatPump:WaterToWater:EquationFit:Cooling", this->Name, "Initial Design Size Nominal Capacity [W]", tmpCoolingCap);
922 : }
923 : } else {
924 0 : if (this->RatedCapCool > 0.0 && tmpCoolingCap > 0.0) {
925 0 : Real64 nomCoolingCapUser = this->RatedCapCool;
926 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
927 0 : if (state.dataGlobal->DoPlantSizing) {
928 0 : BaseSizer::reportSizerOutput(state,
929 : "HeatPump:WaterToWater:EquationFit:Cooling",
930 : this->Name,
931 : "Design Size Nominal Capacity [W]",
932 : tmpCoolingCap,
933 : "User-Specified Nominal Capacity [W]",
934 : nomCoolingCapUser);
935 : } else {
936 0 : BaseSizer::reportSizerOutput(state,
937 : "HeatPump:WaterToWater:EquationFit:Cooling",
938 : this->Name,
939 : "User-Specified Nominal Capacity [W]",
940 : nomCoolingCapUser);
941 : }
942 :
943 0 : if (state.dataGlobal->DisplayExtraWarnings) {
944 0 : if ((std::abs(tmpCoolingCap - nomCoolingCapUser) / nomCoolingCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
945 0 : ShowMessage(state, format("sizeCoolingWaterToWaterHP: Potential issue with equipment sizing for {}", this->Name));
946 0 : ShowContinueError(state, format("User-Specified Nominal Capacity of {:.2R} [W]", nomCoolingCapUser));
947 0 : ShowContinueError(state, format("differs from Design Size Nominal Capacity of {:.2R} [W]", tmpCoolingCap));
948 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
949 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
950 : }
951 : }
952 : }
953 0 : tmpCoolingCap = nomCoolingCapUser;
954 : }
955 : }
956 2 : if (this->ratedLoadVolFlowCoolWasAutoSized) {
957 2 : this->RatedLoadVolFlowCool = tmpLoadSideVolFlowRate;
958 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
959 1 : BaseSizer::reportSizerOutput(state,
960 : "HeatPump:WaterToWater:EquationFit:Cooling",
961 : this->Name,
962 : "Design Size Load Side Volume Flow Rate [m3/s]",
963 : tmpLoadSideVolFlowRate);
964 : }
965 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
966 0 : BaseSizer::reportSizerOutput(state,
967 : "HeatPump:WaterToWater:EquationFit:Cooling",
968 : this->Name,
969 : "Initial Design Size Load Side Volume Flow Rate [m3/s]",
970 : tmpLoadSideVolFlowRate);
971 : }
972 : } else {
973 0 : if (this->RatedLoadVolFlowCool > 0.0 && tmpLoadSideVolFlowRate > 0.0) {
974 0 : Real64 nomLoadSideVolFlowUser = this->RatedLoadVolFlowCool;
975 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
976 0 : if (state.dataGlobal->DoPlantSizing) {
977 0 : BaseSizer::reportSizerOutput(state,
978 : "HeatPump:WaterToWater:EquationFit:Cooling",
979 : this->Name,
980 : "Design Size Load Side Volume Flow Rate [m3/s]",
981 : tmpLoadSideVolFlowRate,
982 : "User-Specified Load Side Volume Flow Rate [m3/s]",
983 : nomLoadSideVolFlowUser);
984 : } else {
985 0 : BaseSizer::reportSizerOutput(state,
986 : "HeatPump:WaterToWater:EquationFit:Cooling",
987 : this->Name,
988 : "User-Specified Load Side Volume Flow Rate [m3/s]",
989 : nomLoadSideVolFlowUser);
990 : }
991 0 : if (state.dataGlobal->DisplayExtraWarnings) {
992 0 : if ((std::abs(tmpLoadSideVolFlowRate - nomLoadSideVolFlowUser) / nomLoadSideVolFlowUser) >
993 0 : state.dataSize->AutoVsHardSizingThreshold) {
994 0 : ShowMessage(state, format("sizeCoolingWaterToWaterHP: Potential issue with equipment sizing for {}", this->Name));
995 0 : ShowContinueError(state,
996 0 : format("User-Specified Load Side Volume Flow Rate of {:.2R} [m3/s]", nomLoadSideVolFlowUser));
997 0 : ShowContinueError(
998 0 : state, format("differs from Design Size Load Side Volume Flow Rate of {:.2R} [m3/s]", tmpLoadSideVolFlowRate));
999 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1000 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1001 : }
1002 : }
1003 : }
1004 0 : tmpLoadSideVolFlowRate = nomLoadSideVolFlowUser;
1005 : }
1006 : }
1007 : }
1008 :
1009 : } else { // did not find load side loop plant sizing to go with this.
1010 10 : if (this->companionIdentified) {
1011 0 : if (this->ratedLoadVolFlowHeatWasAutoSized && this->RatedLoadVolFlowHeat > 0.0) {
1012 : // fill load side flow rate size from companion coil
1013 0 : tmpLoadSideVolFlowRate = this->RatedLoadVolFlowHeat;
1014 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1015 0 : this->RatedLoadVolFlowCool = tmpLoadSideVolFlowRate;
1016 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
1017 0 : BaseSizer::reportSizerOutput(state,
1018 : "HeatPump:WaterToWater:EquationFit:Cooling",
1019 : this->Name,
1020 : "Design Size Load Side Volume Flow Rate [m3/s]",
1021 : tmpLoadSideVolFlowRate);
1022 : }
1023 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1024 0 : BaseSizer::reportSizerOutput(state,
1025 : "HeatPump:WaterToWater:EquationFit:Cooling",
1026 : this->Name,
1027 : "Initial Design Size Load Side Volume Flow Rate [m3/s]",
1028 : tmpLoadSideVolFlowRate);
1029 : }
1030 : }
1031 : }
1032 0 : if (this->ratedCapHeatWasAutoSized && this->RatedCapHeat > 0.0) {
1033 0 : tmpCoolingCap = this->RatedCapHeat;
1034 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1035 0 : this->RatedCapCool = tmpCoolingCap;
1036 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
1037 0 : BaseSizer::reportSizerOutput(
1038 : state, "HeatPump:WaterToWater:EquationFit:Cooling", this->Name, "Design Size Nominal Capacity [W]", tmpCoolingCap);
1039 : }
1040 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1041 0 : BaseSizer::reportSizerOutput(state,
1042 : "HeatPump:WaterToWater:EquationFit:Cooling",
1043 : this->Name,
1044 : "Initial Design Size Nominal Capacity [W]",
1045 : tmpCoolingCap);
1046 : }
1047 : }
1048 : }
1049 : } else { // no companion heatpump, no plant sizing object
1050 10 : if ((this->ratedLoadVolFlowCoolWasAutoSized || this->ratedCapCoolWasAutoSized) && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1051 0 : ShowSevereError(state, "Autosizing of Water to Water Heat Pump requires a loop Sizing:Plant object.");
1052 0 : ShowContinueError(state, format("Occurs in HeatPump:WaterToWater:EquationFit:Cooling object = {}", this->Name));
1053 0 : errorsFound = true;
1054 : }
1055 : }
1056 :
1057 10 : if (!this->ratedLoadVolFlowCoolWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
1058 1 : BaseSizer::reportSizerOutput(state,
1059 : "HeatPump:WaterToWater:EquationFit:Cooling",
1060 : this->Name,
1061 : "User-Specified Load Side Flow Rate [m3/s]",
1062 : this->RatedLoadVolFlowCool);
1063 : }
1064 10 : if (!this->ratedCapCoolWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
1065 1 : BaseSizer::reportSizerOutput(
1066 : state, "HeatPump:WaterToWater:EquationFit:Cooling", this->Name, "User-Specified Nominal Capacity [W]", this->RatedCapCool);
1067 : }
1068 : }
1069 20 : if (!this->ratedLoadVolFlowCoolWasAutoSized) tmpLoadSideVolFlowRate = this->RatedLoadVolFlowCool;
1070 20 : int pltSourceSizNum = state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).PlantSizNum;
1071 20 : if (pltSourceSizNum > 0) {
1072 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1073 0 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidName,
1074 : Constant::CWInitConvTemp,
1075 0 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidIndex,
1076 : RoutineName);
1077 0 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1078 0 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidName,
1079 : Constant::CWInitConvTemp,
1080 0 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidIndex,
1081 : RoutineName);
1082 0 : tmpSourceSideVolFlowRate = tmpCoolingCap * (1.0 + (1.0 / this->refCOP)) / (state.dataSize->PlantSizData(pltSourceSizNum).DeltaT * Cp * rho);
1083 : } else {
1084 20 : tmpSourceSideVolFlowRate = tmpLoadSideVolFlowRate; // set source side flow equal to load side flow, assumption
1085 : }
1086 :
1087 20 : if (this->ratedSourceVolFlowCoolWasAutoSized) {
1088 10 : this->RatedSourceVolFlowCool = tmpSourceSideVolFlowRate;
1089 10 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
1090 1 : BaseSizer::reportSizerOutput(state,
1091 : "HeatPump:WaterToWater:EquationFit:Cooling",
1092 : this->Name,
1093 : "Design Size Source Side Volume Flow Rate [m3/s]",
1094 : tmpSourceSideVolFlowRate);
1095 : }
1096 10 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1097 0 : BaseSizer::reportSizerOutput(state,
1098 : "HeatPump:WaterToWater:EquationFit:Cooling",
1099 : this->Name,
1100 : "Initial Design Size Source Side Volume Flow Rate [m3/s]",
1101 : tmpSourceSideVolFlowRate);
1102 : }
1103 : } else {
1104 10 : if (this->RatedSourceVolFlowCool > 0.0 && tmpSourceSideVolFlowRate > 0.0) {
1105 10 : Real64 nomSourceSideVolFlowUser = this->RatedSourceVolFlowCool;
1106 10 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
1107 1 : if (state.dataGlobal->DoPlantSizing) {
1108 0 : BaseSizer::reportSizerOutput(state,
1109 : "HeatPump:WaterToWater:EquationFit:Cooling",
1110 : this->Name,
1111 : "Design Size Source Side Volume Flow Rate [m3/s]",
1112 : tmpSourceSideVolFlowRate,
1113 : "User-Specified Source Side Volume Flow Rate [m3/s]",
1114 : nomSourceSideVolFlowUser);
1115 : } else {
1116 1 : BaseSizer::reportSizerOutput(state,
1117 : "HeatPump:WaterToWater:EquationFit:Cooling",
1118 : this->Name,
1119 : "User-Specified Source Side Volume Flow Rate [m3/s]",
1120 : nomSourceSideVolFlowUser);
1121 : }
1122 1 : if (state.dataGlobal->DisplayExtraWarnings) {
1123 0 : if ((std::abs(tmpSourceSideVolFlowRate - nomSourceSideVolFlowUser) / nomSourceSideVolFlowUser) >
1124 0 : state.dataSize->AutoVsHardSizingThreshold) {
1125 0 : ShowMessage(state, format("sizeCoolingWaterToWaterHP: Potential issue with equipment sizing for {}", this->Name));
1126 0 : ShowContinueError(state, format("User-Specified Source Side Volume Flow Rate of {:.2R} [m3/s]", nomSourceSideVolFlowUser));
1127 0 : ShowContinueError(state,
1128 0 : format("differs from Design Size Source Side Volume Flow Rate of {:.2R} [m3/s]", tmpSourceSideVolFlowRate));
1129 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1130 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1131 : }
1132 : }
1133 : }
1134 10 : tmpSourceSideVolFlowRate = nomSourceSideVolFlowUser;
1135 : }
1136 : }
1137 20 : if (!this->ratedSourceVolFlowCoolWasAutoSized) tmpSourceSideVolFlowRate = this->RatedSourceVolFlowCool;
1138 20 : if (!this->ratedCapCoolWasAutoSized) tmpCoolingCap = this->RatedCapCool;
1139 20 : if (this->ratedPowerCoolWasAutoSized) {
1140 10 : tmpPowerDraw = tmpCoolingCap / this->refCOP;
1141 10 : this->RatedPowerCool = tmpPowerDraw;
1142 10 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
1143 1 : BaseSizer::reportSizerOutput(
1144 : state, "HeatPump:WaterToWater:EquationFit:Cooling", this->Name, "Design Size Cooling Power Consumption [W]", tmpPowerDraw);
1145 : }
1146 10 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1147 0 : BaseSizer::reportSizerOutput(
1148 : state, "HeatPump:WaterToWater:EquationFit:Cooling", this->Name, "Initial Design Size Cooling Power Consumption [W]", tmpPowerDraw);
1149 : }
1150 : } else {
1151 10 : if (this->RatedPowerCool > 0.0 && tmpPowerDraw > 0.0) {
1152 10 : Real64 nomPowerDrawUser = this->RatedPowerCool;
1153 10 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
1154 1 : if (state.dataGlobal->DoPlantSizing) {
1155 0 : BaseSizer::reportSizerOutput(state,
1156 : "HeatPump:WaterToWater:EquationFit:Cooling",
1157 : this->Name,
1158 : "Design Size Cooling Power Consumption [W]",
1159 : tmpPowerDraw,
1160 : "User-Specified Cooling Power Consumption [W]",
1161 : nomPowerDrawUser);
1162 : } else {
1163 1 : BaseSizer::reportSizerOutput(state,
1164 : "HeatPump:WaterToWater:EquationFit:Cooling",
1165 : this->Name,
1166 : "User-Specified Cooling Power Consumption [W]",
1167 : nomPowerDrawUser);
1168 : }
1169 1 : if (state.dataGlobal->DisplayExtraWarnings) {
1170 0 : if ((std::abs(tmpPowerDraw - nomPowerDrawUser) / nomPowerDrawUser) > state.dataSize->AutoVsHardSizingThreshold) {
1171 0 : ShowMessage(state, format("sizeCoolingWaterToWaterHP: Potential issue with equipment sizing for {}", this->Name));
1172 0 : ShowContinueError(state, format("User-Specified Cooling Power Consumption of {:.2R} [W]", nomPowerDrawUser));
1173 0 : ShowContinueError(state, format("differs from Design Size Cooling Power Consumption of {:.2R} [W]", tmpPowerDraw));
1174 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1175 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1176 : }
1177 : }
1178 : }
1179 10 : tmpPowerDraw = nomPowerDrawUser;
1180 10 : this->refCOP = tmpCoolingCap / tmpPowerDraw;
1181 : }
1182 : }
1183 :
1184 20 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->LoadSideInletNodeNum, tmpLoadSideVolFlowRate);
1185 : // only register half of the source side flow because we expect a companion heat pump to also register a flow and we don't want to double
1186 : // count
1187 20 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->SourceSideInletNodeNum, tmpSourceSideVolFlowRate * 0.5);
1188 :
1189 20 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myCoolingSizesReported) {
1190 : // create predefined report
1191 4 : OutputReportPredefined::PreDefTableEntry(
1192 2 : state, state.dataOutRptPredefined->pdchMechType, this->Name, "HeatPump:WaterToWater:EquationFit:Cooling");
1193 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomEff, this->Name, this->refCOP);
1194 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomCap, this->Name, this->RatedCapCool);
1195 : }
1196 :
1197 20 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1198 4 : this->myCoolingSizesReported = true;
1199 : }
1200 :
1201 20 : if (errorsFound) {
1202 0 : ShowFatalError(state, "Preceding sizing errors cause program termination");
1203 : }
1204 20 : }
1205 :
1206 20 : void GshpSpecs::sizeHeatingWaterToWaterHP(EnergyPlusData &state)
1207 : {
1208 :
1209 : // do sizing related calculations and reporting for heating heat pumps
1210 20 : bool errorsFound(false);
1211 : static constexpr std::string_view RoutineName("sizeHeatingWaterToWaterHP");
1212 20 : Real64 tmpLoadSideVolFlowRate = this->RatedLoadVolFlowHeat;
1213 : Real64 tmpSourceSideVolFlowRate;
1214 20 : Real64 tmpHeatingCap = this->RatedCapHeat;
1215 20 : Real64 tmpPowerDraw = this->RatedPowerHeat;
1216 :
1217 : // if companion cooling coil known, update info from that
1218 20 : if (this->companionIdentified) {
1219 10 : this->RatedLoadVolFlowCool = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).RatedLoadVolFlowCool;
1220 10 : this->ratedLoadVolFlowCoolWasAutoSized = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).ratedLoadVolFlowCoolWasAutoSized;
1221 10 : this->RatedSourceVolFlowCool = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).RatedSourceVolFlowCool;
1222 10 : this->ratedSourceVolFlowCoolWasAutoSized = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).ratedSourceVolFlowCoolWasAutoSized;
1223 10 : this->RatedCapCool = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).RatedCapCool;
1224 10 : this->ratedCapCoolWasAutoSized = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).ratedCapCoolWasAutoSized;
1225 10 : this->RatedPowerCool = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).RatedPowerCool;
1226 10 : this->ratedPowerCoolWasAutoSized = state.dataHPWaterToWaterSimple->GSHP(this->companionIndex).ratedPowerCoolWasAutoSized;
1227 : }
1228 :
1229 20 : int pltLoadSizNum = state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).PlantSizNum;
1230 20 : if (pltLoadSizNum > 0) {
1231 10 : if (state.dataSize->PlantSizData(pltLoadSizNum).DesVolFlowRate > HVAC::SmallWaterVolFlow) {
1232 8 : tmpLoadSideVolFlowRate = state.dataSize->PlantSizData(pltLoadSizNum).DesVolFlowRate * this->sizFac;
1233 : // now compare to companion coil and take higher
1234 8 : if (this->companionIdentified) {
1235 8 : tmpLoadSideVolFlowRate = max(tmpLoadSideVolFlowRate, this->RatedLoadVolFlowCool);
1236 : // store flow rate right away regardless of PlantFirstSizesOkayToFinalize so that data are available for companion when
1237 : // PlantFirstSizesOkayToFinalize is true
1238 8 : this->RatedLoadVolFlowHeat = tmpLoadSideVolFlowRate;
1239 : }
1240 8 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1241 8 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
1242 : Constant::HWInitConvTemp,
1243 8 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
1244 : RoutineName);
1245 8 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1246 8 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
1247 : Constant::HWInitConvTemp,
1248 8 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
1249 : RoutineName);
1250 8 : tmpHeatingCap = Cp * rho * state.dataSize->PlantSizData(pltLoadSizNum).DeltaT * tmpLoadSideVolFlowRate;
1251 2 : } else if (this->companionIdentified && this->RatedLoadVolFlowCool > 0.0) {
1252 0 : tmpLoadSideVolFlowRate = this->RatedLoadVolFlowCool;
1253 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1254 0 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
1255 : Constant::HWInitConvTemp,
1256 0 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
1257 : RoutineName);
1258 0 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1259 0 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
1260 : Constant::HWInitConvTemp,
1261 0 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
1262 : RoutineName);
1263 0 : tmpHeatingCap = Cp * rho * state.dataSize->PlantSizData(pltLoadSizNum).DeltaT * tmpLoadSideVolFlowRate;
1264 0 : } else {
1265 2 : if (this->ratedCapHeatWasAutoSized) tmpHeatingCap = 0.0;
1266 2 : if (this->ratedLoadVolFlowHeatWasAutoSized) tmpLoadSideVolFlowRate = 0.0;
1267 : }
1268 10 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1269 2 : if (this->ratedCapHeatWasAutoSized) {
1270 2 : this->RatedCapHeat = tmpHeatingCap;
1271 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1272 1 : BaseSizer::reportSizerOutput(
1273 : state, "HeatPump:WaterToWater:EquationFit:Heating", this->Name, "Design Size Nominal Capacity [W]", tmpHeatingCap);
1274 : }
1275 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1276 0 : BaseSizer::reportSizerOutput(
1277 : state, "HeatPump:WaterToWater:EquationFit:Heating", this->Name, "Initial Design Size Nominal Capacity [W]", tmpHeatingCap);
1278 : }
1279 : } else {
1280 0 : if (this->RatedCapHeat > 0.0 && tmpHeatingCap > 0.0) {
1281 0 : Real64 nomHeatingCapUser = this->RatedCapHeat;
1282 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1283 0 : if (state.dataGlobal->DoPlantSizing) {
1284 0 : BaseSizer::reportSizerOutput(state,
1285 : "HeatPump:WaterToWater:EquationFit:Heating",
1286 : this->Name,
1287 : "Design Size Nominal Capacity [W]",
1288 : tmpHeatingCap,
1289 : "User-Specified Nominal Capacity [W]",
1290 : nomHeatingCapUser);
1291 : } else {
1292 0 : BaseSizer::reportSizerOutput(state,
1293 : "HeatPump:WaterToWater:EquationFit:Heating",
1294 : this->Name,
1295 : "User-Specified Nominal Capacity [W]",
1296 : nomHeatingCapUser);
1297 : }
1298 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1299 0 : if ((std::abs(tmpHeatingCap - nomHeatingCapUser) / nomHeatingCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
1300 0 : ShowMessage(state, format("sizeHeatingWaterToWaterHP: Potential issue with equipment sizing for {}", this->Name));
1301 0 : ShowContinueError(state, format("User-Specified Nominal Capacity of {:.2R} [W]", nomHeatingCapUser));
1302 0 : ShowContinueError(state, format("differs from Design Size Nominal Capacity of {:.2R} [W]", tmpHeatingCap));
1303 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1304 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1305 : }
1306 : }
1307 : }
1308 0 : tmpHeatingCap = nomHeatingCapUser;
1309 : }
1310 : }
1311 2 : if (this->ratedLoadVolFlowHeatWasAutoSized) {
1312 2 : this->RatedLoadVolFlowHeat = tmpLoadSideVolFlowRate;
1313 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1314 1 : BaseSizer::reportSizerOutput(state,
1315 : "HeatPump:WaterToWater:EquationFit:Heating",
1316 : this->Name,
1317 : "Design Size Load Side Volume Flow Rate [m3/s]",
1318 : tmpLoadSideVolFlowRate);
1319 : }
1320 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1321 0 : BaseSizer::reportSizerOutput(state,
1322 : "HeatPump:WaterToWater:EquationFit:Heating",
1323 : this->Name,
1324 : "Initial Design Size Load Side Volume Flow Rate [m3/s]",
1325 : tmpLoadSideVolFlowRate);
1326 : }
1327 : } else {
1328 0 : if (this->RatedLoadVolFlowHeat > 0.0 && tmpLoadSideVolFlowRate > 0.0) {
1329 0 : Real64 nomLoadSideVolFlowUser = this->RatedLoadVolFlowHeat;
1330 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1331 0 : if (state.dataGlobal->DoPlantSizing) {
1332 0 : BaseSizer::reportSizerOutput(state,
1333 : "HeatPump:WaterToWater:EquationFit:Heating",
1334 : this->Name,
1335 : "Design Size Load Side Volume Flow Rate [m3/s]",
1336 : tmpLoadSideVolFlowRate,
1337 : "User-Specified Load Side Volume Flow Rate [m3/s]",
1338 : nomLoadSideVolFlowUser);
1339 : } else {
1340 0 : BaseSizer::reportSizerOutput(state,
1341 : "HeatPump:WaterToWater:EquationFit:Heating",
1342 : this->Name,
1343 : "User-Specified Load Side Volume Flow Rate [m3/s]",
1344 : nomLoadSideVolFlowUser);
1345 : }
1346 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1347 0 : if ((std::abs(tmpLoadSideVolFlowRate - nomLoadSideVolFlowUser) / nomLoadSideVolFlowUser) >
1348 0 : state.dataSize->AutoVsHardSizingThreshold) {
1349 0 : ShowMessage(state, format("sizeHeatingWaterToWaterHP: Potential issue with equipment sizing for {}", this->Name));
1350 0 : ShowContinueError(state,
1351 0 : format("User-Specified Load Side Volume Flow Rate of {:.2R} [m3/s]", nomLoadSideVolFlowUser));
1352 0 : ShowContinueError(
1353 0 : state, format("differs from Design Size Load Side Volume Flow Rate of {:.2R} [m3/s]", tmpLoadSideVolFlowRate));
1354 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1355 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1356 : }
1357 : }
1358 : }
1359 0 : tmpLoadSideVolFlowRate = nomLoadSideVolFlowUser;
1360 : }
1361 : }
1362 : }
1363 : } else { // did not find plant sizing to go with this.
1364 10 : if (this->companionIdentified) {
1365 0 : if (this->ratedLoadVolFlowHeatWasAutoSized && this->RatedLoadVolFlowCool > 0.0) {
1366 : // fill load side flow rate size from companion coil
1367 0 : tmpLoadSideVolFlowRate = this->RatedLoadVolFlowCool;
1368 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1369 0 : this->RatedLoadVolFlowHeat = tmpLoadSideVolFlowRate;
1370 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1371 0 : BaseSizer::reportSizerOutput(state,
1372 : "HeatPump:WaterToWater:EquationFit:Heating",
1373 : this->Name,
1374 : "Design Size Load Side Volume Flow Rate [m3/s]",
1375 : tmpLoadSideVolFlowRate);
1376 : }
1377 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1378 0 : BaseSizer::reportSizerOutput(state,
1379 : "HeatPump:WaterToWater:EquationFit:Heating",
1380 : this->Name,
1381 : "Initial Design Size Load Side Volume Flow Rate [m3/s]",
1382 : tmpLoadSideVolFlowRate);
1383 : }
1384 : }
1385 : }
1386 0 : if (this->ratedCapHeatWasAutoSized && this->RatedCapCool > 0.0) {
1387 0 : tmpHeatingCap = this->RatedCapCool;
1388 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1389 0 : this->RatedCapHeat = tmpHeatingCap;
1390 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1391 0 : BaseSizer::reportSizerOutput(
1392 : state, "HeatPump:WaterToWater:EquationFit:Heating", this->Name, "Design Size Nominal Capacity [W]", tmpHeatingCap);
1393 : }
1394 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1395 0 : BaseSizer::reportSizerOutput(state,
1396 : "HeatPump:WaterToWater:EquationFit:Heating",
1397 : this->Name,
1398 : "Initial Design Size Nominal Capacity [W]",
1399 : tmpHeatingCap);
1400 : }
1401 : }
1402 : }
1403 :
1404 : } else { // no companion heatpump, no plant sizing object
1405 10 : if ((this->ratedLoadVolFlowHeatWasAutoSized || this->ratedCapHeatWasAutoSized) && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1406 0 : ShowSevereError(state, "Autosizing of Water to Water Heat Pump requires a loop Sizing:Plant object.");
1407 0 : ShowContinueError(state, format("Occurs in HeatPump:WaterToWater:EquationFit:Heating object = {}", this->Name));
1408 0 : errorsFound = true;
1409 : }
1410 : }
1411 :
1412 10 : if (!this->ratedLoadVolFlowHeatWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1413 1 : BaseSizer::reportSizerOutput(state,
1414 : "HeatPump:WaterToWater:EquationFit:Heating",
1415 : this->Name,
1416 : "User-Specified Load Side Flow Rate [m3/s]",
1417 : this->RatedLoadVolFlowHeat);
1418 : }
1419 10 : if (!this->ratedCapHeatWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1420 1 : BaseSizer::reportSizerOutput(
1421 : state, "HeatPump:WaterToWater:EquationFit:Heating", this->Name, "User-Specified Nominal Capacity [W]", this->RatedCapHeat);
1422 : }
1423 : }
1424 20 : if (!this->ratedLoadVolFlowHeatWasAutoSized) tmpLoadSideVolFlowRate = this->RatedLoadVolFlowHeat;
1425 20 : int pltSourceSizNum = state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).PlantSizNum;
1426 20 : if (pltSourceSizNum > 0) {
1427 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1428 0 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidName,
1429 : Constant::HWInitConvTemp,
1430 0 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidIndex,
1431 : RoutineName);
1432 0 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1433 0 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidName,
1434 : Constant::HWInitConvTemp,
1435 0 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidIndex,
1436 : RoutineName);
1437 0 : tmpSourceSideVolFlowRate = tmpHeatingCap * (1.0 - (1.0 / this->refCOP)) / (state.dataSize->PlantSizData(pltSourceSizNum).DeltaT * Cp * rho);
1438 : } else {
1439 20 : tmpSourceSideVolFlowRate = tmpLoadSideVolFlowRate; // set source side flow equal to load side flow, assumption
1440 : }
1441 20 : if (this->ratedSourceVolFlowHeatWasAutoSized) {
1442 10 : this->RatedSourceVolFlowHeat = tmpSourceSideVolFlowRate;
1443 10 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1444 1 : BaseSizer::reportSizerOutput(state,
1445 : "HeatPump:WaterToWater:EquationFit:Heating",
1446 : this->Name,
1447 : "Design Size Source Side Volume Flow Rate [m3/s]",
1448 : tmpSourceSideVolFlowRate);
1449 : }
1450 10 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1451 0 : BaseSizer::reportSizerOutput(state,
1452 : "HeatPump:WaterToWater:EquationFit:Heating",
1453 : this->Name,
1454 : "Initial Design Size Source Side Volume Flow Rate [m3/s]",
1455 : tmpSourceSideVolFlowRate);
1456 : }
1457 : } else {
1458 10 : if (this->RatedSourceVolFlowHeat > 0.0 && tmpSourceSideVolFlowRate > 0.0) {
1459 10 : Real64 nomSourceSideVolFlowUser = this->RatedSourceVolFlowHeat;
1460 10 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1461 1 : if (state.dataGlobal->DoPlantSizing) {
1462 0 : BaseSizer::reportSizerOutput(state,
1463 : "HeatPump:WaterToWater:EquationFit:Heating",
1464 : this->Name,
1465 : "Design Size Source Side Volume Flow Rate [m3/s]",
1466 : tmpSourceSideVolFlowRate,
1467 : "User-Specified Source Side Volume Flow Rate [m3/s]",
1468 : nomSourceSideVolFlowUser);
1469 : } else {
1470 1 : BaseSizer::reportSizerOutput(state,
1471 : "HeatPump:WaterToWater:EquationFit:Heating",
1472 : this->Name,
1473 : "User-Specified Source Side Volume Flow Rate [m3/s]",
1474 : nomSourceSideVolFlowUser);
1475 : }
1476 1 : if (state.dataGlobal->DisplayExtraWarnings) {
1477 0 : if ((std::abs(tmpSourceSideVolFlowRate - nomSourceSideVolFlowUser) / nomSourceSideVolFlowUser) >
1478 0 : state.dataSize->AutoVsHardSizingThreshold) {
1479 0 : ShowMessage(state, format("sizeHeatingWaterToWaterHP: Potential issue with equipment sizing for {}", this->Name));
1480 0 : ShowContinueError(state, format("User-Specified Source Side Volume Flow Rate of {:.2R} [m3/s]", nomSourceSideVolFlowUser));
1481 0 : ShowContinueError(state,
1482 0 : format("differs from Design Size Source Side Volume Flow Rate of {:.2R} [m3/s]", tmpSourceSideVolFlowRate));
1483 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1484 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1485 : }
1486 : }
1487 : }
1488 10 : tmpSourceSideVolFlowRate = nomSourceSideVolFlowUser;
1489 : }
1490 : }
1491 20 : if (!this->ratedSourceVolFlowHeatWasAutoSized) tmpSourceSideVolFlowRate = this->RatedSourceVolFlowHeat;
1492 20 : if (!this->ratedCapHeatWasAutoSized) tmpHeatingCap = this->RatedCapHeat;
1493 20 : if (this->ratedPowerHeatWasAutoSized) {
1494 10 : tmpPowerDraw = tmpHeatingCap / this->refCOP;
1495 10 : this->RatedPowerHeat = tmpPowerDraw;
1496 10 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1497 1 : BaseSizer::reportSizerOutput(
1498 : state, "HeatPump:WaterToWater:EquationFit:Heating", this->Name, "Design Size Heating Power Consumption [W]", tmpPowerDraw);
1499 : }
1500 10 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1501 0 : BaseSizer::reportSizerOutput(
1502 : state, "HeatPump:WaterToWater:EquationFit:Heating", this->Name, "Initial Design Size Heating Power Consumption [W]", tmpPowerDraw);
1503 : }
1504 : } else {
1505 10 : if (this->RatedPowerHeat > 0.0 && tmpPowerDraw > 0.0) {
1506 10 : Real64 nomPowerDrawUser = this->RatedPowerHeat;
1507 10 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1508 1 : if (state.dataGlobal->DoPlantSizing) {
1509 0 : BaseSizer::reportSizerOutput(state,
1510 : "HeatPump:WaterToWater:EquationFit:Heating",
1511 : this->Name,
1512 : "Design Size Heating Power Consumption [W]",
1513 : tmpPowerDraw,
1514 : "User-Specified Heating Power Consumption [W]",
1515 : nomPowerDrawUser);
1516 : } else {
1517 1 : BaseSizer::reportSizerOutput(state,
1518 : "HeatPump:WaterToWater:EquationFit:Heating",
1519 : this->Name,
1520 : "User-Specified Heating Power Consumption [W]",
1521 : nomPowerDrawUser);
1522 : }
1523 1 : if (state.dataGlobal->DisplayExtraWarnings) {
1524 0 : if ((std::abs(tmpPowerDraw - nomPowerDrawUser) / nomPowerDrawUser) > state.dataSize->AutoVsHardSizingThreshold) {
1525 0 : ShowMessage(state, format("sizeHeatingWaterToWaterHP: Potential issue with equipment sizing for {}", this->Name));
1526 0 : ShowContinueError(state, format("User-Specified Heating Power Consumption of {:.2R} [W]", nomPowerDrawUser));
1527 0 : ShowContinueError(state, format("differs from Design Size Heating Power Consumption of {:.2R} [W]", tmpPowerDraw));
1528 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1529 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1530 : }
1531 : }
1532 : }
1533 10 : tmpPowerDraw = nomPowerDrawUser;
1534 10 : this->refCOP = tmpHeatingCap / tmpPowerDraw;
1535 : }
1536 : }
1537 :
1538 20 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->LoadSideInletNodeNum, tmpLoadSideVolFlowRate);
1539 : // register half of source side flow to avoid double counting
1540 20 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->SourceSideInletNodeNum, tmpSourceSideVolFlowRate * 0.5);
1541 :
1542 20 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->myHeatingSizesReported) {
1543 : // create predefined report
1544 4 : OutputReportPredefined::PreDefTableEntry(
1545 2 : state, state.dataOutRptPredefined->pdchMechType, this->Name, "HeatPump:WaterToWater:EquationFit:Heating");
1546 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomEff, this->Name, this->refCOP);
1547 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomCap, this->Name, this->RatedCapHeat);
1548 : }
1549 :
1550 20 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1551 4 : this->myHeatingSizesReported = true;
1552 : }
1553 :
1554 20 : if (errorsFound) {
1555 0 : ShowFatalError(state, "Preceding sizing errors cause program termination");
1556 : }
1557 20 : }
1558 :
1559 34043 : void GshpSpecs::CalcWatertoWaterHPCooling(EnergyPlusData &state, Real64 const MyLoad)
1560 : {
1561 : // SUBROUTINE INFORMATION:
1562 : // AUTHOR Kenneth Tang
1563 : // DATE WRITTEN March 2005
1564 : // MODIFIED
1565 : // RE-ENGINEERED
1566 :
1567 : // PURPOSE OF THIS SUBROUTINE:
1568 : // This routine simulate the heat pump peformance in cooling mode
1569 :
1570 : // REFERENCES:
1571 : // (1) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
1572 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
1573 : // Oklahoma State University. (downloadable from http://www.hvac.okstate.edu/)
1574 :
1575 : // Using/Aliasing
1576 34043 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
1577 :
1578 : // SUBROUTINE PARAMETER DEFINITIONS:
1579 34043 : Real64 constexpr CelsiustoKelvin(Constant::Kelvin); // Conversion from Celsius to Kelvin
1580 34043 : Real64 constexpr Tref(283.15); // Reference Temperature for performance curves,10C [K]
1581 : static constexpr std::string_view RoutineName("CalcWatertoWaterHPCooling");
1582 :
1583 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1584 : Real64 CoolCapRated; // Rated Cooling Capacity [W]
1585 : Real64 CoolPowerRated; // Rated Cooling Power Consumption[W]
1586 : Real64 LoadSideVolFlowRateRated; // Rated Load Side Volumetric Flow Rate [m3/s]
1587 : Real64 SourceSideVolFlowRateRated; // Rated Source Side Volumetric Flow Rate [m3/s]
1588 :
1589 : Real64 LoadSideMassFlowRate; // Load Side Mass Flow Rate [kg/s]
1590 : Real64 LoadSideInletTemp; // Load Side Inlet Temperature [C]
1591 : Real64 LoadSideOutletTemp; // Load side Outlet Temperature [C]
1592 : Real64 SourceSideMassFlowRate; // Source Side Mass Flow Rate [kg/s]
1593 : Real64 SourceSideInletTemp; // Source Side Inlet Temperature [C]
1594 : Real64 SourceSideOutletTemp; // Source Side Outlet Temperature [C]
1595 :
1596 : Real64 func1; // Portion of the heat transfer and power equation
1597 : Real64 func2; // Portion of the heat transfer and power equation
1598 : Real64 func3; // Portion of the heat transfer and power equation
1599 : Real64 func4; // Portion of the heat transfer and power equation
1600 : Real64 Power; // Power Consumption [W]
1601 : Real64 QLoad; // Cooling Capacity [W]
1602 : Real64 QSource; // Source Side Heat Transfer Rate [W]
1603 : Real64 PartLoadRatio; // Part-Load Ratio
1604 : Real64 rhoLoadSide;
1605 : Real64 rhoSourceSide;
1606 : Real64 CpLoadSide;
1607 : Real64 CpSourceSide;
1608 :
1609 : // LOAD LOCAL VARIABLES FROM DATA STRUCTURE
1610 34043 : LoadSideVolFlowRateRated = this->RatedLoadVolFlowCool;
1611 34043 : SourceSideVolFlowRateRated = this->RatedSourceVolFlowCool;
1612 34043 : CoolCapRated = this->RatedCapCool;
1613 34043 : CoolPowerRated = this->RatedPowerCool;
1614 :
1615 34043 : LoadSideMassFlowRate = this->reportLoadSideMassFlowRate;
1616 34043 : LoadSideInletTemp = this->reportLoadSideInletTemp;
1617 34043 : SourceSideMassFlowRate = this->reportSourceSideMassFlowRate;
1618 34043 : SourceSideInletTemp = this->reportSourceSideInletTemp;
1619 :
1620 : // If heat pump is not operating, THEN return
1621 34043 : if (!this->MustRun) {
1622 17703 : return;
1623 : }
1624 :
1625 16340 : rhoLoadSide = FluidProperties::GetDensityGlycol(state,
1626 16340 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
1627 : LoadSideInletTemp,
1628 16340 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
1629 : RoutineName);
1630 :
1631 16340 : rhoSourceSide = FluidProperties::GetDensityGlycol(state,
1632 16340 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidName,
1633 : SourceSideInletTemp,
1634 16340 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidIndex,
1635 : RoutineName);
1636 :
1637 16340 : func1 = ((LoadSideInletTemp + CelsiustoKelvin) / Tref);
1638 16340 : func2 = ((SourceSideInletTemp + CelsiustoKelvin) / Tref);
1639 16340 : func3 = (LoadSideMassFlowRate / (LoadSideVolFlowRateRated * rhoLoadSide));
1640 16340 : func4 = (SourceSideMassFlowRate / (SourceSideVolFlowRateRated * rhoSourceSide));
1641 :
1642 16340 : QLoad = CoolCapRated * Curve::CurveValue(state, this->CoolCapCurveIndex, func1, func2, func3, func4);
1643 :
1644 16340 : Power = CoolPowerRated * Curve::CurveValue(state, this->CoolPowCurveIndex, func1, func2, func3, func4);
1645 :
1646 16340 : if ((QLoad <= 0.0 || Power <= 0.0) && !state.dataGlobal->WarmupFlag) {
1647 0 : if (QLoad <= 0.0) {
1648 0 : if (this->CoolCapNegativeCounter < 1) {
1649 0 : ++this->CoolCapNegativeCounter;
1650 0 : ShowWarningError(state, format("{} \"{}\":", HPEqFitCooling, this->Name));
1651 0 : ShowContinueError(state, format(" Cooling capacity curve output is <= 0.0 ({:.4T}).", QLoad));
1652 0 : ShowContinueError(state, format(" Zero or negative value occurs with a load-side inlet temperature of {:.2T} C,", LoadSideInletTemp));
1653 0 : ShowContinueError(state, format(" a source-side inlet temperature of {:.2T} C,", SourceSideInletTemp));
1654 0 : ShowContinueError(state, format(" a load-side mass flow rate of {:.3T} kg/s,", LoadSideMassFlowRate));
1655 0 : ShowContinueError(state, format(" and a source-side mass flow rate of {:.3T} kg/s.", SourceSideMassFlowRate));
1656 0 : ShowContinueErrorTimeStamp(state, " The heat pump is turned off for this time step but simulation continues.");
1657 : } else {
1658 0 : ShowRecurringWarningErrorAtEnd(state,
1659 0 : HPEqFitCooling + " \"" + this->Name +
1660 : "\": Cooling capacity curve output is <= 0.0 warning continues...",
1661 0 : this->CoolCapNegativeIndex,
1662 : QLoad,
1663 : QLoad);
1664 : }
1665 : }
1666 0 : if (Power <= 0.0) {
1667 0 : if (this->CoolPowerNegativeCounter < 1) {
1668 0 : ++this->CoolPowerNegativeCounter;
1669 0 : ShowWarningError(state, format("{} \"{}\":", HPEqFitCooling, this->Name));
1670 0 : ShowContinueError(state, format(" Cooling compressor power curve output is <= 0.0 ({:.4T}).", Power));
1671 0 : ShowContinueError(state, format(" Zero or negative value occurs with a load-side inlet temperature of {:.2T} C,", LoadSideInletTemp));
1672 0 : ShowContinueError(state, format(" a source-side inlet temperature of {:.2T} C,", SourceSideInletTemp));
1673 0 : ShowContinueError(state, format(" a load-side mass flow rate of {:.3T} kg/s,", LoadSideMassFlowRate));
1674 0 : ShowContinueError(state, format(" and a source-side mass flow rate of {:.3T} kg/s.", SourceSideMassFlowRate));
1675 0 : ShowContinueErrorTimeStamp(state, " The heat pump is turned off for this time step but simulation continues.");
1676 : } else {
1677 0 : ShowRecurringWarningErrorAtEnd(state,
1678 0 : HPEqFitCooling + " \"" + this->Name +
1679 : "\": Cooling compressor power curve output is <= 0.0 warning continues...",
1680 0 : this->CoolPowerNegativeIndex,
1681 : Power,
1682 : Power);
1683 : }
1684 : }
1685 :
1686 0 : QLoad = 0.0;
1687 0 : Power = 0.0;
1688 : }
1689 :
1690 16340 : QSource = QLoad + Power; // assume no losses
1691 :
1692 : // Control Strategy
1693 16340 : if (std::abs(MyLoad) < QLoad && QLoad != 0.0) {
1694 16328 : PartLoadRatio = std::abs(MyLoad) / QLoad;
1695 16328 : QLoad = std::abs(MyLoad);
1696 16328 : Power *= PartLoadRatio;
1697 16328 : QSource *= PartLoadRatio;
1698 : }
1699 :
1700 16340 : CpLoadSide = FluidProperties::GetSpecificHeatGlycol(state,
1701 16340 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
1702 : LoadSideInletTemp,
1703 16340 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
1704 : RoutineName);
1705 :
1706 16340 : CpSourceSide = FluidProperties::GetSpecificHeatGlycol(state,
1707 16340 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidName,
1708 : SourceSideInletTemp,
1709 16340 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidIndex,
1710 : RoutineName);
1711 :
1712 16340 : LoadSideOutletTemp = LoadSideInletTemp - QLoad / (LoadSideMassFlowRate * CpLoadSide);
1713 16340 : SourceSideOutletTemp = SourceSideInletTemp + QSource / (SourceSideMassFlowRate * CpSourceSide);
1714 :
1715 16340 : this->reportPower = Power;
1716 16340 : this->reportEnergy = Power * TimeStepSysSec;
1717 16340 : this->reportQSource = QSource;
1718 16340 : this->reportQLoad = QLoad;
1719 16340 : this->reportQSourceEnergy = QSource * TimeStepSysSec;
1720 16340 : this->reportQLoadEnergy = QLoad * TimeStepSysSec;
1721 16340 : this->reportLoadSideOutletTemp = LoadSideOutletTemp;
1722 16340 : this->reportSourceSideOutletTemp = SourceSideOutletTemp;
1723 : }
1724 :
1725 34043 : void GshpSpecs::CalcWatertoWaterHPHeating(EnergyPlusData &state, Real64 const MyLoad)
1726 : {
1727 : // SUBROUTINE INFORMATION:
1728 : // AUTHOR Kenneth Tang
1729 : // DATE WRITTEN March 2005
1730 : // MODIFIED
1731 : // RE-ENGINEERED
1732 :
1733 : // PURPOSE OF THIS SUBROUTINE:
1734 : // This routine simulate the heat pump peformance in heating mode
1735 :
1736 : // REFERENCES:
1737 : // (1) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
1738 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
1739 : // Oklahoma State University. (downloadable from http://www.hvac.okstate.edu/)
1740 :
1741 : // Using/Aliasing
1742 34043 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
1743 :
1744 : // SUBROUTINE PARAMETER DEFINITIONS:
1745 34043 : Real64 const CelsiustoKelvin(Constant::Kelvin); // Conversion from Celsius to Kelvin
1746 34043 : Real64 constexpr Tref(283.15); // Reference Temperature for performance curves,10C [K]
1747 : static constexpr std::string_view RoutineName("CalcWatertoWaterHPHeating");
1748 :
1749 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1750 :
1751 : Real64 HeatCapRated; // Rated Heating Capacity [W]
1752 : Real64 HeatPowerRated; // Rated Heating Compressor Power[W]
1753 : Real64 LoadSideVolFlowRateRated; // Rated Load Side Volumetric Flow Rate [m3/s]
1754 : Real64 SourceSideVolFlowRateRated; // Rated Source Side Volumetric Flow Rate [m3/s]
1755 : Real64 LoadSideMassFlowRate; // Load Side Mass Flow Rate [kg/s]
1756 : Real64 LoadSideInletTemp; // Load Side Inlet Temperature [C]
1757 : Real64 LoadSideOutletTemp; // Load side Outlet Temperature [C]
1758 : Real64 SourceSideMassFlowRate; // Source Side Mass Flow Rate [kg/s]
1759 : Real64 SourceSideInletTemp; // Source Side Inlet Temperature [C]
1760 : Real64 SourceSideOutletTemp; // Source Side Outlet Temperature [C]
1761 : Real64 func1; // Portion of the heat transfer and power equation
1762 : Real64 func2; // Portion of the heat transfer and power equation
1763 : Real64 func3; // Portion of the heat transfer and power equation
1764 : Real64 func4; // Portion of the heat transfer and power equation
1765 : Real64 Power; // Power Consumption [W]
1766 : Real64 QLoad; // Cooling Capacity [W]
1767 : Real64 QSource; // Source Side Heat Transfer Rate [W]
1768 : Real64 PartLoadRatio; // Part Load Ratio
1769 : Real64 rhoLoadSide;
1770 : Real64 rhoSourceSide;
1771 : Real64 CpLoadSide;
1772 : Real64 CpSourceSide;
1773 :
1774 : // LOAD LOCAL VARIABLES FROM DATA STRUCTURE
1775 34043 : LoadSideVolFlowRateRated = this->RatedLoadVolFlowHeat;
1776 34043 : SourceSideVolFlowRateRated = this->RatedSourceVolFlowHeat;
1777 34043 : HeatCapRated = this->RatedCapHeat;
1778 34043 : HeatPowerRated = this->RatedPowerHeat;
1779 :
1780 34043 : LoadSideMassFlowRate = this->reportLoadSideMassFlowRate;
1781 34043 : LoadSideInletTemp = this->reportLoadSideInletTemp;
1782 34043 : SourceSideMassFlowRate = this->reportSourceSideMassFlowRate;
1783 34043 : SourceSideInletTemp = this->reportSourceSideInletTemp;
1784 :
1785 : // If heat pump is not operating, THEN return
1786 34043 : if (!this->MustRun) {
1787 16811 : return;
1788 : }
1789 17232 : rhoLoadSide = FluidProperties::GetDensityGlycol(state,
1790 17232 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
1791 : LoadSideInletTemp,
1792 17232 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
1793 : RoutineName);
1794 :
1795 17232 : rhoSourceSide = FluidProperties::GetDensityGlycol(state,
1796 17232 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidName,
1797 : SourceSideInletTemp,
1798 17232 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidIndex,
1799 : RoutineName);
1800 :
1801 17232 : func1 = ((LoadSideInletTemp + CelsiustoKelvin) / Tref);
1802 17232 : func2 = ((SourceSideInletTemp + CelsiustoKelvin) / Tref);
1803 17232 : func3 = (LoadSideMassFlowRate / (LoadSideVolFlowRateRated * rhoLoadSide));
1804 17232 : func4 = (SourceSideMassFlowRate / (SourceSideVolFlowRateRated * rhoSourceSide));
1805 :
1806 17232 : QLoad = HeatCapRated * Curve::CurveValue(state, this->HeatCapCurveIndex, func1, func2, func3, func4);
1807 17232 : Power = HeatPowerRated * Curve::CurveValue(state, this->HeatPowCurveIndex, func1, func2, func3, func4);
1808 :
1809 17232 : if ((QLoad <= 0.0 || Power <= 0.0) && !state.dataGlobal->WarmupFlag) {
1810 0 : if (QLoad <= 0.0) {
1811 0 : if (this->HeatCapNegativeCounter < 1) {
1812 0 : ++this->HeatCapNegativeCounter;
1813 0 : ShowWarningError(state, format("{} \"{}\":", HPEqFitHeating, this->Name));
1814 0 : ShowContinueError(state, format(" Heating capacity curve output is <= 0.0 ({:.4T}).", QLoad));
1815 0 : ShowContinueError(state, format(" Zero or negative value occurs with a load-side inlet temperature of {:.2T} C,", LoadSideInletTemp));
1816 0 : ShowContinueError(state, format(" a source-side inlet temperature of {:.2T} C,", SourceSideInletTemp));
1817 0 : ShowContinueError(state, format(" a load-side mass flow rate of {:.3T} kg/s,", LoadSideMassFlowRate));
1818 0 : ShowContinueError(state, format(" and a source-side mass flow rate of {:.3T} kg/s.", SourceSideMassFlowRate));
1819 0 : ShowContinueErrorTimeStamp(state, " The heat pump is turned off for this time step but simulation continues.");
1820 : } else {
1821 0 : ShowRecurringWarningErrorAtEnd(state,
1822 0 : HPEqFitHeating + " \"" + this->Name +
1823 : "\": Heating capacity curve output is <= 0.0 warning continues...",
1824 0 : this->HeatCapNegativeIndex,
1825 : QLoad,
1826 : QLoad);
1827 : }
1828 : }
1829 0 : if (Power <= 0.0) {
1830 0 : if (this->HeatPowerNegativeCounter < 1) {
1831 0 : ++this->HeatPowerNegativeCounter;
1832 0 : ShowWarningError(state, format("{} \"{}\":", HPEqFitHeating, this->Name));
1833 0 : ShowContinueError(state, format(" Heating compressor power curve output is <= 0.0 ({:.4T}).", Power));
1834 0 : ShowContinueError(state, format(" Zero or negative value occurs with a load-side inlet temperature of {:.2T} C,", LoadSideInletTemp));
1835 0 : ShowContinueError(state, format(" a source-side inlet temperature of {:.2T} C,", SourceSideInletTemp));
1836 0 : ShowContinueError(state, format(" a load-side mass flow rate of {:.3T} kg/s,", LoadSideMassFlowRate));
1837 0 : ShowContinueError(state, format(" and a source-side mass flow rate of {:.3T} kg/s.", SourceSideMassFlowRate));
1838 0 : ShowContinueErrorTimeStamp(state, " The heat pump is turned off for this time step but simulation continues.");
1839 : } else {
1840 0 : ShowRecurringWarningErrorAtEnd(state,
1841 0 : HPEqFitHeating + " \"" + this->Name +
1842 : "\": Heating compressor power curve output is <= 0.0 warning continues...",
1843 0 : this->HeatPowerNegativeIndex,
1844 : Power,
1845 : Power);
1846 : }
1847 : }
1848 :
1849 0 : QLoad = 0.0;
1850 0 : Power = 0.0;
1851 : }
1852 :
1853 17232 : QSource = QLoad - Power; // assume no losses
1854 :
1855 : // Control Strategy
1856 17232 : if (std::abs(MyLoad) < QLoad && QLoad != 0.0) {
1857 17232 : PartLoadRatio = std::abs(MyLoad) / QLoad;
1858 17232 : QLoad = std::abs(MyLoad);
1859 17232 : Power *= PartLoadRatio;
1860 17232 : QSource *= PartLoadRatio;
1861 : }
1862 :
1863 17232 : CpLoadSide = FluidProperties::GetSpecificHeatGlycol(state,
1864 17232 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidName,
1865 : LoadSideInletTemp,
1866 17232 : state.dataPlnt->PlantLoop(this->LoadPlantLoc.loopNum).FluidIndex,
1867 : RoutineName);
1868 :
1869 17232 : CpSourceSide = FluidProperties::GetSpecificHeatGlycol(state,
1870 17232 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidName,
1871 : SourceSideInletTemp,
1872 17232 : state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).FluidIndex,
1873 : RoutineName);
1874 :
1875 17232 : LoadSideOutletTemp = LoadSideInletTemp + QLoad / (LoadSideMassFlowRate * CpLoadSide);
1876 17232 : SourceSideOutletTemp = SourceSideInletTemp - QSource / (SourceSideMassFlowRate * CpSourceSide);
1877 :
1878 17232 : this->reportPower = Power;
1879 17232 : this->reportEnergy = Power * TimeStepSysSec;
1880 17232 : this->reportQSource = QSource;
1881 17232 : this->reportQLoad = QLoad;
1882 17232 : this->reportQSourceEnergy = QSource * TimeStepSysSec;
1883 17232 : this->reportQLoadEnergy = QLoad * TimeStepSysSec;
1884 17232 : this->reportLoadSideOutletTemp = LoadSideOutletTemp;
1885 17232 : this->reportSourceSideOutletTemp = SourceSideOutletTemp;
1886 : }
1887 :
1888 68086 : void GshpSpecs::UpdateGSHPRecords(EnergyPlusData &state)
1889 : {
1890 : // SUBROUTINE INFORMATION:
1891 : // AUTHOR: Kenneth Tang
1892 : // DATE WRITTEN: March 2005
1893 :
1894 68086 : int LoadSideOutletNode = this->LoadSideOutletNodeNum;
1895 68086 : int SourceSideOutletNode = this->SourceSideOutletNodeNum;
1896 :
1897 68086 : if (!this->MustRun) {
1898 : // Heatpump is off; just pass through conditions
1899 34514 : this->reportPower = 0.0;
1900 34514 : this->reportEnergy = 0.0;
1901 34514 : this->reportQSource = 0.0;
1902 34514 : this->reportQSourceEnergy = 0.0;
1903 34514 : this->reportQLoad = 0.0;
1904 34514 : this->reportQLoadEnergy = 0.0;
1905 34514 : this->reportLoadSideOutletTemp = this->reportLoadSideInletTemp;
1906 34514 : this->reportSourceSideOutletTemp = this->reportSourceSideInletTemp;
1907 : }
1908 :
1909 68086 : state.dataLoopNodes->Node(SourceSideOutletNode).Temp = this->reportSourceSideOutletTemp;
1910 68086 : state.dataLoopNodes->Node(LoadSideOutletNode).Temp = this->reportLoadSideOutletTemp;
1911 68086 : }
1912 0 : void GshpSpecs::oneTimeInit([[maybe_unused]] EnergyPlusData &state)
1913 : {
1914 0 : }
1915 4 : void GshpSpecs::oneTimeInit_new([[maybe_unused]] EnergyPlusData &state)
1916 : {
1917 4 : }
1918 :
1919 : } // namespace EnergyPlus::HeatPumpWaterToWaterSimple
|