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