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