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 : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
49 : #include <EnergyPlus/CurveManager.hh>
50 : #include <EnergyPlus/Data/EnergyPlusData.hh>
51 : #include <EnergyPlus/DataEnvironment.hh>
52 : #include <EnergyPlus/DataHVACGlobals.hh>
53 : #include <EnergyPlus/Fans.hh>
54 : #include <EnergyPlus/General.hh>
55 : #include <EnergyPlus/GeneralRoutines.hh>
56 : #include <EnergyPlus/Psychrometrics.hh>
57 : #include <EnergyPlus/SimAirServingZones.hh>
58 : #include <EnergyPlus/VariableSpeedCoils.hh>
59 : #include <EnergyPlus/WeatherManager.hh>
60 :
61 : namespace EnergyPlus {
62 :
63 3800 : Real64 CoolingCapacitySizer::size(EnergyPlusData &state, Real64 _originalValue, bool &errorsFound)
64 : {
65 3800 : if (!this->checkInitialized(state, errorsFound)) {
66 0 : return 0.0;
67 : }
68 3800 : this->preSize(state, _originalValue);
69 3800 : Real64 DesVolFlow = 0.0;
70 3800 : Real64 CoilInTemp = -999.0;
71 3800 : Real64 CoilInHumRat = -999.0;
72 3800 : Real64 CoilOutTemp = -999.0;
73 3800 : Real64 CoilOutHumRat = -999.0;
74 3800 : Real64 FanCoolLoad = 0.0;
75 3800 : Real64 TotCapTempModFac = 1.0;
76 3800 : Real64 DXFlowPerCapMinRatio = 1.0;
77 3800 : Real64 DXFlowPerCapMaxRatio = 1.0;
78 :
79 3800 : if (this->dataEMSOverrideON) {
80 0 : this->autoSizedValue = this->dataEMSOverride;
81 3800 : } else if (this->dataConstantUsedForSizing >= 0 && this->dataFractionUsedForSizing > 0) {
82 : // back and forth if dataConstantUsedForSizing should be > or >= 0 to make this work for AutoCalculate
83 308 : this->autoSizedValue = this->dataConstantUsedForSizing * this->dataFractionUsedForSizing;
84 : } else {
85 3492 : if (this->curZoneEqNum > 0) {
86 1124 : if (!this->wasAutoSized && !this->sizingDesRunThisZone) {
87 0 : this->autoSizedValue = _originalValue;
88 1124 : } else if (this->zoneEqSizing(this->curZoneEqNum).DesignSizeFromParent) {
89 162 : this->autoSizedValue = this->zoneEqSizing(this->curZoneEqNum).DesCoolingLoad;
90 : } else {
91 962 : if (this->zoneEqSizing(this->curZoneEqNum).CoolingCapacity) { // Parent object calculated capacity
92 363 : this->autoSizedValue = this->zoneEqSizing(this->curZoneEqNum).DesCoolingLoad;
93 363 : DesVolFlow = this->dataFlowUsedForSizing;
94 363 : CoilInTemp = state.dataSize->DataCoilSizingAirInTemp;
95 363 : CoilInHumRat = state.dataSize->DataCoilSizingAirInHumRat;
96 363 : CoilOutTemp = state.dataSize->DataCoilSizingAirOutTemp;
97 363 : CoilOutHumRat = state.dataSize->DataCoilSizingAirOutHumRat;
98 363 : FanCoolLoad = state.dataSize->DataCoilSizingFanCoolLoad;
99 363 : TotCapTempModFac = state.dataSize->DataCoilSizingCapFT;
100 : } else {
101 1146 : if (Util::SameString(this->compType, "COIL:COOLING:WATER") ||
102 1146 : Util::SameString(this->compType, "COIL:COOLING:WATER:DETAILEDGEOMETRY") ||
103 1146 : Util::SameString(this->compType, "ZONEHVAC:IDEALLOADSAIRSYSTEM")) {
104 64 : if (this->termUnitIU && (this->curTermUnitSizingNum > 0)) {
105 8 : this->autoSizedValue = this->termUnitSizing(this->curTermUnitSizingNum).DesCoolingLoad;
106 56 : } else if (this->zoneEqFanCoil) {
107 0 : this->autoSizedValue = this->zoneEqSizing(this->curZoneEqNum).DesCoolingLoad;
108 : } else {
109 56 : CoilInTemp = this->finalZoneSizing(this->curZoneEqNum).DesCoolCoilInTemp;
110 56 : CoilInHumRat = this->finalZoneSizing(this->curZoneEqNum).DesCoolCoilInHumRat;
111 56 : CoilOutTemp = min(CoilInTemp, this->finalZoneSizing(this->curZoneEqNum).CoolDesTemp);
112 56 : CoilOutHumRat = min(CoilInHumRat, this->finalZoneSizing(this->curZoneEqNum).CoolDesHumRat);
113 56 : this->autoSizedValue =
114 56 : this->finalZoneSizing(this->curZoneEqNum).DesCoolMassFlow *
115 56 : (Psychrometrics::PsyHFnTdbW(CoilInTemp, CoilInHumRat) - Psychrometrics::PsyHFnTdbW(CoilOutTemp, CoilOutHumRat));
116 56 : DesVolFlow = this->finalZoneSizing(this->curZoneEqNum).DesCoolMassFlow / state.dataEnvrn->StdRhoAir;
117 : // add fan heat to coil load
118 56 : FanCoolLoad += this->calcFanDesHeatGain(DesVolFlow);
119 56 : this->autoSizedValue += FanCoolLoad;
120 : }
121 : } else {
122 535 : DesVolFlow = this->dataFlowUsedForSizing;
123 535 : if (DesVolFlow >= HVAC::SmallAirVolFlow) {
124 : // each of these IFs now seem the same and can be condensed to just CoilInTemp = set() and CoilInHumRat = set()
125 535 : if (state.dataSize->ZoneEqDXCoil) {
126 : // ATMixer has priority over Equipment OA vol flow
127 410 : if (this->zoneEqSizing(this->curZoneEqNum).ATMixerVolFlow > 0.0) { // NEW ATMixer coil sizing method
128 24 : Real64 DesMassFlow = DesVolFlow * state.dataEnvrn->StdRhoAir;
129 24 : CoilInTemp = setCoolCoilInletTempForZoneEqSizing(
130 24 : setOAFracForZoneEqSizing(state, DesMassFlow, zoneEqSizing(this->curZoneEqNum)),
131 24 : zoneEqSizing(this->curZoneEqNum),
132 24 : finalZoneSizing(this->curZoneEqNum));
133 24 : CoilInHumRat = setCoolCoilInletHumRatForZoneEqSizing(
134 24 : setOAFracForZoneEqSizing(state, DesMassFlow, zoneEqSizing(this->curZoneEqNum)),
135 24 : zoneEqSizing(this->curZoneEqNum),
136 24 : finalZoneSizing(this->curZoneEqNum));
137 386 : } else if (this->zoneEqSizing(this->curZoneEqNum).OAVolFlow > 0.0) {
138 209 : CoilInTemp = this->finalZoneSizing(this->curZoneEqNum).DesCoolCoilInTemp;
139 209 : CoilInHumRat = this->finalZoneSizing(this->curZoneEqNum).DesCoolCoilInHumRat;
140 : } else {
141 177 : CoilInTemp = this->finalZoneSizing(this->curZoneEqNum)
142 177 : .ZoneRetTempAtCoolPeak; // Question whether zone equipment should use return temp for sizing
143 177 : CoilInHumRat = this->finalZoneSizing(this->curZoneEqNum).ZoneHumRatAtCoolPeak;
144 : }
145 125 : } else if (this->zoneEqFanCoil) {
146 : // use fan coil flow (i.e., set by parent) or flow used during sizing?
147 81 : Real64 DesMassFlow = this->finalZoneSizing(this->curZoneEqNum).DesCoolMassFlow;
148 81 : CoilInTemp = setCoolCoilInletTempForZoneEqSizing(
149 81 : setOAFracForZoneEqSizing(state, DesMassFlow, zoneEqSizing(this->curZoneEqNum)),
150 81 : zoneEqSizing(this->curZoneEqNum),
151 81 : finalZoneSizing(this->curZoneEqNum));
152 81 : CoilInHumRat = setCoolCoilInletHumRatForZoneEqSizing(
153 81 : setOAFracForZoneEqSizing(state, DesMassFlow, zoneEqSizing(this->curZoneEqNum)),
154 81 : zoneEqSizing(this->curZoneEqNum),
155 81 : finalZoneSizing(this->curZoneEqNum));
156 : } else {
157 44 : CoilInTemp = this->finalZoneSizing(this->curZoneEqNum).DesCoolCoilInTemp;
158 44 : CoilInHumRat = this->finalZoneSizing(this->curZoneEqNum).DesCoolCoilInHumRat;
159 : }
160 535 : CoilOutTemp = min(CoilInTemp, this->finalZoneSizing(this->curZoneEqNum).CoolDesTemp);
161 535 : CoilOutHumRat = min(CoilInHumRat, this->finalZoneSizing(this->curZoneEqNum).CoolDesHumRat);
162 535 : int TimeStepNumAtMax = this->finalZoneSizing(this->curZoneEqNum).TimeStepNumAtCoolMax;
163 535 : int DDNum = this->finalZoneSizing(this->curZoneEqNum).CoolDDNum;
164 535 : Real64 OutTemp = 0.0;
165 535 : if (DDNum > 0 && TimeStepNumAtMax > 0) {
166 535 : OutTemp = state.dataSize->DesDayWeath(DDNum).Temp(TimeStepNumAtMax);
167 : }
168 535 : if (this->dataCoolCoilType == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
169 3 : OutTemp = VariableSpeedCoils::GetVSCoilRatedSourceTemp(state, this->dataCoolCoilIndex);
170 : }
171 535 : Real64 CoilInEnth = Psychrometrics::PsyHFnTdbW(CoilInTemp, CoilInHumRat);
172 535 : Real64 CoilOutEnth = Psychrometrics::PsyHFnTdbW(CoilOutTemp, CoilOutHumRat);
173 535 : Real64 PeakCoilLoad = max(0.0, (state.dataEnvrn->StdRhoAir * DesVolFlow * (CoilInEnth - CoilOutEnth)));
174 : // add fan heat to coil load
175 535 : FanCoolLoad += this->calcFanDesHeatGain(DesVolFlow);
176 535 : PeakCoilLoad += FanCoolLoad;
177 535 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(CoilInHumRat);
178 : // adjust coil inlet/outlet temp with fan temperature rise
179 535 : if (this->dataDesAccountForFanHeat) {
180 535 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
181 307 : CoilInTemp += FanCoolLoad / (CpAir * state.dataEnvrn->StdRhoAir * DesVolFlow);
182 228 : } else if (state.dataSize->DataFanPlacement == HVAC::FanPlace::DrawThru) {
183 220 : CoilOutTemp -= FanCoolLoad / (CpAir * state.dataEnvrn->StdRhoAir * DesVolFlow);
184 : }
185 : }
186 : Real64 CoilInWetBulb =
187 535 : Psychrometrics::PsyTwbFnTdbWPb(state, CoilInTemp, CoilInHumRat, state.dataEnvrn->StdBaroPress, this->callingRoutine);
188 535 : if (this->dataTotCapCurveIndex > 0) {
189 262 : switch (state.dataCurveManager->curves(this->dataTotCapCurveIndex)->numDims) {
190 29 : case 1:
191 29 : TotCapTempModFac = Curve::CurveValue(state, this->dataTotCapCurveIndex, CoilInWetBulb);
192 29 : break;
193 233 : case 2:
194 : default: // this default allows the simulation to continue, but will issue a warning, should be removed eventually
195 233 : TotCapTempModFac = Curve::CurveValue(state, this->dataTotCapCurveIndex, CoilInWetBulb, OutTemp);
196 233 : break;
197 : }
198 273 : } else if (this->dataTotCapCurveValue > 0) {
199 16 : TotCapTempModFac = this->dataTotCapCurveValue;
200 : } else {
201 257 : TotCapTempModFac = 1.0;
202 : }
203 535 : if (TotCapTempModFac > 0.0) {
204 535 : this->autoSizedValue = PeakCoilLoad / TotCapTempModFac;
205 : } else {
206 0 : this->autoSizedValue = PeakCoilLoad;
207 : }
208 : // save these conditions to use when this->zoneEqSizing(this->curZoneEqNum).CoolingCapacity = true
209 535 : state.dataSize->DataCoilSizingAirInTemp = CoilInTemp;
210 535 : state.dataSize->DataCoilSizingAirInHumRat = CoilInHumRat;
211 535 : state.dataSize->DataCoilSizingAirOutTemp = CoilOutTemp;
212 535 : state.dataSize->DataCoilSizingAirOutHumRat = CoilOutHumRat;
213 535 : state.dataSize->DataCoilSizingFanCoolLoad = FanCoolLoad;
214 535 : state.dataSize->DataCoilSizingCapFT = TotCapTempModFac;
215 : } else {
216 0 : this->autoSizedValue = 0.0;
217 0 : CoilOutTemp = -999.0;
218 : }
219 : }
220 : }
221 962 : this->autoSizedValue = this->autoSizedValue * this->dataFracOfAutosizedCoolingCapacity;
222 962 : this->dataDesAccountForFanHeat = true; // reset for next water coil
223 962 : if (state.dataGlobal->DisplayExtraWarnings && this->autoSizedValue <= 0.0) {
224 0 : ShowWarningMessage(state,
225 0 : this->callingRoutine + ": Potential issue with equipment sizing for " + this->compType + ' ' + this->compName);
226 0 : ShowContinueError(state, format("...Rated Total Cooling Capacity = {:.2T} [W]", this->autoSizedValue));
227 0 : if (this->zoneEqSizing(this->curZoneEqNum).CoolingCapacity) {
228 0 : ShowContinueError(state,
229 0 : format("...Capacity passed by parent object to size child component = {:.2T} [W]", this->autoSizedValue));
230 : } else {
231 0 : if (Util::SameString(this->compType, "COIL:COOLING:WATER") ||
232 0 : Util::SameString(this->compType, "COIL:COOLING:WATER:DETAILEDGEOMETRY") ||
233 0 : Util::SameString(this->compType, "ZONEHVAC:IDEALLOADSAIRSYSTEM")) {
234 0 : if (this->termUnitIU || this->zoneEqFanCoil) {
235 0 : ShowContinueError(
236 0 : state, format("...Capacity passed by parent object to size child component = {:.2T} [W]", this->autoSizedValue));
237 : } else {
238 0 : ShowContinueError(state, format("...Air flow rate used for sizing = {:.5T} [m3/s]", DesVolFlow));
239 0 : ShowContinueError(state, format("...Coil inlet air temperature used for sizing = {:.2T} [C]", CoilInTemp));
240 0 : ShowContinueError(state, format("...Coil outlet air temperature used for sizing = {:.2T} [C]", CoilOutTemp));
241 : }
242 : } else {
243 0 : if (CoilOutTemp > -999.0) {
244 0 : ShowContinueError(state, format("...Air flow rate used for sizing = {:.5T} [m3/s]", DesVolFlow));
245 0 : ShowContinueError(state, format("...Coil inlet air temperature used for sizing = {:.2T} [C]", CoilInTemp));
246 0 : ShowContinueError(state, format("...Coil outlet air temperature used for sizing = {:.2T} [C]", CoilOutTemp));
247 : } else {
248 0 : ShowContinueError(state, "...Capacity used to size child component set to 0 [W]");
249 : }
250 : }
251 : }
252 : }
253 : }
254 2368 : } else if (this->curSysNum > 0) {
255 2344 : if (!this->wasAutoSized && !this->sizingDesRunThisAirSys) {
256 194 : this->autoSizedValue = _originalValue;
257 : } else {
258 2150 : Real64 OutAirFrac = 0.0;
259 2150 : this->dataFracOfAutosizedCoolingCapacity = 1.0;
260 2150 : if (this->oaSysFlag) {
261 0 : this->autoSizedValue = this->oaSysEqSizing(this->curOASysNum).DesCoolingLoad;
262 0 : DesVolFlow = this->dataFlowUsedForSizing;
263 2150 : } else if (this->airLoopSysFlag) {
264 368 : this->autoSizedValue = this->unitarySysEqSizing(this->curSysNum).DesCoolingLoad;
265 368 : DesVolFlow = this->dataFlowUsedForSizing;
266 368 : CoilInTemp = state.dataSize->DataCoilSizingAirInTemp;
267 368 : CoilInHumRat = state.dataSize->DataCoilSizingAirInHumRat;
268 368 : CoilOutTemp = state.dataSize->DataCoilSizingAirOutTemp;
269 368 : CoilOutHumRat = state.dataSize->DataCoilSizingAirOutHumRat;
270 368 : FanCoolLoad = state.dataSize->DataCoilSizingFanCoolLoad;
271 368 : TotCapTempModFac = state.dataSize->DataCoilSizingCapFT;
272 368 : if (state.dataRptCoilSelection->coilSelectionReportObj->isCompTypeCoil(this->compType)) {
273 212 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, this->compName, this->compType, CoilInHumRat);
274 212 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
275 212 : state, this->compName, this->compType, CoilInTemp, this->curSysNum, this->curZoneEqNum);
276 212 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, this->compName, this->compType, CoilOutTemp);
277 212 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, this->compName, this->compType, CoilOutHumRat);
278 : }
279 1782 : } else if (this->curOASysNum > 0 && this->outsideAirSys(this->curOASysNum).AirLoopDOASNum > -1) {
280 2 : auto &thisAirloopDOAS = this->airloopDOAS[this->outsideAirSys(this->curOASysNum).AirLoopDOASNum];
281 2 : DesVolFlow = thisAirloopDOAS.SizingMassFlow / state.dataEnvrn->StdRhoAir;
282 2 : CoilInTemp = thisAirloopDOAS.SizingCoolOATemp;
283 2 : CoilOutTemp = thisAirloopDOAS.PrecoolTemp;
284 2 : if (thisAirloopDOAS.m_FanIndex > 0) {
285 : // This should work for all fan types
286 2 : state.dataFans->fans(thisAirloopDOAS.m_FanIndex)
287 2 : ->getInputsForDesignHeatGain(state,
288 2 : this->deltaP,
289 2 : this->motEff,
290 2 : this->totEff,
291 2 : this->motInAirFrac,
292 2 : this->fanShaftPow,
293 2 : this->motInPower,
294 2 : this->fanCompModel);
295 :
296 2 : if (thisAirloopDOAS.m_FanTypeNum == SimAirServingZones::CompType::Fan_ComponentModel) {
297 0 : FanCoolLoad = this->fanShaftPow + (this->motInPower - this->fanShaftPow) * this->motInAirFrac;
298 2 : } else if (thisAirloopDOAS.m_FanTypeNum == SimAirServingZones::CompType::Fan_System_Object) {
299 2 : Real64 const fanPowerTot = (DesVolFlow * this->deltaP) / this->totEff;
300 2 : FanCoolLoad = this->motEff * fanPowerTot + (fanPowerTot - this->motEff * fanPowerTot) * this->motInAirFrac;
301 : }
302 2 : this->dataFanType = state.dataFans->fans(thisAirloopDOAS.m_FanIndex)->type;
303 2 : this->dataFanIndex = thisAirloopDOAS.m_FanIndex;
304 2 : Real64 const CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(thisAirloopDOAS.m_FanInletNodeNum).HumRat);
305 2 : Real64 const DeltaT = FanCoolLoad / (thisAirloopDOAS.SizingMassFlow * CpAir);
306 2 : if (thisAirloopDOAS.FanBeforeCoolingCoilFlag) {
307 2 : CoilInTemp += DeltaT;
308 : } else {
309 0 : CoilOutTemp -= DeltaT;
310 0 : CoilOutTemp =
311 0 : max(CoilOutTemp, Psychrometrics::PsyTdpFnWPb(state, thisAirloopDOAS.PrecoolHumRat, state.dataEnvrn->StdBaroPress));
312 : }
313 : }
314 2 : CoilInHumRat = thisAirloopDOAS.SizingCoolOAHumRat;
315 2 : CoilOutHumRat = thisAirloopDOAS.PrecoolHumRat;
316 2 : this->autoSizedValue =
317 2 : DesVolFlow * state.dataEnvrn->StdRhoAir *
318 2 : (Psychrometrics::PsyHFnTdbW(CoilInTemp, CoilInHumRat) - Psychrometrics::PsyHFnTdbW(CoilOutTemp, CoilOutHumRat));
319 : } else {
320 1780 : CheckSysSizing(state, this->compType, this->compName);
321 1780 : auto const &thisFinalSysSizing = this->finalSysSizing(this->curSysNum);
322 1780 : DesVolFlow = this->dataFlowUsedForSizing;
323 1780 : Real64 NominalCapacityDes = 0.0;
324 1780 : if (thisFinalSysSizing.CoolingCapMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
325 2 : this->dataFracOfAutosizedCoolingCapacity = thisFinalSysSizing.FractionOfAutosizedCoolingCapacity;
326 : }
327 1780 : if (thisFinalSysSizing.CoolingCapMethod == DataSizing::CapacityPerFloorArea) {
328 0 : NominalCapacityDes = thisFinalSysSizing.CoolingTotalCapacity;
329 0 : this->autoSizedValue = NominalCapacityDes;
330 1780 : } else if (thisFinalSysSizing.CoolingCapMethod == DataSizing::CoolingDesignCapacity &&
331 1778 : thisFinalSysSizing.CoolingTotalCapacity > 0.0) {
332 0 : NominalCapacityDes = thisFinalSysSizing.CoolingTotalCapacity;
333 0 : this->autoSizedValue = NominalCapacityDes;
334 1780 : } else if (DesVolFlow >= HVAC::SmallAirVolFlow) {
335 1780 : if (DesVolFlow > 0.0) {
336 1780 : OutAirFrac = thisFinalSysSizing.DesOutAirVolFlow / DesVolFlow;
337 : } else {
338 0 : OutAirFrac = 1.0;
339 : }
340 1780 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
341 1780 : if (this->curOASysNum > 0) { // coil is in the OA stream
342 62 : CoilInTemp = thisFinalSysSizing.OutTempAtCoolPeak;
343 62 : CoilInHumRat = thisFinalSysSizing.OutHumRatAtCoolPeak;
344 62 : CoilOutTemp = thisFinalSysSizing.PrecoolTemp;
345 62 : CoilOutHumRat = thisFinalSysSizing.PrecoolHumRat;
346 : } else { // coil is on the main air loop
347 1718 : if (this->dataAirFlowUsedForSizing > 0.0) {
348 706 : DesVolFlow = this->dataAirFlowUsedForSizing;
349 : }
350 1718 : if (this->dataDesOutletAirTemp > 0.0) {
351 706 : CoilOutTemp = this->dataDesOutletAirTemp;
352 : } else {
353 1012 : CoilOutTemp = thisFinalSysSizing.CoolSupTemp;
354 : }
355 1718 : if (this->dataDesOutletAirHumRat > 0.0) {
356 706 : CoilOutHumRat = this->dataDesOutletAirHumRat;
357 : } else {
358 1012 : CoilOutHumRat = thisFinalSysSizing.CoolSupHumRat;
359 : }
360 :
361 1718 : if (this->primaryAirSystem(this->curSysNum).NumOACoolCoils == 0) { // there is no precooling of the OA stream
362 1661 : CoilInTemp = thisFinalSysSizing.MixTempAtCoolPeak;
363 1661 : CoilInHumRat = thisFinalSysSizing.MixHumRatAtCoolPeak;
364 : } else { // there is precooling of OA stream
365 57 : if (DesVolFlow > 0.0) {
366 57 : OutAirFrac = thisFinalSysSizing.DesOutAirVolFlow / DesVolFlow;
367 : } else {
368 0 : OutAirFrac = 1.0;
369 : }
370 57 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
371 57 : CoilInTemp = OutAirFrac * thisFinalSysSizing.PrecoolTemp + (1.0 - OutAirFrac) * thisFinalSysSizing.RetTempAtCoolPeak;
372 57 : CoilInHumRat =
373 57 : OutAirFrac * thisFinalSysSizing.PrecoolHumRat + (1.0 - OutAirFrac) * thisFinalSysSizing.RetHumRatAtCoolPeak;
374 : }
375 1718 : if (this->dataDesInletAirTemp > 0.0) {
376 353 : CoilInTemp = this->dataDesInletAirTemp;
377 : }
378 1718 : if (this->dataDesInletAirHumRat > 0.0) {
379 706 : CoilInHumRat = this->dataDesInletAirHumRat;
380 : }
381 : }
382 1780 : Real64 OutTemp = thisFinalSysSizing.OutTempAtCoolPeak;
383 1780 : if (this->dataCoolCoilType == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
384 0 : OutTemp = VariableSpeedCoils::GetVSCoilRatedSourceTemp(state, this->dataCoolCoilIndex);
385 : }
386 1780 : CoilOutTemp = min(CoilInTemp, CoilOutTemp);
387 1780 : CoilOutHumRat = min(CoilInHumRat, CoilOutHumRat);
388 1780 : Real64 CoilInEnth = Psychrometrics::PsyHFnTdbW(CoilInTemp, CoilInHumRat);
389 : Real64 CoilInWetBulb =
390 1780 : Psychrometrics::PsyTwbFnTdbWPb(state, CoilInTemp, CoilInHumRat, state.dataEnvrn->StdBaroPress, this->callingRoutine);
391 1780 : Real64 CoilOutEnth = Psychrometrics::PsyHFnTdbW(CoilOutTemp, CoilOutHumRat);
392 1780 : if (this->curOASysNum > 0) { // coil is in the OA stream
393 : // need to find fan type in OA system
394 : } else {
395 1718 : if (this->primaryAirSystem(this->curSysNum).supFanType != HVAC::FanType::Invalid) {
396 1712 : FanCoolLoad = this->calcFanDesHeatGain(DesVolFlow);
397 : }
398 1718 : if (this->primaryAirSystem(this->curSysNum).retFanType != HVAC::FanType::Invalid) {
399 8 : FanCoolLoad += (1.0 - OutAirFrac) * this->calcFanDesHeatGain(DesVolFlow);
400 : }
401 1718 : this->primaryAirSystem(this->curSysNum).FanDesCoolLoad = FanCoolLoad;
402 : }
403 1780 : Real64 PeakCoilLoad = max(0.0, (state.dataEnvrn->StdRhoAir * DesVolFlow * (CoilInEnth - CoilOutEnth)));
404 1780 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(CoilInHumRat);
405 : // adjust coil inlet/outlet temp with fan temperature rise
406 1780 : if (this->dataDesAccountForFanHeat) {
407 1397 : PeakCoilLoad = max(0.0, (state.dataEnvrn->StdRhoAir * DesVolFlow * (CoilInEnth - CoilOutEnth) + FanCoolLoad));
408 1397 : if (this->primaryAirSystem(this->curSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
409 328 : CoilInTemp += FanCoolLoad / (CpAir * state.dataEnvrn->StdRhoAir * DesVolFlow);
410 : // include change in inlet condition in TotCapTempModFac
411 656 : CoilInWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
412 328 : state, CoilInTemp, CoilInHumRat, state.dataEnvrn->StdBaroPress, this->callingRoutine);
413 1069 : } else if (this->primaryAirSystem(this->curSysNum).supFanPlace == HVAC::FanPlace::DrawThru) {
414 1069 : CoilOutTemp -= FanCoolLoad / (CpAir * state.dataEnvrn->StdRhoAir * DesVolFlow);
415 : }
416 : }
417 1780 : if (this->dataTotCapCurveIndex > 0) {
418 763 : switch (state.dataCurveManager->curves(this->dataTotCapCurveIndex)->numDims) {
419 2 : case 1:
420 2 : TotCapTempModFac = Curve::CurveValue(state, this->dataTotCapCurveIndex, CoilInWetBulb);
421 2 : break;
422 761 : case 2:
423 : default: // this default allows the simulation to continue, but will issue a warning, should be removed eventually
424 761 : TotCapTempModFac = Curve::CurveValue(state, this->dataTotCapCurveIndex, CoilInWetBulb, OutTemp);
425 761 : break;
426 : }
427 : } else {
428 1017 : TotCapTempModFac = 1.0;
429 : }
430 1780 : if (TotCapTempModFac > 0.0) {
431 1780 : NominalCapacityDes = PeakCoilLoad / TotCapTempModFac;
432 : } else {
433 0 : NominalCapacityDes = PeakCoilLoad;
434 : }
435 1780 : state.dataSize->DataCoilSizingAirInTemp = CoilInTemp;
436 1780 : state.dataSize->DataCoilSizingAirInHumRat = CoilInHumRat;
437 1780 : state.dataSize->DataCoilSizingAirOutTemp = CoilOutTemp;
438 1780 : state.dataSize->DataCoilSizingAirOutHumRat = CoilOutHumRat;
439 1780 : state.dataSize->DataCoilSizingFanCoolLoad = FanCoolLoad;
440 1780 : state.dataSize->DataCoilSizingCapFT = TotCapTempModFac;
441 : } else {
442 0 : NominalCapacityDes = 0.0;
443 : }
444 1780 : this->autoSizedValue =
445 1780 : NominalCapacityDes * this->dataFracOfAutosizedCoolingCapacity; // Fixed Moved up 1 line inside block per Richard Raustad
446 : } // IF(OASysFlag) THEN or ELSE IF(AirLoopSysFlag) THEN
447 2150 : this->dataDesAccountForFanHeat = true; // reset for next water coil
448 2150 : if (state.dataGlobal->DisplayExtraWarnings && this->autoSizedValue <= 0.0) {
449 0 : ShowWarningMessage(state,
450 0 : this->callingRoutine + ": Potential issue with equipment sizing for " + this->compType + ' ' + this->compName);
451 0 : ShowContinueError(state, format("...Rated Total Cooling Capacity = {:.2T} [W]", this->autoSizedValue));
452 0 : if (this->oaSysFlag || this->airLoopSysFlag ||
453 0 : this->finalSysSizing(this->curSysNum).CoolingCapMethod == DataSizing::CapacityPerFloorArea ||
454 0 : (this->finalSysSizing(this->curSysNum).CoolingCapMethod == DataSizing::CoolingDesignCapacity &&
455 0 : this->finalSysSizing(this->curSysNum).CoolingTotalCapacity)) {
456 0 : ShowContinueError(state,
457 0 : format("...Capacity passed by parent object to size child component = {:.2T} [W]", this->autoSizedValue));
458 : } else {
459 0 : ShowContinueError(state, format("...Air flow rate used for sizing = {:.5T} [m3/s]", DesVolFlow));
460 0 : ShowContinueError(state, format("...Outdoor air fraction used for sizing = {:.2T}", OutAirFrac));
461 0 : ShowContinueError(state, format("...Coil inlet air temperature used for sizing = {:.2T} [C]", CoilInTemp));
462 0 : ShowContinueError(state, format("...Coil outlet air temperature used for sizing = {:.2T} [C]", CoilOutTemp));
463 : }
464 : }
465 : }
466 24 : } else if (this->dataNonZoneNonAirloopValue > 0) {
467 24 : this->autoSizedValue = this->dataNonZoneNonAirloopValue;
468 0 : } else if (!this->wasAutoSized) {
469 0 : this->autoSizedValue = this->originalValue;
470 : } else {
471 0 : std::string msg = this->callingRoutine + ' ' + this->compType + ' ' + this->compName + ", Developer Error: Component sizing incomplete.";
472 0 : ShowSevereError(state, msg);
473 0 : this->addErrorMessage(msg);
474 0 : msg = format("SizingString = {}, SizingResult = {:.1T}", this->sizingString, this->autoSizedValue);
475 0 : ShowContinueError(state, msg);
476 0 : this->addErrorMessage(msg);
477 0 : errorsFound = true;
478 0 : }
479 : }
480 3800 : if (this->dataDXCoolsLowSpeedsAutozize) {
481 67 : this->autoSizedValue *= this->dataFractionUsedForSizing;
482 : }
483 3800 : if (!this->hardSizeNoDesignRun || this->dataScalableSizingON || this->dataScalableCapSizingON) {
484 3604 : if (this->wasAutoSized) {
485 : // Note: the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil model, which implements variable flow fans and
486 : // determines capacity using physical calculations instead of emperical curves
487 3169 : bool FlagCheckVolFlowPerRatedTotCap = true;
488 6323 : if (Util::SameString(this->compType, "Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl") ||
489 6323 : Util::SameString(this->compType, "Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl")) {
490 15 : FlagCheckVolFlowPerRatedTotCap = false;
491 : }
492 :
493 3169 : if (this->dataIsDXCoil && FlagCheckVolFlowPerRatedTotCap) {
494 1145 : Real64 RatedVolFlowPerRatedTotCap = 0.0;
495 1145 : if (this->autoSizedValue > 0.0) {
496 1145 : RatedVolFlowPerRatedTotCap = DesVolFlow / this->autoSizedValue;
497 : }
498 1145 : if (RatedVolFlowPerRatedTotCap < HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) {
499 288 : if (!this->dataEMSOverride && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
500 1 : ShowWarningError(state, this->callingRoutine + ' ' + this->compType + ' ' + this->compName);
501 2 : ShowContinueError(
502 2 : state, "..." + this->sizingString + " will be limited by the minimum rated volume flow per rated total capacity ratio.");
503 1 : ShowContinueError(state, format("...DX coil volume flow rate (m3/s ) = {:.6T}", DesVolFlow));
504 1 : ShowContinueError(state, format("...Requested capacity (W ) = {:.3T}", this->autoSizedValue));
505 1 : ShowContinueError(state, format("...Requested flow/capacity ratio (m3/s/W ) = {:.3T}", RatedVolFlowPerRatedTotCap));
506 2 : ShowContinueError(state,
507 2 : format("...Minimum flow/capacity ratio (m3/s/W ) = {:.3T}",
508 1 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
509 : }
510 :
511 288 : DXFlowPerCapMinRatio = (DesVolFlow / HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) /
512 288 : this->autoSizedValue; // set DX Coil Capacity Increase Ratio from Too Low Flow/Capacity Ratio
513 288 : this->autoSizedValue = DesVolFlow / HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT];
514 :
515 288 : if (!this->dataEMSOverride && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
516 1 : ShowContinueError(state, format("...Adjusted capacity ( W ) = {:.3T}", this->autoSizedValue));
517 : }
518 857 : } else if (RatedVolFlowPerRatedTotCap > HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) {
519 122 : if (!this->dataEMSOverride && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
520 0 : ShowWarningError(state, this->callingRoutine + ' ' + this->compType + ' ' + this->compName);
521 0 : ShowContinueError(
522 0 : state, "..." + this->sizingString + " will be limited by the maximum rated volume flow per rated total capacity ratio.");
523 0 : ShowContinueError(state, format("...DX coil volume flow rate ( m3/s ) = {:.6T}", DesVolFlow));
524 0 : ShowContinueError(state, format("...Requested capacity ( W ) = {:.3T}", this->autoSizedValue));
525 0 : ShowContinueError(state, format("...Requested flow/capacity ratio ( m3/s/W ) = {:.3T}", RatedVolFlowPerRatedTotCap));
526 0 : ShowContinueError(state,
527 0 : format("...Maximum flow/capacity ratio ( m3/s/W ) = {:.3T}",
528 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
529 : }
530 :
531 122 : DXFlowPerCapMaxRatio = DesVolFlow / HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] /
532 122 : this->autoSizedValue; // set DX Coil Capacity Decrease Ratio from Too High Flow/Capacity Ratio
533 122 : this->autoSizedValue = DesVolFlow / HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT];
534 :
535 122 : if (!this->dataEMSOverride && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
536 0 : ShowContinueError(state, format("...Adjusted capacity ( W ) = {:.3T}", this->autoSizedValue));
537 : }
538 : }
539 : }
540 : }
541 : }
542 :
543 : // override sizing string
544 3800 : if (this->overrideSizeString) {
545 10 : if (this->isEpJSON) {
546 0 : this->sizingString = "cooling_design_capacity [W]";
547 : }
548 : }
549 3800 : if (this->dataScalableCapSizingON) {
550 7 : int const SELECT_CASE_var(this->zoneEqSizing(this->curZoneEqNum).SizingMethod(HVAC::CoolingCapacitySizing));
551 7 : if (SELECT_CASE_var == DataSizing::CapacityPerFloorArea) {
552 3 : this->sizingStringScalable = "(scaled by capacity / area) ";
553 4 : } else if (SELECT_CASE_var == DataSizing::FractionOfAutosizedHeatingCapacity ||
554 : SELECT_CASE_var == DataSizing::FractionOfAutosizedCoolingCapacity) {
555 3 : this->sizingStringScalable = "(scaled by fractional multiplier) ";
556 : }
557 : }
558 :
559 3800 : this->selectSizerOutput(state, errorsFound);
560 :
561 3800 : if (this->isCoilReportObject && this->curSysNum <= state.dataHVACGlobal->NumPrimaryAirSys) {
562 2134 : if (CoilInTemp > -999.0) { // set inlet air properties used during capacity sizing if available, allow for negative winter temps
563 1721 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
564 1721 : state, this->compName, this->compType, CoilInTemp, this->curSysNum, this->curZoneEqNum);
565 1721 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, this->compName, this->compType, CoilInHumRat);
566 : }
567 2134 : if (CoilOutTemp > -999.0) { // set outlet air properties used during capacity sizing if available
568 1721 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, this->compName, this->compType, CoilOutTemp);
569 1721 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, this->compName, this->compType, CoilOutHumRat);
570 : }
571 2134 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilCoolingCapacity(state,
572 2134 : this->compName,
573 2134 : this->compType,
574 : this->autoSizedValue,
575 2134 : this->wasAutoSized,
576 : this->curSysNum,
577 : this->curZoneEqNum,
578 : this->curOASysNum,
579 : FanCoolLoad,
580 : TotCapTempModFac,
581 : DXFlowPerCapMinRatio,
582 : DXFlowPerCapMaxRatio);
583 : }
584 3800 : return this->autoSizedValue;
585 : }
586 :
587 0 : void CoolingCapacitySizer::clearState()
588 : {
589 0 : BaseSizerWithScalableInputs::clearState();
590 0 : }
591 :
592 : } // namespace EnergyPlus
|