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 368 : Real64 HeatingCapacitySizer::size(EnergyPlusData &state, Real64 _originalValue, bool &errorsFound)
63 : {
64 368 : if (!this->checkInitialized(state, errorsFound)) {
65 1 : return 0.0;
66 : }
67 367 : this->preSize(state, _originalValue);
68 367 : Real64 DesVolFlow = 0.0;
69 367 : Real64 CoilInTemp = -999.0;
70 367 : Real64 CoilInHumRat = -999.0;
71 367 : Real64 CoilOutTemp = -999.0;
72 367 : Real64 CoilOutHumRat = -999.0;
73 :
74 367 : Real64 DXFlowPerCapMinRatio = 1.0;
75 367 : Real64 DXFlowPerCapMaxRatio = 1.0;
76 367 : Real64 NominalCapacityDes = 0.0;
77 367 : Real64 DesMassFlow = 0.0;
78 367 : Real64 DesCoilLoad = 0.0;
79 367 : Real64 OutAirFrac = 0.0;
80 367 : Real64 const CpAirStd = Psychrometrics::PsyCpAirFnW(0.0);
81 :
82 367 : if (this->dataEMSOverrideON) {
83 1 : this->autoSizedValue = this->dataEMSOverride;
84 366 : } 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 29 : this->autoSizedValue = this->dataConstantUsedForSizing * this->dataFractionUsedForSizing;
87 : } else {
88 337 : if (this->curZoneEqNum > 0) {
89 228 : if (!this->wasAutoSized && !this->sizingDesRunThisZone) {
90 81 : this->autoSizedValue = _originalValue;
91 147 : } else if (this->zoneEqSizing(this->curZoneEqNum).DesignSizeFromParent) {
92 1 : this->autoSizedValue = this->zoneEqSizing(this->curZoneEqNum).DesHeatingLoad;
93 : } else {
94 146 : if (this->dataCoilIsSuppHeater && this->suppHeatCap > 0.0) {
95 4 : NominalCapacityDes = this->suppHeatCap;
96 4 : if (this->dataFlowUsedForSizing > 0.0) {
97 0 : DesVolFlow = this->dataFlowUsedForSizing;
98 : }
99 142 : } else if (this->zoneEqSizing(this->curZoneEqNum).HeatingCapacity) {
100 66 : NominalCapacityDes = this->zoneEqSizing(this->curZoneEqNum).DesHeatingLoad;
101 66 : if (this->dataFlowUsedForSizing > 0.0) {
102 7 : DesVolFlow = this->dataFlowUsedForSizing;
103 : }
104 76 : } else if (this->dataCoolCoilCap > 0.0 && this->dataFlowUsedForSizing > 0.0) {
105 12 : NominalCapacityDes = this->dataCoolCoilCap;
106 12 : DesVolFlow = this->dataFlowUsedForSizing;
107 128 : } else if (int(this->finalZoneSizing.size()) > 0 &&
108 64 : this->finalZoneSizing(this->curZoneEqNum).DesHeatMassFlow >= HVAC::SmallMassFlow) {
109 58 : if (this->dataFlowUsedForSizing > 0.0) {
110 28 : DesVolFlow = this->dataFlowUsedForSizing;
111 : }
112 58 : if (this->termUnitPIU && (this->curTermUnitSizingNum > 0)) {
113 9 : Real64 const MinPriFlowFrac = this->termUnitSizing(this->curTermUnitSizingNum).MinPriFlowFrac;
114 9 : if (this->termUnitSizing(this->curTermUnitSizingNum).InducesPlenumAir) {
115 2 : CoilInTemp = (this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatCoilInTempTU * MinPriFlowFrac) +
116 2 : (this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).ZoneRetTempAtHeatPeak * (1.0 - MinPriFlowFrac));
117 : } else {
118 7 : CoilInTemp = (this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatCoilInTempTU * MinPriFlowFrac) +
119 7 : (this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).ZoneTempAtHeatPeak * (1.0 - MinPriFlowFrac));
120 : }
121 58 : } else if (this->termUnitIU && (this->curTermUnitSizingNum > 0)) {
122 1 : CoilInTemp = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).ZoneTempAtHeatPeak;
123 1 : CoilInHumRat = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).ZoneHumRatAtHeatPeak;
124 48 : } else if (this->termUnitSingDuct && (this->curTermUnitSizingNum > 0)) {
125 4 : CoilInTemp = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatCoilInTempTU;
126 4 : 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 44 : if (DesVolFlow > 0.0) {
130 24 : DesMassFlow = DesVolFlow * state.dataEnvrn->StdRhoAir;
131 : } else {
132 20 : DesMassFlow = this->finalZoneSizing(this->curZoneEqNum).DesHeatMassFlow;
133 : }
134 44 : CoilInTemp = this->setHeatCoilInletTempForZoneEqSizing(
135 44 : this->setOAFracForZoneEqSizing(state, DesMassFlow, zoneEqSizing(this->curZoneEqNum)),
136 44 : zoneEqSizing(this->curZoneEqNum),
137 44 : finalZoneSizing(this->curZoneEqNum));
138 44 : CoilInHumRat = this->setHeatCoilInletHumRatForZoneEqSizing(
139 44 : this->setOAFracForZoneEqSizing(state, DesMassFlow, zoneEqSizing(this->curZoneEqNum)),
140 44 : zoneEqSizing(this->curZoneEqNum),
141 44 : finalZoneSizing(this->curZoneEqNum));
142 : }
143 58 : if ((this->termUnitSingDuct || this->termUnitPIU) && (this->curTermUnitSizingNum > 0)) {
144 13 : CoilOutTemp = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).HeatDesTemp;
145 13 : CoilOutHumRat = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).HeatDesHumRat;
146 13 : Real64 const CpAir = Psychrometrics::PsyCpAirFnW(CoilOutHumRat);
147 13 : DesCoilLoad = CpAir * state.dataEnvrn->StdRhoAir * this->termUnitSizing(this->curTermUnitSizingNum).AirVolFlow *
148 13 : (CoilOutTemp - CoilInTemp);
149 13 : DesVolFlow = this->termUnitSizing(this->curTermUnitSizingNum).AirVolFlow;
150 58 : } else if (this->termUnitIU && (this->curTermUnitSizingNum > 0)) {
151 1 : if (this->termUnitSizing(this->curTermUnitSizingNum).InducRat > 0.01) {
152 1 : DesVolFlow = this->termUnitSizing(this->curTermUnitSizingNum).AirVolFlow /
153 1 : this->termUnitSizing(this->curTermUnitSizingNum).InducRat;
154 1 : 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 1 : DesCoilLoad = this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatLoad -
158 1 : (CpAir * state.dataEnvrn->StdRhoAir * DesVolFlow *
159 1 : (this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).DesHeatCoilInTempTU -
160 1 : this->termUnitFinalZoneSizing(this->curTermUnitSizingNum).ZoneTempAtHeatPeak));
161 : } else {
162 0 : DesCoilLoad = 0.0;
163 : }
164 1 : } else {
165 44 : CoilOutTemp = this->finalZoneSizing(this->curZoneEqNum).HeatDesTemp;
166 44 : CoilOutHumRat = this->finalZoneSizing(this->curZoneEqNum).HeatDesHumRat;
167 44 : Real64 const CpAir = Psychrometrics::PsyCpAirFnW(CoilOutHumRat);
168 44 : DesCoilLoad = CpAir * this->finalZoneSizing(this->curZoneEqNum).DesHeatMassFlow * (CoilOutTemp - CoilInTemp);
169 44 : DesVolFlow = this->finalZoneSizing(this->curZoneEqNum).DesHeatMassFlow / state.dataEnvrn->StdRhoAir;
170 : }
171 58 : NominalCapacityDes = max(0.0, DesCoilLoad);
172 : } else {
173 6 : NominalCapacityDes = 0.0;
174 6 : CoilOutTemp = -999.0;
175 : }
176 146 : if (this->dataCoolCoilCap > 0.0) {
177 12 : this->autoSizedValue = NominalCapacityDes * this->dataHeatSizeRatio;
178 : } else {
179 134 : this->autoSizedValue = NominalCapacityDes * this->dataHeatSizeRatio * this->dataFracOfAutosizedHeatingCapacity;
180 : }
181 146 : if (state.dataGlobal->DisplayExtraWarnings && this->autoSizedValue <= 0.0) {
182 2 : ShowWarningMessage(state,
183 2 : this->callingRoutine + ": Potential issue with equipment sizing for " + this->compType + ' ' + this->compName);
184 1 : ShowContinueError(state, format("...Rated Total Heating Capacity = {:.2T} [W]", this->autoSizedValue));
185 2 : if (this->zoneEqSizing(this->curZoneEqNum).HeatingCapacity ||
186 1 : (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 1 : 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 3 : ShowContinueError(state, "...Capacity used to size child component set to 0 [W]");
196 : }
197 : }
198 : }
199 : }
200 109 : } else if (this->curSysNum > 0) {
201 81 : if (!this->wasAutoSized && !this->sizingDesRunThisAirSys) {
202 6 : this->autoSizedValue = _originalValue;
203 : } else {
204 75 : if (this->curOASysNum > 0) {
205 12 : if (this->oaSysEqSizing(this->curOASysNum).AirFlow) {
206 2 : DesVolFlow = this->oaSysEqSizing(this->curOASysNum).AirVolFlow;
207 10 : } else if (this->oaSysEqSizing(this->curOASysNum).HeatingAirFlow) {
208 1 : DesVolFlow = this->oaSysEqSizing(this->curOASysNum).HeatingAirVolFlow;
209 9 : } else if (this->outsideAirSys(this->curOASysNum).AirLoopDOASNum > -1) {
210 4 : DesVolFlow =
211 4 : this->airloopDOAS[this->outsideAirSys(this->curOASysNum).AirLoopDOASNum].SizingMassFlow / state.dataEnvrn->StdRhoAir;
212 : } else {
213 5 : DesVolFlow = this->finalSysSizing(this->curSysNum).DesOutAirVolFlow;
214 : }
215 : } else {
216 63 : if (this->finalSysSizing(this->curSysNum).HeatingCapMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
217 3 : this->dataFracOfAutosizedHeatingCapacity = this->finalSysSizing(this->curSysNum).FractionOfAutosizedHeatingCapacity;
218 : }
219 63 : if (this->dataFlowUsedForSizing > 0.0) {
220 29 : DesVolFlow = this->dataFlowUsedForSizing;
221 34 : } else if (this->unitarySysEqSizing(this->curSysNum).AirFlow) {
222 1 : DesVolFlow = this->unitarySysEqSizing(this->curSysNum).AirVolFlow;
223 33 : } else if (this->unitarySysEqSizing(this->curSysNum).HeatingAirFlow) {
224 1 : DesVolFlow = this->unitarySysEqSizing(this->curSysNum).HeatingAirVolFlow;
225 : } else {
226 32 : if (this->curDuctType == HVAC::AirDuctType::Main) {
227 23 : if (this->finalSysSizing(this->curSysNum).SysAirMinFlowRat > 0.0 && !this->dataDesicRegCoil) {
228 15 : DesVolFlow =
229 15 : this->finalSysSizing(this->curSysNum).SysAirMinFlowRat * this->finalSysSizing(this->curSysNum).DesMainVolFlow;
230 : } else {
231 8 : DesVolFlow = this->finalSysSizing(this->curSysNum).DesMainVolFlow;
232 : }
233 9 : } else if (this->curDuctType == HVAC::AirDuctType::Cooling) {
234 2 : if (this->finalSysSizing(this->curSysNum).SysAirMinFlowRat > 0.0 && !this->dataDesicRegCoil) {
235 1 : DesVolFlow =
236 1 : this->finalSysSizing(this->curSysNum).SysAirMinFlowRat * this->finalSysSizing(this->curSysNum).DesCoolVolFlow;
237 : } else {
238 1 : DesVolFlow = this->finalSysSizing(this->curSysNum).DesCoolVolFlow;
239 : }
240 7 : } else if (this->curDuctType == HVAC::AirDuctType::Heating) {
241 1 : DesVolFlow = this->finalSysSizing(this->curSysNum).DesHeatVolFlow;
242 : } else {
243 6 : DesVolFlow = this->finalSysSizing(this->curSysNum).DesMainVolFlow;
244 : }
245 : }
246 : }
247 75 : DesMassFlow = state.dataEnvrn->StdRhoAir * DesVolFlow;
248 : // get the outside air fraction
249 75 : if (this->curOASysNum > 0) {
250 12 : OutAirFrac = 1.0;
251 63 : } else if (this->finalSysSizing(this->curSysNum).HeatOAOption == DataSizing::OAControl::MinOA) {
252 32 : if (DesVolFlow > 0.0) {
253 32 : OutAirFrac = this->finalSysSizing(this->curSysNum).DesOutAirVolFlow / DesVolFlow;
254 : } else {
255 0 : OutAirFrac = 1.0;
256 : }
257 32 : OutAirFrac = std::min(1.0, std::max(0.0, OutAirFrac));
258 : } else {
259 31 : OutAirFrac = 1.0;
260 : }
261 : // coil inlet temperature
262 75 : if (this->curOASysNum == 0 && this->primaryAirSystem(this->curSysNum).NumOAHeatCoils > 0) {
263 18 : CoilInTemp = OutAirFrac * this->finalSysSizing(this->curSysNum).PreheatTemp +
264 18 : (1.0 - OutAirFrac) * this->finalSysSizing(this->curSysNum).HeatRetTemp;
265 18 : CoilInHumRat = OutAirFrac * this->finalSysSizing(this->curSysNum).PreheatHumRat +
266 18 : (1.0 - OutAirFrac) * this->finalSysSizing(this->curSysNum).HeatRetHumRat; // include humrat for coil sizing reports
267 57 : } else if (this->curOASysNum > 0 && this->outsideAirSys(this->curOASysNum).AirLoopDOASNum > -1) {
268 4 : CoilInTemp = this->airloopDOAS[this->outsideAirSys(this->curOASysNum).AirLoopDOASNum].HeatOutTemp;
269 : } else {
270 53 : CoilInTemp = OutAirFrac * this->finalSysSizing(this->curSysNum).HeatOutTemp +
271 53 : (1.0 - OutAirFrac) * this->finalSysSizing(this->curSysNum).HeatRetTemp;
272 53 : CoilInHumRat = OutAirFrac * this->finalSysSizing(this->curSysNum).HeatOutHumRat +
273 53 : (1.0 - OutAirFrac) * this->finalSysSizing(this->curSysNum).HeatRetHumRat; // include humrat for coil sizing reports
274 : }
275 : // coil load
276 75 : if (this->curOASysNum > 0) {
277 12 : if (this->oaSysEqSizing(this->curOASysNum).HeatingCapacity) {
278 1 : DesCoilLoad = this->oaSysEqSizing(this->curOASysNum).DesHeatingLoad;
279 11 : } else if (this->dataDesicRegCoil) {
280 2 : DesCoilLoad = CpAirStd * DesMassFlow * (this->dataDesOutletAirTemp - this->dataDesInletAirTemp);
281 2 : CoilOutTemp = this->dataDesOutletAirTemp;
282 9 : } else if (this->outsideAirSys(this->curOASysNum).AirLoopDOASNum > -1) {
283 8 : DesCoilLoad = CpAirStd * DesMassFlow *
284 4 : (this->airloopDOAS[this->outsideAirSys(this->curOASysNum).AirLoopDOASNum].PreheatTemp - CoilInTemp);
285 4 : CoilOutTemp = this->airloopDOAS[outsideAirSys(this->curOASysNum).AirLoopDOASNum].PreheatTemp;
286 : } else {
287 5 : DesCoilLoad = CpAirStd * DesMassFlow * (this->finalSysSizing(this->curSysNum).PreheatTemp - CoilInTemp);
288 5 : CoilOutTemp = this->finalSysSizing(this->curSysNum).PreheatTemp;
289 5 : CoilOutHumRat = this->finalSysSizing(this->curSysNum).PreheatHumRat;
290 : }
291 : } else {
292 63 : if (this->unitarySysEqSizing(this->curSysNum).HeatingCapacity) {
293 3 : DesCoilLoad = this->unitarySysEqSizing(this->curSysNum).DesHeatingLoad;
294 3 : CoilOutTemp = this->finalSysSizing(this->curSysNum).HeatSupTemp;
295 3 : CoilOutHumRat = this->finalSysSizing(this->curSysNum).HeatSupHumRat;
296 60 : } else if (this->dataDesicRegCoil) {
297 4 : DesCoilLoad = CpAirStd * DesMassFlow * (this->dataDesOutletAirTemp - this->dataDesInletAirTemp);
298 4 : CoilOutTemp = this->dataDesOutletAirTemp;
299 : } else {
300 56 : DesCoilLoad = CpAirStd * DesMassFlow * (this->finalSysSizing(this->curSysNum).HeatSupTemp - CoilInTemp);
301 56 : CoilOutTemp = this->finalSysSizing(this->curSysNum).HeatSupTemp;
302 56 : CoilOutHumRat = this->finalSysSizing(this->curSysNum).HeatSupHumRat;
303 : }
304 : }
305 75 : if (this->curSysNum <= state.dataHVACGlobal->NumPrimaryAirSys && this->airLoopControlInfo(this->curSysNum).UnitarySys) {
306 13 : if (this->dataCoilIsSuppHeater) {
307 3 : NominalCapacityDes = this->suppHeatCap;
308 10 : } else if (this->dataCoolCoilCap > 0.0) {
309 3 : 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 12 : if (this->airLoopControlInfo(this->curSysNum).UnitarySysSimulating &&
315 12 : !Util::SameString(this->compType, "COIL:HEATING:WATER")) {
316 1 : NominalCapacityDes = this->unitaryHeatCap;
317 : } else {
318 6 : if (DesCoilLoad >= HVAC::SmallLoad) {
319 6 : NominalCapacityDes = DesCoilLoad;
320 : } else {
321 0 : NominalCapacityDes = 0.0;
322 : }
323 : }
324 : }
325 13 : DesCoilLoad = NominalCapacityDes;
326 109 : } else if (this->curSysNum <= state.dataHVACGlobal->NumPrimaryAirSys &&
327 47 : this->finalSysSizing(this->curSysNum).HeatingCapMethod == DataSizing::CapacityPerFloorArea) {
328 1 : NominalCapacityDes = this->finalSysSizing(this->curSysNum).HeatingTotalCapacity;
329 61 : } else if (this->curSysNum <= state.dataHVACGlobal->NumPrimaryAirSys &&
330 85 : this->finalSysSizing(this->curSysNum).HeatingCapMethod == DataSizing::HeatingDesignCapacity &&
331 24 : this->finalSysSizing(this->curSysNum).HeatingTotalCapacity > 0.0) {
332 2 : NominalCapacityDes = this->finalSysSizing(this->curSysNum).HeatingTotalCapacity;
333 : } else {
334 59 : if (this->dataCoolCoilCap > 0.0) { // this line can't get executed with same logic above else
335 1 : NominalCapacityDes = this->dataCoolCoilCap;
336 58 : } else if (DesCoilLoad >= HVAC::SmallLoad) {
337 55 : NominalCapacityDes = DesCoilLoad;
338 : } else {
339 3 : NominalCapacityDes = 0.0;
340 : }
341 : }
342 75 : this->autoSizedValue = NominalCapacityDes * this->dataHeatSizeRatio * this->dataFracOfAutosizedHeatingCapacity;
343 75 : if (state.dataGlobal->DisplayExtraWarnings && this->autoSizedValue <= 0.0) {
344 4 : ShowWarningMessage(state,
345 4 : this->callingRoutine + ": Potential issue with equipment sizing for " + this->compType + ' ' + this->compName);
346 2 : ShowContinueError(state, format("...Rated Total Heating Capacity = {:.2T} [W]", this->autoSizedValue));
347 2 : if (CoilOutTemp > -999.0) {
348 2 : ShowContinueError(state, format("...Air flow rate used for sizing = {:.5T} [m3/s]", DesVolFlow));
349 2 : ShowContinueError(state, format("...Outdoor air fraction used for sizing = {:.2T}", OutAirFrac));
350 2 : ShowContinueError(state, format("...Coil inlet air temperature used for sizing = {:.2T} [C]", CoilInTemp));
351 2 : 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 28 : } else if (this->dataNonZoneNonAirloopValue > 0) {
358 0 : this->autoSizedValue = this->dataNonZoneNonAirloopValue;
359 28 : } else if (!this->wasAutoSized) {
360 26 : this->autoSizedValue = this->originalValue;
361 : } else {
362 2 : std::string msg = this->callingRoutine + ' ' + this->compType + ' ' + this->compName + ", Developer Error: Component sizing incomplete.";
363 2 : ShowSevereError(state, msg);
364 2 : this->addErrorMessage(msg);
365 2 : msg = format("SizingString = {}, SizingResult = {:.1T}", this->sizingString, this->autoSizedValue);
366 2 : ShowContinueError(state, msg);
367 2 : this->addErrorMessage(msg);
368 2 : errorsFound = true;
369 2 : }
370 : }
371 367 : if (!this->hardSizeNoDesignRun || this->dataScalableSizingON || this->dataScalableCapSizingON) {
372 339 : 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 196 : bool FlagCheckVolFlowPerRatedTotCap = true;
376 392 : if (Util::SameString(this->compType, "Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl") ||
377 392 : Util::SameString(this->compType, "Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl")) {
378 5 : FlagCheckVolFlowPerRatedTotCap = false;
379 : }
380 :
381 196 : if (this->dataIsDXCoil && FlagCheckVolFlowPerRatedTotCap && this->autoSizedValue > 0.0) {
382 13 : Real64 RatedVolFlowPerRatedTotCap = DesVolFlow / this->autoSizedValue;
383 13 : if (RatedVolFlowPerRatedTotCap < HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) {
384 4 : if ((this->dataEMSOverride == 0.0) && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
385 0 : ShowWarningError(state, this->callingRoutine + ' ' + this->compType + ' ' + this->compName);
386 0 : ShowContinueError(
387 0 : state, "..." + this->sizingString + " will be limited by the minimum rated volume flow per rated total capacity ratio.");
388 0 : ShowContinueError(state, format("...DX coil volume flow rate (m3/s ) = {:.6T}", DesVolFlow));
389 0 : ShowContinueError(state, format("...Requested capacity (W ) = {:.3T}", this->autoSizedValue));
390 0 : ShowContinueError(state, format("...Requested flow/capacity ratio (m3/s/W ) = {:.3T}", RatedVolFlowPerRatedTotCap));
391 0 : ShowContinueError(state,
392 0 : format("...Minimum flow/capacity ratio (m3/s/W ) = {:.3T}",
393 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
394 : }
395 :
396 4 : DXFlowPerCapMinRatio = (DesVolFlow / HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) /
397 4 : this->autoSizedValue; // set DX Coil Capacity Increase Ratio from Too Low Flow/Capacity Ratio
398 4 : this->autoSizedValue = DesVolFlow / HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT];
399 :
400 4 : if ((this->dataEMSOverride == 0.0) && state.dataGlobal->DisplayExtraWarnings && this->printWarningFlag) {
401 0 : ShowContinueError(state, format("...Adjusted capacity ( W ) = {:.3T}", this->autoSizedValue));
402 : }
403 9 : } else if (RatedVolFlowPerRatedTotCap > HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) {
404 0 : 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 0 : DXFlowPerCapMaxRatio = DesVolFlow / HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] /
417 0 : this->autoSizedValue; // set DX Coil Capacity Decrease Ratio from Too High Flow/Capacity Ratio
418 0 : this->autoSizedValue = DesVolFlow / HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT];
419 :
420 0 : 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 367 : if (this->overrideSizeString) {
430 44 : if (this->isEpJSON) {
431 0 : this->sizingString = "nominal_capacity [W]";
432 : }
433 : }
434 367 : if (this->dataScalableCapSizingON) {
435 14 : switch (this->zoneEqSizing(this->curZoneEqNum).SizingMethod(HVAC::HeatingCapacitySizing)) {
436 7 : case DataSizing::CapacityPerFloorArea: {
437 7 : this->sizingStringScalable = "(scaled by capacity / area) ";
438 7 : } break;
439 7 : case DataSizing::FractionOfAutosizedHeatingCapacity:
440 : case DataSizing::FractionOfAutosizedCoolingCapacity: {
441 7 : this->sizingStringScalable = "(scaled by fractional multiplier) ";
442 7 : } break;
443 0 : default:
444 0 : break;
445 : }
446 : }
447 :
448 367 : this->selectSizerOutput(state, errorsFound);
449 :
450 367 : if (this->isCoilReportObject) {
451 200 : if (CoilInTemp > -999.0) { // set inlet air properties used during capacity sizing if available, allow for negative winter temps
452 93 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
453 93 : state, this->compName, this->compType, CoilInTemp, this->curSysNum, this->curZoneEqNum);
454 93 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, this->compName, this->compType, CoilInHumRat);
455 : }
456 200 : if (CoilOutTemp > -999.0) { // set outlet air properties used during capacity sizing if available
457 91 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, this->compName, this->compType, CoilOutTemp);
458 91 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, this->compName, this->compType, CoilOutHumRat);
459 : }
460 200 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilAirFlow(state, this->compName, this->compType, DesVolFlow, this->wasAutoSized);
461 200 : Real64 constexpr FanCoolLoad = 0.0;
462 200 : Real64 constexpr TotCapTempModFac = 1.0;
463 200 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilHeatingCapacity(state,
464 200 : this->compName,
465 200 : this->compType,
466 : this->autoSizedValue,
467 200 : this->wasAutoSized,
468 : this->curSysNum,
469 : this->curZoneEqNum,
470 : this->curOASysNum,
471 : FanCoolLoad,
472 : TotCapTempModFac,
473 : DXFlowPerCapMinRatio,
474 : DXFlowPerCapMaxRatio);
475 : }
476 367 : return this->autoSizedValue;
477 : }
478 :
479 0 : void HeatingCapacitySizer::clearState()
480 : {
481 0 : BaseSizerWithScalableInputs::clearState();
482 0 : }
483 :
484 : } // namespace EnergyPlus
|