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/HeatingCapacitySizing.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/WeatherManager.hh>
59 :
60 : namespace EnergyPlus {
61 :
62 3836 : Real64 HeatingCapacitySizer::size(EnergyPlusData &state, Real64 _originalValue, bool &errorsFound)
63 : {
64 3836 : if (!this->checkInitialized(state, errorsFound)) {
65 0 : return 0.0;
66 : }
67 3836 : this->preSize(state, _originalValue);
68 3836 : Real64 DesVolFlow = 0.0;
69 3836 : Real64 CoilInTemp = -999.0;
70 3836 : Real64 CoilInHumRat = -999.0;
71 3836 : Real64 CoilOutTemp = -999.0;
72 3836 : Real64 CoilOutHumRat = -999.0;
73 :
74 3836 : Real64 DXFlowPerCapMinRatio = 1.0;
75 3836 : Real64 DXFlowPerCapMaxRatio = 1.0;
76 3836 : Real64 NominalCapacityDes = 0.0;
77 3836 : Real64 DesMassFlow = 0.0;
78 3836 : Real64 DesCoilLoad = 0.0;
79 3836 : Real64 OutAirFrac = 0.0;
80 3836 : Real64 const CpAirStd = Psychrometrics::PsyCpAirFnW(0.0);
81 :
82 3836 : if (this->dataEMSOverrideON) {
83 0 : this->autoSizedValue = this->dataEMSOverride;
84 3836 : } 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 268 : this->autoSizedValue = this->dataConstantUsedForSizing * this->dataFractionUsedForSizing;
87 : } else {
88 3568 : if (this->curZoneEqNum > 0) {
89 1986 : if (!this->wasAutoSized && !this->sizingDesRunThisZone) {
90 86 : this->autoSizedValue = _originalValue;
91 1900 : } else if (this->zoneEqSizing(this->curZoneEqNum).DesignSizeFromParent) {
92 1 : this->autoSizedValue = this->zoneEqSizing(this->curZoneEqNum).DesHeatingLoad;
93 : } else {
94 1899 : if (this->dataCoilIsSuppHeater && this->suppHeatCap > 0.0) {
95 356 : NominalCapacityDes = this->suppHeatCap;
96 356 : if (this->dataFlowUsedForSizing > 0.0) {
97 0 : DesVolFlow = this->dataFlowUsedForSizing;
98 : }
99 1543 : } else if (this->zoneEqSizing(this->curZoneEqNum).HeatingCapacity) {
100 143 : NominalCapacityDes = this->zoneEqSizing(this->curZoneEqNum).DesHeatingLoad;
101 143 : if (this->dataFlowUsedForSizing > 0.0) {
102 4 : DesVolFlow = this->dataFlowUsedForSizing;
103 : }
104 1400 : } else if (this->dataCoolCoilCap > 0.0 && this->dataFlowUsedForSizing > 0.0) {
105 85 : NominalCapacityDes = this->dataCoolCoilCap;
106 85 : DesVolFlow = this->dataFlowUsedForSizing;
107 2630 : } else if (int(this->finalZoneSizing.size()) > 0 &&
108 1315 : this->finalZoneSizing(this->curZoneEqNum).DesHeatMassFlow >= HVAC::SmallMassFlow) {
109 1305 : if (this->dataFlowUsedForSizing > 0.0) {
110 18 : DesVolFlow = this->dataFlowUsedForSizing;
111 : }
112 1305 : if (this->termUnitPIU && (this->curTermUnitSizingNum > 0)) {
113 1 : Real64 const MinPriFlowFrac = this->termUnitSizing(this->curTermUnitSizingNum).MinPriFlowFrac;
114 1 : if (this->termUnitSizing(this->curTermUnitSizingNum).InducesPlenumAir) {
115 1 : CoilInTemp = (this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatCoilInTempTU * MinPriFlowFrac) +
116 1 : (this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).ZoneRetTempAtHeatPeak * (1.0 - MinPriFlowFrac));
117 : } else {
118 0 : CoilInTemp = (this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatCoilInTempTU * MinPriFlowFrac) +
119 0 : (this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).ZoneTempAtHeatPeak * (1.0 - MinPriFlowFrac));
120 : }
121 1305 : } else if (this->termUnitIU && (this->curTermUnitSizingNum > 0)) {
122 0 : CoilInTemp = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).ZoneTempAtHeatPeak;
123 0 : CoilInHumRat = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).ZoneHumRatAtHeatPeak;
124 1304 : } else if (this->termUnitSingDuct && (this->curTermUnitSizingNum > 0)) {
125 317 : CoilInTemp = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatCoilInTempTU;
126 317 : CoilInHumRat = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatCoilInHumRatTU;
127 : } else {
128 : // all other components calculate coil inlet condition based on actual, not design, OA fraction (e.g., FanCoil)
129 987 : if (DesVolFlow > 0.0) {
130 18 : DesMassFlow = DesVolFlow * state.dataEnvrn->StdRhoAir;
131 : } else {
132 969 : DesMassFlow = this->finalZoneSizing(this->curZoneEqNum).DesHeatMassFlow;
133 : }
134 987 : CoilInTemp = this->setHeatCoilInletTempForZoneEqSizing(
135 987 : this->setOAFracForZoneEqSizing(state, DesMassFlow, zoneEqSizing(this->curZoneEqNum)),
136 987 : zoneEqSizing(this->curZoneEqNum),
137 987 : finalZoneSizing(this->curZoneEqNum));
138 987 : CoilInHumRat = this->setHeatCoilInletHumRatForZoneEqSizing(
139 987 : this->setOAFracForZoneEqSizing(state, DesMassFlow, zoneEqSizing(this->curZoneEqNum)),
140 987 : zoneEqSizing(this->curZoneEqNum),
141 987 : finalZoneSizing(this->curZoneEqNum));
142 : }
143 1305 : if ((this->termUnitSingDuct || this->termUnitPIU) && (this->curTermUnitSizingNum > 0)) {
144 318 : CoilOutTemp = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).HeatDesTemp;
145 318 : CoilOutHumRat = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).HeatDesHumRat;
146 318 : Real64 const CpAir = Psychrometrics::PsyCpAirFnW(CoilOutHumRat);
147 318 : DesCoilLoad = CpAir * state.dataEnvrn->StdRhoAir * this->termUnitSizing(this->curTermUnitSizingNum).AirVolFlow *
148 318 : (CoilOutTemp - CoilInTemp);
149 318 : DesVolFlow = this->termUnitSizing(this->curTermUnitSizingNum).AirVolFlow;
150 1305 : } else if (this->termUnitIU && (this->curTermUnitSizingNum > 0)) {
151 0 : if (this->termUnitSizing(this->curTermUnitSizingNum).InducRat > 0.01) {
152 0 : DesVolFlow = this->termUnitSizing(this->curTermUnitSizingNum).AirVolFlow /
153 0 : this->termUnitSizing(this->curTermUnitSizingNum).InducRat;
154 0 : Real64 const CpAir = Psychrometrics::PsyCpAirFnW(this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).HeatDesHumRat);
155 : // the design heating coil load is the zone load minus whatever the central system does.Note that
156 : // DesHeatCoilInTempTU is really the primary air inlet temperature for the unit.
157 0 : DesCoilLoad = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatLoad -
158 0 : (CpAir * state.dataEnvrn->StdRhoAir * DesVolFlow *
159 0 : (this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatCoilInTempTU -
160 0 : this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).ZoneTempAtHeatPeak));
161 : } else {
162 0 : DesCoilLoad = 0.0;
163 : }
164 0 : } else {
165 987 : CoilOutTemp = this->finalZoneSizing(this->curZoneEqNum).HeatDesTemp;
166 987 : CoilOutHumRat = this->finalZoneSizing(this->curZoneEqNum).HeatDesHumRat;
167 987 : Real64 const CpAir = Psychrometrics::PsyCpAirFnW(CoilOutHumRat);
168 987 : DesCoilLoad = CpAir * this->finalZoneSizing(this->curZoneEqNum).DesHeatMassFlow * (CoilOutTemp - CoilInTemp);
169 987 : DesVolFlow = this->finalZoneSizing(this->curZoneEqNum).DesHeatMassFlow / state.dataEnvrn->StdRhoAir;
170 : }
171 1305 : NominalCapacityDes = max(0.0, DesCoilLoad);
172 : } else {
173 10 : NominalCapacityDes = 0.0;
174 10 : CoilOutTemp = -999.0;
175 : }
176 1899 : if (this->dataCoolCoilCap > 0.0) {
177 86 : this->autoSizedValue = NominalCapacityDes * this->dataHeatSizeRatio;
178 : } else {
179 1813 : this->autoSizedValue = NominalCapacityDes * this->dataHeatSizeRatio * this->dataFracOfAutosizedHeatingCapacity;
180 : }
181 1899 : if (state.dataGlobal->DisplayExtraWarnings && this->autoSizedValue <= 0.0) {
182 0 : ShowWarningMessage(state,
183 0 : this->callingRoutine + ": Potential issue with equipment sizing for " + this->compType + ' ' + this->compName);
184 0 : ShowContinueError(state, format("...Rated Total Heating Capacity = {:.2T} [W]", this->autoSizedValue));
185 0 : if (this->zoneEqSizing(this->curZoneEqNum).HeatingCapacity ||
186 0 : (this->dataCoolCoilCap > 0.0 && this->dataFlowUsedForSizing > 0.0)) {
187 0 : ShowContinueError(state,
188 0 : format("...Capacity passed by parent object to size child component = {:.2T} [W]", NominalCapacityDes));
189 : } else {
190 0 : if (CoilOutTemp > -999.0) {
191 0 : ShowContinueError(state, format("...Air flow rate used for sizing = {:.5T} [m3/s]", DesVolFlow));
192 0 : ShowContinueError(state, format("...Coil inlet air temperature used for sizing = {:.2T} [C]", CoilInTemp));
193 0 : ShowContinueError(state, format("...Coil outlet air temperature used for sizing = {:.2T} [C]", CoilOutTemp));
194 : } else {
195 0 : ShowContinueError(state, "...Capacity used to size child component set to 0 [W]");
196 : }
197 : }
198 : }
199 : }
200 1582 : } else if (this->curSysNum > 0) {
201 1582 : if (!this->wasAutoSized && !this->sizingDesRunThisAirSys) {
202 255 : this->autoSizedValue = _originalValue;
203 : } else {
204 1327 : if (this->curOASysNum > 0) {
205 32 : if (this->oaSysEqSizing(this->curOASysNum).AirFlow) {
206 0 : DesVolFlow = this->oaSysEqSizing(this->curOASysNum).AirVolFlow;
207 32 : } else if (this->oaSysEqSizing(this->curOASysNum).HeatingAirFlow) {
208 1 : DesVolFlow = this->oaSysEqSizing(this->curOASysNum).HeatingAirVolFlow;
209 31 : } else if (this->outsideAirSys(this->curOASysNum).AirLoopDOASNum > -1) {
210 1 : DesVolFlow =
211 1 : this->airloopDOAS[this->outsideAirSys(this->curOASysNum).AirLoopDOASNum].SizingMassFlow / state.dataEnvrn->StdRhoAir;
212 : } else {
213 30 : DesVolFlow = this->finalSysSizing(this->curSysNum).DesOutAirVolFlow;
214 : }
215 : } else {
216 1295 : if (this->finalSysSizing(this->curSysNum).HeatingCapMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
217 1 : this->dataFracOfAutosizedHeatingCapacity = this->finalSysSizing(this->curSysNum).FractionOfAutosizedHeatingCapacity;
218 : }
219 1295 : if (this->dataFlowUsedForSizing > 0.0) {
220 526 : DesVolFlow = this->dataFlowUsedForSizing;
221 769 : } else if (this->unitarySysEqSizing(this->curSysNum).AirFlow) {
222 108 : DesVolFlow = this->unitarySysEqSizing(this->curSysNum).AirVolFlow;
223 661 : } else if (this->unitarySysEqSizing(this->curSysNum).HeatingAirFlow) {
224 144 : DesVolFlow = this->unitarySysEqSizing(this->curSysNum).HeatingAirVolFlow;
225 : } else {
226 517 : if (this->curDuctType == HVAC::AirDuctType::Main) {
227 517 : if (this->finalSysSizing(this->curSysNum).SysAirMinFlowRat > 0.0 && !this->dataDesicRegCoil) {
228 513 : DesVolFlow =
229 513 : this->finalSysSizing(this->curSysNum).SysAirMinFlowRat * this->finalSysSizing(this->curSysNum).DesMainVolFlow;
230 : } else {
231 4 : DesVolFlow = this->finalSysSizing(this->curSysNum).DesMainVolFlow;
232 : }
233 0 : } else if (this->curDuctType == HVAC::AirDuctType::Cooling) {
234 0 : if (this->finalSysSizing(this->curSysNum).SysAirMinFlowRat > 0.0 && !this->dataDesicRegCoil) {
235 0 : DesVolFlow =
236 0 : this->finalSysSizing(this->curSysNum).SysAirMinFlowRat * this->finalSysSizing(this->curSysNum).DesCoolVolFlow;
237 : } else {
238 0 : DesVolFlow = this->finalSysSizing(this->curSysNum).DesCoolVolFlow;
239 : }
240 0 : } else if (this->curDuctType == HVAC::AirDuctType::Heating) {
241 0 : DesVolFlow = this->finalSysSizing(this->curSysNum).DesHeatVolFlow;
242 : } else {
243 0 : DesVolFlow = this->finalSysSizing(this->curSysNum).DesMainVolFlow;
244 : }
245 : }
246 : }
247 1327 : DesMassFlow = state.dataEnvrn->StdRhoAir * DesVolFlow;
248 : // get the outside air fraction
249 1327 : if (this->curOASysNum > 0) {
250 32 : OutAirFrac = 1.0;
251 1295 : } else if (this->finalSysSizing(this->curSysNum).HeatOAOption == DataSizing::OAControl::MinOA) {
252 1244 : if (DesVolFlow > 0.0) {
253 1244 : OutAirFrac = this->finalSysSizing(this->curSysNum).DesOutAirVolFlow / DesVolFlow;
254 : } else {
255 0 : OutAirFrac = 1.0;
256 : }
257 1244 : OutAirFrac = std::min(1.0, std::max(0.0, OutAirFrac));
258 : } else {
259 51 : OutAirFrac = 1.0;
260 : }
261 : // coil inlet temperature
262 1327 : if (this->curOASysNum == 0 && this->primaryAirSystem(this->curSysNum).NumOAHeatCoils > 0) {
263 29 : CoilInTemp = OutAirFrac * this->finalSysSizing(this->curSysNum).PreheatTemp +
264 29 : (1.0 - OutAirFrac) * this->finalSysSizing(this->curSysNum).HeatRetTemp;
265 29 : CoilInHumRat = OutAirFrac * this->finalSysSizing(this->curSysNum).PreheatHumRat +
266 29 : (1.0 - OutAirFrac) * this->finalSysSizing(this->curSysNum).HeatRetHumRat; // include humrat for coil sizing reports
267 1298 : } else if (this->curOASysNum > 0 && this->outsideAirSys(this->curOASysNum).AirLoopDOASNum > -1) {
268 1 : CoilInTemp = this->airloopDOAS[this->outsideAirSys(this->curOASysNum).AirLoopDOASNum].HeatOutTemp;
269 : } else {
270 1297 : CoilInTemp = OutAirFrac * this->finalSysSizing(this->curSysNum).HeatOutTemp +
271 1297 : (1.0 - OutAirFrac) * this->finalSysSizing(this->curSysNum).HeatRetTemp;
272 1297 : CoilInHumRat = OutAirFrac * this->finalSysSizing(this->curSysNum).HeatOutHumRat +
273 1297 : (1.0 - OutAirFrac) * this->finalSysSizing(this->curSysNum).HeatRetHumRat; // include humrat for coil sizing reports
274 : }
275 : // coil load
276 1327 : if (this->curOASysNum > 0) {
277 32 : if (this->oaSysEqSizing(this->curOASysNum).HeatingCapacity) {
278 0 : DesCoilLoad = this->oaSysEqSizing(this->curOASysNum).DesHeatingLoad;
279 32 : } else if (this->dataDesicRegCoil) {
280 0 : DesCoilLoad = CpAirStd * DesMassFlow * (this->dataDesOutletAirTemp - this->dataDesInletAirTemp);
281 0 : CoilOutTemp = this->dataDesOutletAirTemp;
282 32 : } else if (this->outsideAirSys(this->curOASysNum).AirLoopDOASNum > -1) {
283 2 : DesCoilLoad = CpAirStd * DesMassFlow *
284 1 : (this->airloopDOAS[this->outsideAirSys(this->curOASysNum).AirLoopDOASNum].PreheatTemp - CoilInTemp);
285 1 : CoilOutTemp = this->airloopDOAS[outsideAirSys(this->curOASysNum).AirLoopDOASNum].PreheatTemp;
286 : } else {
287 31 : DesCoilLoad = CpAirStd * DesMassFlow * (this->finalSysSizing(this->curSysNum).PreheatTemp - CoilInTemp);
288 31 : CoilOutTemp = this->finalSysSizing(this->curSysNum).PreheatTemp;
289 31 : CoilOutHumRat = this->finalSysSizing(this->curSysNum).PreheatHumRat;
290 : }
291 : } else {
292 1295 : if (this->unitarySysEqSizing(this->curSysNum).HeatingCapacity) {
293 282 : DesCoilLoad = this->unitarySysEqSizing(this->curSysNum).DesHeatingLoad;
294 282 : CoilOutTemp = this->finalSysSizing(this->curSysNum).HeatSupTemp;
295 282 : CoilOutHumRat = this->finalSysSizing(this->curSysNum).HeatSupHumRat;
296 1013 : } else if (this->dataDesicRegCoil) {
297 0 : DesCoilLoad = CpAirStd * DesMassFlow * (this->dataDesOutletAirTemp - this->dataDesInletAirTemp);
298 0 : CoilOutTemp = this->dataDesOutletAirTemp;
299 : } else {
300 1013 : DesCoilLoad = CpAirStd * DesMassFlow * (this->finalSysSizing(this->curSysNum).HeatSupTemp - CoilInTemp);
301 1013 : CoilOutTemp = this->finalSysSizing(this->curSysNum).HeatSupTemp;
302 1013 : CoilOutHumRat = this->finalSysSizing(this->curSysNum).HeatSupHumRat;
303 : }
304 : }
305 1327 : if (this->curSysNum <= state.dataHVACGlobal->NumPrimaryAirSys && this->airLoopControlInfo(this->curSysNum).UnitarySys) {
306 670 : if (this->dataCoilIsSuppHeater) {
307 177 : NominalCapacityDes = this->suppHeatCap;
308 493 : } else if (this->dataCoolCoilCap > 0.0) {
309 28 : NominalCapacityDes = this->dataCoolCoilCap;
310 : } else {
311 : // TRUE for all air loop parent equipment except UnitarySystem where flag is reset to FALSE after simulating
312 : // This method allows downstream heating coils to size individually.Probably should do this for all air loop equipment
313 : // ChangoverBypass model always sets AirLoopControlInfo%UnitarySys to FALSE so heating coil can individually size
314 741 : if (this->airLoopControlInfo(this->curSysNum).UnitarySysSimulating &&
315 741 : !Util::SameString(this->compType, "COIL:HEATING:WATER")) {
316 270 : NominalCapacityDes = this->unitaryHeatCap;
317 : } else {
318 195 : if (DesCoilLoad >= HVAC::SmallLoad) {
319 195 : NominalCapacityDes = DesCoilLoad;
320 : } else {
321 0 : NominalCapacityDes = 0.0;
322 : }
323 : }
324 : }
325 670 : DesCoilLoad = NominalCapacityDes;
326 1313 : } else if (this->curSysNum <= state.dataHVACGlobal->NumPrimaryAirSys &&
327 656 : this->finalSysSizing(this->curSysNum).HeatingCapMethod == DataSizing::CapacityPerFloorArea) {
328 0 : NominalCapacityDes = this->finalSysSizing(this->curSysNum).HeatingTotalCapacity;
329 657 : } else if (this->curSysNum <= state.dataHVACGlobal->NumPrimaryAirSys &&
330 1312 : this->finalSysSizing(this->curSysNum).HeatingCapMethod == DataSizing::HeatingDesignCapacity &&
331 655 : this->finalSysSizing(this->curSysNum).HeatingTotalCapacity > 0.0) {
332 0 : NominalCapacityDes = this->finalSysSizing(this->curSysNum).HeatingTotalCapacity;
333 : } else {
334 657 : if (this->dataCoolCoilCap > 0.0) { // this line can't get executed with same logic above else
335 4 : NominalCapacityDes = this->dataCoolCoilCap;
336 653 : } else if (DesCoilLoad >= HVAC::SmallLoad) {
337 620 : NominalCapacityDes = DesCoilLoad;
338 : } else {
339 33 : NominalCapacityDes = 0.0;
340 : }
341 : }
342 1327 : this->autoSizedValue = NominalCapacityDes * this->dataHeatSizeRatio * this->dataFracOfAutosizedHeatingCapacity;
343 1327 : if (state.dataGlobal->DisplayExtraWarnings && this->autoSizedValue <= 0.0) {
344 0 : ShowWarningMessage(state,
345 0 : this->callingRoutine + ": Potential issue with equipment sizing for " + this->compType + ' ' + this->compName);
346 0 : ShowContinueError(state, format("...Rated Total Heating Capacity = {:.2T} [W]", this->autoSizedValue));
347 0 : if (CoilOutTemp > -999.0) {
348 0 : ShowContinueError(state, format("...Air flow rate used for sizing = {:.5T} [m3/s]", DesVolFlow));
349 0 : ShowContinueError(state, format("...Outdoor air fraction used for sizing = {:.2T}", OutAirFrac));
350 0 : ShowContinueError(state, format("...Coil inlet air temperature used for sizing = {:.2T} [C]", CoilInTemp));
351 0 : ShowContinueError(state, format("...Coil outlet air temperature used for sizing = {:.2T} [C]", CoilOutTemp));
352 : } else {
353 0 : ShowContinueError(state, format("...Capacity passed by parent object to size child component = {:.2T} [W]", DesCoilLoad));
354 : }
355 : }
356 : }
357 0 : } else if (this->dataNonZoneNonAirloopValue > 0) {
358 0 : this->autoSizedValue = this->dataNonZoneNonAirloopValue;
359 0 : } else if (!this->wasAutoSized) {
360 0 : this->autoSizedValue = this->originalValue;
361 : } else {
362 0 : std::string msg = this->callingRoutine + ' ' + this->compType + ' ' + this->compName + ", Developer Error: Component sizing incomplete.";
363 0 : ShowSevereError(state, msg);
364 0 : this->addErrorMessage(msg);
365 0 : msg = format("SizingString = {}, SizingResult = {:.1T}", this->sizingString, this->autoSizedValue);
366 0 : ShowContinueError(state, msg);
367 0 : this->addErrorMessage(msg);
368 0 : errorsFound = true;
369 0 : }
370 : }
371 3836 : if (!this->hardSizeNoDesignRun || this->dataScalableSizingON || this->dataScalableCapSizingON) {
372 3595 : if (this->wasAutoSized && this->dataFractionUsedForSizing == 0.0) {
373 : // Note: the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil model, which implements variable flow fans and
374 : // determines capacity using physical calculations instead of emperical curves
375 2894 : bool FlagCheckVolFlowPerRatedTotCap = true;
376 5788 : if (Util::SameString(this->compType, "Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl") ||
377 5788 : Util::SameString(this->compType, "Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl")) {
378 15 : FlagCheckVolFlowPerRatedTotCap = false;
379 : }
380 :
381 2894 : if (this->dataIsDXCoil && FlagCheckVolFlowPerRatedTotCap && this->autoSizedValue > 0.0) {
382 135 : Real64 RatedVolFlowPerRatedTotCap = DesVolFlow / this->autoSizedValue;
383 135 : if (RatedVolFlowPerRatedTotCap < HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) {
384 31 : if ((this->dataEMSOverride == 0.0) && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
385 1 : ShowWarningError(state, this->callingRoutine + ' ' + this->compType + ' ' + this->compName);
386 2 : ShowContinueError(
387 2 : state, "..." + this->sizingString + " will be limited by the minimum rated volume flow per rated total capacity ratio.");
388 1 : ShowContinueError(state, format("...DX coil volume flow rate (m3/s ) = {:.6T}", DesVolFlow));
389 1 : ShowContinueError(state, format("...Requested capacity (W ) = {:.3T}", this->autoSizedValue));
390 1 : ShowContinueError(state, format("...Requested flow/capacity ratio (m3/s/W ) = {:.3T}", RatedVolFlowPerRatedTotCap));
391 2 : ShowContinueError(state,
392 2 : format("...Minimum flow/capacity ratio (m3/s/W ) = {:.3T}",
393 1 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
394 : }
395 :
396 31 : DXFlowPerCapMinRatio = (DesVolFlow / HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) /
397 31 : this->autoSizedValue; // set DX Coil Capacity Increase Ratio from Too Low Flow/Capacity Ratio
398 31 : this->autoSizedValue = DesVolFlow / HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT];
399 :
400 31 : if ((this->dataEMSOverride == 0.0) && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
401 1 : ShowContinueError(state, format("...Adjusted capacity ( W ) = {:.3T}", this->autoSizedValue));
402 : }
403 104 : } else if (RatedVolFlowPerRatedTotCap > HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) {
404 7 : if ((this->dataEMSOverride == 0.0) && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
405 0 : ShowWarningError(state, this->callingRoutine + ' ' + this->compType + ' ' + this->compName);
406 0 : ShowContinueError(
407 0 : state, "..." + this->sizingString + " will be limited by the maximum rated volume flow per rated total capacity ratio.");
408 0 : ShowContinueError(state, format("...DX coil volume flow rate ( m3/s ) = {:.6T}", DesVolFlow));
409 0 : ShowContinueError(state, format("...Requested capacity ( W ) = {:.3T}", this->autoSizedValue));
410 0 : ShowContinueError(state, format("...Requested flow/capacity ratio ( m3/s/W ) = {:.3T}", RatedVolFlowPerRatedTotCap));
411 0 : ShowContinueError(state,
412 0 : format("...Maximum flow/capacity ratio ( m3/s/W ) = {:.3T}",
413 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
414 : }
415 :
416 7 : DXFlowPerCapMaxRatio = DesVolFlow / HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] /
417 7 : this->autoSizedValue; // set DX Coil Capacity Decrease Ratio from Too High Flow/Capacity Ratio
418 7 : this->autoSizedValue = DesVolFlow / HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT];
419 :
420 7 : if ((this->dataEMSOverride == 0.0) && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
421 0 : ShowContinueError(state, format("...Adjusted capacity ( W ) = {:.3T}", this->autoSizedValue));
422 : }
423 : }
424 : }
425 : }
426 : }
427 :
428 : // override sizing string
429 3836 : if (this->overrideSizeString) {
430 9 : if (this->isEpJSON) {
431 0 : this->sizingString = "nominal_capacity [W]";
432 : }
433 : }
434 3836 : if (this->dataScalableCapSizingON) {
435 10 : switch (this->zoneEqSizing(this->curZoneEqNum).SizingMethod(HVAC::HeatingCapacitySizing)) {
436 5 : case DataSizing::CapacityPerFloorArea: {
437 5 : this->sizingStringScalable = "(scaled by capacity / area) ";
438 5 : } break;
439 4 : case DataSizing::FractionOfAutosizedHeatingCapacity:
440 : case DataSizing::FractionOfAutosizedCoolingCapacity: {
441 4 : this->sizingStringScalable = "(scaled by fractional multiplier) ";
442 4 : } break;
443 1 : default:
444 1 : break;
445 : }
446 : }
447 :
448 3836 : this->selectSizerOutput(state, errorsFound);
449 :
450 3836 : if (this->isCoilReportObject) {
451 2241 : if (CoilInTemp > -999.0) { // set inlet air properties used during capacity sizing if available, allow for negative winter temps
452 1607 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
453 1607 : state, this->compName, this->compType, CoilInTemp, this->curSysNum, this->curZoneEqNum);
454 1607 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, this->compName, this->compType, CoilInHumRat);
455 : }
456 2241 : if (CoilOutTemp > -999.0) { // set outlet air properties used during capacity sizing if available
457 1607 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, this->compName, this->compType, CoilOutTemp);
458 1607 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, this->compName, this->compType, CoilOutHumRat);
459 : }
460 2241 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilAirFlow(state, this->compName, this->compType, DesVolFlow, this->wasAutoSized);
461 2241 : Real64 constexpr FanCoolLoad = 0.0;
462 2241 : Real64 constexpr TotCapTempModFac = 1.0;
463 2241 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilHeatingCapacity(state,
464 2241 : this->compName,
465 2241 : this->compType,
466 : this->autoSizedValue,
467 2241 : this->wasAutoSized,
468 : this->curSysNum,
469 : this->curZoneEqNum,
470 : this->curOASysNum,
471 : FanCoolLoad,
472 : TotCapTempModFac,
473 : DXFlowPerCapMinRatio,
474 : DXFlowPerCapMaxRatio);
475 : }
476 3836 : return this->autoSizedValue;
477 : }
478 :
479 0 : void HeatingCapacitySizer::clearState()
480 : {
481 0 : BaseSizerWithScalableInputs::clearState();
482 0 : }
483 :
484 : } // namespace EnergyPlus
|