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