Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #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 3483 : Real64 CoolingCapacitySizer::size(EnergyPlusData &state, Real64 _originalValue, bool &errorsFound)
64 : {
65 3483 : if (!this->checkInitialized(state, errorsFound)) {
66 0 : return 0.0;
67 : }
68 3483 : this->preSize(state, _originalValue);
69 3483 : Real64 DesVolFlow = 0.0;
70 3483 : Real64 CoilInTemp = -999.0;
71 3483 : Real64 CoilInHumRat = -999.0;
72 3483 : Real64 CoilOutTemp = -999.0;
73 3483 : Real64 CoilOutHumRat = -999.0;
74 3483 : Real64 FanCoolLoad = 0.0;
75 3483 : Real64 TotCapTempModFac = 1.0;
76 3483 : Real64 DXFlowPerCapMinRatio = 1.0;
77 3483 : Real64 DXFlowPerCapMaxRatio = 1.0;
78 :
79 3483 : if (this->dataEMSOverrideON) {
80 0 : this->autoSizedValue = this->dataEMSOverride;
81 3483 : } 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 180 : this->autoSizedValue = this->dataConstantUsedForSizing * this->dataFractionUsedForSizing;
84 : } else {
85 3303 : if (this->curZoneEqNum > 0) {
86 981 : if (!this->wasAutoSized && !this->sizingDesRunThisZone) {
87 6 : this->autoSizedValue = _originalValue;
88 975 : } else if (this->zoneEqSizing(this->curZoneEqNum).DesignSizeFromParent) {
89 162 : this->autoSizedValue = this->zoneEqSizing(this->curZoneEqNum).DesCoolingLoad;
90 : } else {
91 813 : if (this->zoneEqSizing(this->curZoneEqNum).CoolingCapacity) { // Parent object calculated capacity
92 353 : this->autoSizedValue = this->zoneEqSizing(this->curZoneEqNum).DesCoolingLoad;
93 353 : DesVolFlow = this->dataFlowUsedForSizing;
94 353 : CoilInTemp = state.dataSize->DataCoilSizingAirInTemp;
95 353 : CoilInHumRat = state.dataSize->DataCoilSizingAirInHumRat;
96 353 : CoilOutTemp = state.dataSize->DataCoilSizingAirOutTemp;
97 353 : CoilOutHumRat = state.dataSize->DataCoilSizingAirOutHumRat;
98 353 : FanCoolLoad = state.dataSize->DataCoilSizingFanCoolLoad;
99 353 : TotCapTempModFac = state.dataSize->DataCoilSizingCapFT;
100 : } else {
101 868 : if (Util::SameString(this->compType, "COIL:COOLING:WATER") ||
102 868 : Util::SameString(this->compType, "COIL:COOLING:WATER:DETAILEDGEOMETRY") ||
103 868 : 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 396 : DesVolFlow = this->dataFlowUsedForSizing;
123 396 : 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 396 : if (state.dataSize->ZoneEqDXCoil) {
126 : // ATMixer has priority over Equipment OA vol flow
127 271 : 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 247 : } else if (this->zoneEqSizing(this->curZoneEqNum).OAVolFlow > 0.0) {
138 205 : CoilInTemp = this->finalZoneSizing(this->curZoneEqNum).DesCoolCoilInTemp;
139 205 : CoilInHumRat = this->finalZoneSizing(this->curZoneEqNum).DesCoolCoilInHumRat;
140 : } else {
141 42 : CoilInTemp = this->finalZoneSizing(this->curZoneEqNum)
142 42 : .ZoneRetTempAtCoolPeak; // Question whether zone equipment should use return temp for sizing
143 42 : 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 396 : CoilOutTemp = min(CoilInTemp, this->finalZoneSizing(this->curZoneEqNum).CoolDesTemp);
161 396 : CoilOutHumRat = min(CoilInHumRat, this->finalZoneSizing(this->curZoneEqNum).CoolDesHumRat);
162 396 : int TimeStepNumAtMax = this->finalZoneSizing(this->curZoneEqNum).TimeStepNumAtCoolMax;
163 396 : int DDNum = this->finalZoneSizing(this->curZoneEqNum).CoolDDNum;
164 396 : Real64 OutTemp = 0.0;
165 396 : if (DDNum > 0 && TimeStepNumAtMax > 0) {
166 396 : OutTemp = state.dataSize->DesDayWeath(DDNum).Temp(TimeStepNumAtMax);
167 : }
168 396 : if (this->dataCoolCoilType == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
169 3 : OutTemp = VariableSpeedCoils::GetVSCoilRatedSourceTemp(state, this->dataCoolCoilIndex);
170 : }
171 396 : Real64 CoilInEnth = Psychrometrics::PsyHFnTdbW(CoilInTemp, CoilInHumRat);
172 396 : Real64 CoilOutEnth = Psychrometrics::PsyHFnTdbW(CoilOutTemp, CoilOutHumRat);
173 396 : Real64 PeakCoilLoad = max(0.0, (state.dataEnvrn->StdRhoAir * DesVolFlow * (CoilInEnth - CoilOutEnth)));
174 : // add fan heat to coil load
175 396 : FanCoolLoad += this->calcFanDesHeatGain(DesVolFlow);
176 396 : PeakCoilLoad += FanCoolLoad;
177 396 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(CoilInHumRat);
178 : // adjust coil inlet/outlet temp with fan temperature rise
179 396 : if (this->dataDesAccountForFanHeat) {
180 396 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
181 173 : CoilInTemp += FanCoolLoad / (CpAir * state.dataEnvrn->StdRhoAir * DesVolFlow);
182 223 : } else if (state.dataSize->DataFanPlacement == HVAC::FanPlace::DrawThru) {
183 215 : CoilOutTemp -= FanCoolLoad / (CpAir * state.dataEnvrn->StdRhoAir * DesVolFlow);
184 : }
185 : }
186 : Real64 CoilInWetBulb =
187 396 : Psychrometrics::PsyTwbFnTdbWPb(state, CoilInTemp, CoilInHumRat, state.dataEnvrn->StdBaroPress, this->callingRoutine);
188 396 : if (this->dataTotCapCurveIndex > 0) {
189 251 : switch (state.dataCurveManager->PerfCurve(this->dataTotCapCurveIndex)->numDims) {
190 29 : case 1:
191 29 : TotCapTempModFac = Curve::CurveValue(state, this->dataTotCapCurveIndex, CoilInWetBulb);
192 29 : break;
193 222 : case 2:
194 : default: // this default allows the simulation to continue, but will issue a warning, should be removed eventually
195 222 : TotCapTempModFac = Curve::CurveValue(state, this->dataTotCapCurveIndex, CoilInWetBulb, OutTemp);
196 222 : break;
197 : }
198 145 : } else if (this->dataTotCapCurveValue > 0) {
199 16 : TotCapTempModFac = this->dataTotCapCurveValue;
200 : } else {
201 129 : TotCapTempModFac = 1.0;
202 : }
203 396 : if (TotCapTempModFac > 0.0) {
204 396 : 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 396 : state.dataSize->DataCoilSizingAirInTemp = CoilInTemp;
210 396 : state.dataSize->DataCoilSizingAirInHumRat = CoilInHumRat;
211 396 : state.dataSize->DataCoilSizingAirOutTemp = CoilOutTemp;
212 396 : state.dataSize->DataCoilSizingAirOutHumRat = CoilOutHumRat;
213 396 : state.dataSize->DataCoilSizingFanCoolLoad = FanCoolLoad;
214 396 : state.dataSize->DataCoilSizingCapFT = TotCapTempModFac;
215 : } else {
216 0 : this->autoSizedValue = 0.0;
217 0 : CoilOutTemp = -999.0;
218 : }
219 : }
220 : }
221 813 : this->autoSizedValue = this->autoSizedValue * this->dataFracOfAutosizedCoolingCapacity;
222 813 : this->dataDesAccountForFanHeat = true; // reset for next water coil
223 813 : 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 2322 : } else if (this->curSysNum > 0) {
255 2298 : if (!this->wasAutoSized && !this->sizingDesRunThisAirSys) {
256 190 : this->autoSizedValue = _originalValue;
257 : } else {
258 2108 : Real64 OutAirFrac = 0.0;
259 2108 : this->dataFracOfAutosizedCoolingCapacity = 1.0;
260 2108 : if (this->oaSysFlag) {
261 0 : this->autoSizedValue = this->oaSysEqSizing(this->curOASysNum).DesCoolingLoad;
262 0 : DesVolFlow = this->dataFlowUsedForSizing;
263 2108 : } 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 1740 : } 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 1738 : CheckSysSizing(state, this->compType, this->compName);
321 1738 : auto const &thisFinalSysSizing = this->finalSysSizing(this->curSysNum);
322 1738 : DesVolFlow = this->dataFlowUsedForSizing;
323 1738 : Real64 NominalCapacityDes = 0.0;
324 1738 : if (thisFinalSysSizing.CoolingCapMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
325 2 : this->dataFracOfAutosizedCoolingCapacity = thisFinalSysSizing.FractionOfAutosizedCoolingCapacity;
326 : }
327 1738 : if (thisFinalSysSizing.CoolingCapMethod == DataSizing::CapacityPerFloorArea) {
328 0 : NominalCapacityDes = thisFinalSysSizing.CoolingTotalCapacity;
329 0 : this->autoSizedValue = NominalCapacityDes;
330 1738 : } else if (thisFinalSysSizing.CoolingCapMethod == DataSizing::CoolingDesignCapacity &&
331 1736 : thisFinalSysSizing.CoolingTotalCapacity > 0.0) {
332 0 : NominalCapacityDes = thisFinalSysSizing.CoolingTotalCapacity;
333 0 : this->autoSizedValue = NominalCapacityDes;
334 1738 : } else if (DesVolFlow >= HVAC::SmallAirVolFlow) {
335 1738 : if (DesVolFlow > 0.0) {
336 1738 : OutAirFrac = thisFinalSysSizing.DesOutAirVolFlow / DesVolFlow;
337 : } else {
338 0 : OutAirFrac = 1.0;
339 : }
340 1738 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
341 1738 : 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 1676 : if (this->dataAirFlowUsedForSizing > 0.0) {
348 682 : DesVolFlow = this->dataAirFlowUsedForSizing;
349 : }
350 1676 : if (this->dataDesOutletAirTemp > 0.0) {
351 682 : CoilOutTemp = this->dataDesOutletAirTemp;
352 : } else {
353 994 : CoilOutTemp = thisFinalSysSizing.CoolSupTemp;
354 : }
355 1676 : if (this->dataDesOutletAirHumRat > 0.0) {
356 682 : CoilOutHumRat = this->dataDesOutletAirHumRat;
357 : } else {
358 994 : CoilOutHumRat = thisFinalSysSizing.CoolSupHumRat;
359 : }
360 :
361 1676 : if (this->primaryAirSystem(this->curSysNum).NumOACoolCoils == 0) { // there is no precooling of the OA stream
362 1619 : CoilInTemp = thisFinalSysSizing.MixTempAtCoolPeak;
363 1619 : 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 1676 : if (this->dataDesInletAirTemp > 0.0) CoilInTemp = this->dataDesInletAirTemp;
376 1676 : if (this->dataDesInletAirHumRat > 0.0) CoilInHumRat = this->dataDesInletAirHumRat;
377 : }
378 1738 : Real64 OutTemp = thisFinalSysSizing.OutTempAtCoolPeak;
379 1738 : if (this->dataCoolCoilType == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
380 0 : OutTemp = VariableSpeedCoils::GetVSCoilRatedSourceTemp(state, this->dataCoolCoilIndex);
381 : }
382 1738 : CoilOutTemp = min(CoilInTemp, CoilOutTemp);
383 1738 : CoilOutHumRat = min(CoilInHumRat, CoilOutHumRat);
384 1738 : Real64 CoilInEnth = Psychrometrics::PsyHFnTdbW(CoilInTemp, CoilInHumRat);
385 : Real64 CoilInWetBulb =
386 1738 : Psychrometrics::PsyTwbFnTdbWPb(state, CoilInTemp, CoilInHumRat, state.dataEnvrn->StdBaroPress, this->callingRoutine);
387 1738 : Real64 CoilOutEnth = Psychrometrics::PsyHFnTdbW(CoilOutTemp, CoilOutHumRat);
388 1738 : if (this->curOASysNum > 0) { // coil is in the OA stream
389 : // need to find fan type in OA system
390 : } else {
391 1676 : if (this->primaryAirSystem(this->curSysNum).supFanType != HVAC::FanType::Invalid)
392 1670 : FanCoolLoad = this->calcFanDesHeatGain(DesVolFlow);
393 1676 : if (this->primaryAirSystem(this->curSysNum).retFanType != HVAC::FanType::Invalid)
394 8 : FanCoolLoad += (1.0 - OutAirFrac) * this->calcFanDesHeatGain(DesVolFlow);
395 1676 : this->primaryAirSystem(this->curSysNum).FanDesCoolLoad = FanCoolLoad;
396 : }
397 1738 : Real64 PeakCoilLoad = max(0.0, (state.dataEnvrn->StdRhoAir * DesVolFlow * (CoilInEnth - CoilOutEnth)));
398 1738 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(CoilInHumRat);
399 : // adjust coil inlet/outlet temp with fan temperature rise
400 1738 : if (this->dataDesAccountForFanHeat) {
401 1367 : PeakCoilLoad = max(0.0, (state.dataEnvrn->StdRhoAir * DesVolFlow * (CoilInEnth - CoilOutEnth) + FanCoolLoad));
402 1367 : if (this->primaryAirSystem(this->curSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
403 325 : CoilInTemp += FanCoolLoad / (CpAir * state.dataEnvrn->StdRhoAir * DesVolFlow);
404 : // include change in inlet condition in TotCapTempModFac
405 650 : CoilInWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
406 325 : state, CoilInTemp, CoilInHumRat, state.dataEnvrn->StdBaroPress, this->callingRoutine);
407 1042 : } else if (this->primaryAirSystem(this->curSysNum).supFanPlace == HVAC::FanPlace::DrawThru) {
408 1042 : CoilOutTemp -= FanCoolLoad / (CpAir * state.dataEnvrn->StdRhoAir * DesVolFlow);
409 : }
410 : }
411 1738 : if (this->dataTotCapCurveIndex > 0) {
412 752 : switch (state.dataCurveManager->PerfCurve(this->dataTotCapCurveIndex)->numDims) {
413 2 : case 1:
414 2 : TotCapTempModFac = Curve::CurveValue(state, this->dataTotCapCurveIndex, CoilInWetBulb);
415 2 : break;
416 750 : case 2:
417 : default: // this default allows the simulation to continue, but will issue a warning, should be removed eventually
418 750 : TotCapTempModFac = Curve::CurveValue(state, this->dataTotCapCurveIndex, CoilInWetBulb, OutTemp);
419 750 : break;
420 : }
421 : } else {
422 986 : TotCapTempModFac = 1.0;
423 : }
424 1738 : if (TotCapTempModFac > 0.0) {
425 1738 : NominalCapacityDes = PeakCoilLoad / TotCapTempModFac;
426 : } else {
427 0 : NominalCapacityDes = PeakCoilLoad;
428 : }
429 1738 : state.dataSize->DataCoilSizingAirInTemp = CoilInTemp;
430 1738 : state.dataSize->DataCoilSizingAirInHumRat = CoilInHumRat;
431 1738 : state.dataSize->DataCoilSizingAirOutTemp = CoilOutTemp;
432 1738 : state.dataSize->DataCoilSizingAirOutHumRat = CoilOutHumRat;
433 1738 : state.dataSize->DataCoilSizingFanCoolLoad = FanCoolLoad;
434 1738 : state.dataSize->DataCoilSizingCapFT = TotCapTempModFac;
435 : } else {
436 0 : NominalCapacityDes = 0.0;
437 : }
438 1738 : this->autoSizedValue =
439 1738 : NominalCapacityDes * this->dataFracOfAutosizedCoolingCapacity; // Fixed Moved up 1 line inside block per Richard Raustad
440 : } // IF(OASysFlag) THEN or ELSE IF(AirLoopSysFlag) THEN
441 2108 : this->dataDesAccountForFanHeat = true; // reset for next water coil
442 2108 : if (state.dataGlobal->DisplayExtraWarnings && this->autoSizedValue <= 0.0) {
443 0 : ShowWarningMessage(state,
444 0 : this->callingRoutine + ": Potential issue with equipment sizing for " + this->compType + ' ' + this->compName);
445 0 : ShowContinueError(state, format("...Rated Total Cooling Capacity = {:.2T} [W]", this->autoSizedValue));
446 0 : if (this->oaSysFlag || this->airLoopSysFlag ||
447 0 : this->finalSysSizing(this->curSysNum).CoolingCapMethod == DataSizing::CapacityPerFloorArea ||
448 0 : (this->finalSysSizing(this->curSysNum).CoolingCapMethod == DataSizing::CoolingDesignCapacity &&
449 0 : this->finalSysSizing(this->curSysNum).CoolingTotalCapacity)) {
450 0 : ShowContinueError(state,
451 0 : format("...Capacity passed by parent object to size child component = {:.2T} [W]", this->autoSizedValue));
452 : } else {
453 0 : ShowContinueError(state, format("...Air flow rate used for sizing = {:.5T} [m3/s]", DesVolFlow));
454 0 : ShowContinueError(state, format("...Outdoor air fraction used for sizing = {:.2T}", OutAirFrac));
455 0 : ShowContinueError(state, format("...Coil inlet air temperature used for sizing = {:.2T} [C]", CoilInTemp));
456 0 : ShowContinueError(state, format("...Coil outlet air temperature used for sizing = {:.2T} [C]", CoilOutTemp));
457 : }
458 : }
459 : }
460 24 : } else if (this->dataNonZoneNonAirloopValue > 0) {
461 24 : this->autoSizedValue = this->dataNonZoneNonAirloopValue;
462 0 : } else if (!this->wasAutoSized) {
463 0 : this->autoSizedValue = this->originalValue;
464 : } else {
465 0 : std::string msg = this->callingRoutine + ' ' + this->compType + ' ' + this->compName + ", Developer Error: Component sizing incomplete.";
466 0 : ShowSevereError(state, msg);
467 0 : this->addErrorMessage(msg);
468 0 : msg = format("SizingString = {}, SizingResult = {:.1T}", this->sizingString, this->autoSizedValue);
469 0 : ShowContinueError(state, msg);
470 0 : this->addErrorMessage(msg);
471 0 : errorsFound = true;
472 0 : }
473 : }
474 3483 : if (this->dataDXCoolsLowSpeedsAutozize) {
475 67 : this->autoSizedValue *= this->dataFractionUsedForSizing;
476 : }
477 3483 : if (!this->hardSizeNoDesignRun || this->dataScalableSizingON || this->dataScalableCapSizingON) {
478 3291 : if (this->wasAutoSized) {
479 : // Note: the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil model, which implements variable flow fans and
480 : // determines capacity using physical calculations instead of emperical curves
481 2856 : bool FlagCheckVolFlowPerRatedTotCap = true;
482 5697 : if (Util::SameString(this->compType, "Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl") ||
483 5697 : Util::SameString(this->compType, "Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl"))
484 15 : FlagCheckVolFlowPerRatedTotCap = false;
485 :
486 2856 : if (this->dataIsDXCoil && FlagCheckVolFlowPerRatedTotCap) {
487 1124 : Real64 RatedVolFlowPerRatedTotCap = 0.0;
488 1124 : if (this->autoSizedValue > 0.0) {
489 1124 : RatedVolFlowPerRatedTotCap = DesVolFlow / this->autoSizedValue;
490 : }
491 1124 : if (RatedVolFlowPerRatedTotCap < HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) {
492 285 : if (!this->dataEMSOverride && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
493 1 : ShowWarningError(state, this->callingRoutine + ' ' + this->compType + ' ' + this->compName);
494 2 : ShowContinueError(
495 2 : state, "..." + this->sizingString + " will be limited by the minimum rated volume flow per rated total capacity ratio.");
496 1 : ShowContinueError(state, format("...DX coil volume flow rate (m3/s ) = {:.6T}", DesVolFlow));
497 1 : ShowContinueError(state, format("...Requested capacity (W ) = {:.3T}", this->autoSizedValue));
498 1 : ShowContinueError(state, format("...Requested flow/capacity ratio (m3/s/W ) = {:.3T}", RatedVolFlowPerRatedTotCap));
499 2 : ShowContinueError(state,
500 2 : format("...Minimum flow/capacity ratio (m3/s/W ) = {:.3T}",
501 1 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
502 : }
503 :
504 285 : DXFlowPerCapMinRatio = (DesVolFlow / HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) /
505 285 : this->autoSizedValue; // set DX Coil Capacity Increase Ratio from Too Low Flow/Capacity Ratio
506 285 : this->autoSizedValue = DesVolFlow / HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT];
507 :
508 285 : if (!this->dataEMSOverride && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
509 1 : ShowContinueError(state, format("...Adjusted capacity ( W ) = {:.3T}", this->autoSizedValue));
510 : }
511 839 : } else if (RatedVolFlowPerRatedTotCap > HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) {
512 117 : if (!this->dataEMSOverride && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
513 0 : ShowWarningError(state, this->callingRoutine + ' ' + this->compType + ' ' + this->compName);
514 0 : ShowContinueError(
515 0 : state, "..." + this->sizingString + " will be limited by the maximum rated volume flow per rated total capacity ratio.");
516 0 : ShowContinueError(state, format("...DX coil volume flow rate ( m3/s ) = {:.6T}", DesVolFlow));
517 0 : ShowContinueError(state, format("...Requested capacity ( W ) = {:.3T}", this->autoSizedValue));
518 0 : ShowContinueError(state, format("...Requested flow/capacity ratio ( m3/s/W ) = {:.3T}", RatedVolFlowPerRatedTotCap));
519 0 : ShowContinueError(state,
520 0 : format("...Maximum flow/capacity ratio ( m3/s/W ) = {:.3T}",
521 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
522 : }
523 :
524 117 : DXFlowPerCapMaxRatio = DesVolFlow / HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] /
525 117 : this->autoSizedValue; // set DX Coil Capacity Decrease Ratio from Too High Flow/Capacity Ratio
526 117 : this->autoSizedValue = DesVolFlow / HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT];
527 :
528 117 : if (!this->dataEMSOverride && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
529 0 : ShowContinueError(state, format("...Adjusted capacity ( W ) = {:.3T}", this->autoSizedValue));
530 : }
531 : }
532 : }
533 : }
534 : }
535 :
536 : // override sizing string
537 3483 : if (this->overrideSizeString) {
538 10 : if (this->isEpJSON) this->sizingString = "cooling_design_capacity [W]";
539 : }
540 3483 : if (this->dataScalableCapSizingON) {
541 6 : int const SELECT_CASE_var(this->zoneEqSizing(this->curZoneEqNum).SizingMethod(HVAC::CoolingCapacitySizing));
542 6 : if (SELECT_CASE_var == DataSizing::CapacityPerFloorArea) {
543 3 : this->sizingStringScalable = "(scaled by capacity / area) ";
544 3 : } else if (SELECT_CASE_var == DataSizing::FractionOfAutosizedHeatingCapacity ||
545 : SELECT_CASE_var == DataSizing::FractionOfAutosizedCoolingCapacity) {
546 3 : this->sizingStringScalable = "(scaled by fractional multiplier) ";
547 : }
548 : }
549 :
550 3483 : this->selectSizerOutput(state, errorsFound);
551 :
552 3483 : if (this->isCoilReportObject && this->curSysNum <= state.dataHVACGlobal->NumPrimaryAirSys) {
553 2097 : if (CoilInTemp > -999.0) { // set inlet air properties used during capacity sizing if available, allow for negative winter temps
554 1680 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
555 1680 : state, this->compName, this->compType, CoilInTemp, this->curSysNum, this->curZoneEqNum);
556 1680 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, this->compName, this->compType, CoilInHumRat);
557 : }
558 2097 : if (CoilOutTemp > -999.0) { // set outlet air properties used during capacity sizing if available
559 1680 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, this->compName, this->compType, CoilOutTemp);
560 1680 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, this->compName, this->compType, CoilOutHumRat);
561 : }
562 2097 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilCoolingCapacity(state,
563 2097 : this->compName,
564 2097 : this->compType,
565 : this->autoSizedValue,
566 2097 : this->wasAutoSized,
567 : this->curSysNum,
568 : this->curZoneEqNum,
569 : this->curOASysNum,
570 : FanCoolLoad,
571 : TotCapTempModFac,
572 : DXFlowPerCapMinRatio,
573 : DXFlowPerCapMaxRatio);
574 : }
575 3483 : return this->autoSizedValue;
576 : }
577 :
578 0 : void CoolingCapacitySizer::clearState()
579 : {
580 0 : BaseSizerWithScalableInputs::clearState();
581 0 : }
582 :
583 : } // namespace EnergyPlus
|