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 : // EnergyPlus Headers
49 : #include <EnergyPlus/Data/EnergyPlusData.hh>
50 : #include <EnergyPlus/DataContaminantBalance.hh>
51 : #include <EnergyPlus/DataEnvironment.hh>
52 : #include <EnergyPlus/DataHeatBalance.hh>
53 : #include <EnergyPlus/DataSizing.hh>
54 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
55 : #include <EnergyPlus/DataZoneEquipment.hh>
56 : #include <EnergyPlus/Psychrometrics.hh>
57 : #include <EnergyPlus/ScheduleManager.hh>
58 :
59 : namespace EnergyPlus::DataSizing {
60 :
61 : // MODULE INFORMATION:
62 : // AUTHOR Fred Buhl
63 : // DATE WRITTEN December 2000
64 :
65 : // PURPOSE OF THIS MODULE:
66 : // This data-only module contains type definitions and variables
67 : // associated with HVAC system design flow rates, temperatures and
68 : // capacities. This data is available to the HVAC component modules
69 : // for their self sizing calculations.
70 :
71 : // days; includes effects of user multiplier
72 : // and user set flows)
73 : // of user input multiplier and flows
74 : // all design days, calculated only)
75 : // using user input system flow rates.
76 : // before applying user input sys flow rates.
77 :
78 10220 : Real64 TermUnitSizingData::applyTermUnitSizingCoolFlow(Real64 const coolFlowWithOA, // Cooling flow rate with MinOA limit applied
79 : Real64 const coolFlowNoOA // Cooling flow rate without MinOA limit applied
80 : )
81 : {
82 : // Apply DesignSpecification:AirTerminal:Sizing to cooling flow (could be vol flow or mass flow)
83 10220 : Real64 coolFlowRatio = 1.0;
84 10220 : if (this->SpecDesCoolSATRatio > 0.0) {
85 10220 : coolFlowRatio = this->SpecDesSensCoolingFrac / this->SpecDesCoolSATRatio;
86 : } else {
87 0 : coolFlowRatio = this->SpecDesSensCoolingFrac;
88 : }
89 10220 : Real64 adjustedFlow = coolFlowNoOA * coolFlowRatio + (coolFlowWithOA - coolFlowNoOA) * this->SpecMinOAFrac;
90 10220 : return adjustedFlow;
91 : }
92 :
93 10220 : Real64 TermUnitSizingData::applyTermUnitSizingHeatFlow(Real64 const heatFlowWithOA, // Heating flow rate with MinOA limit applied
94 : Real64 const heatFlowNoOA // Heating flow rate without MinOA limit applied
95 : )
96 : {
97 : // Apply DesignSpecification:AirTerminal:Sizing to heating flow (could be vol flow or mass flow)
98 10220 : Real64 heatFlowRatio = 1.0;
99 10220 : if (this->SpecDesHeatSATRatio > 0.0) {
100 10220 : heatFlowRatio = this->SpecDesSensHeatingFrac / this->SpecDesHeatSATRatio;
101 : } else {
102 0 : heatFlowRatio = this->SpecDesSensHeatingFrac;
103 : }
104 10220 : Real64 adjustedFlow = heatFlowNoOA * heatFlowRatio + (heatFlowWithOA - heatFlowNoOA) * this->SpecMinOAFrac;
105 10220 : return adjustedFlow;
106 : }
107 :
108 25 : void TermUnitZoneSizingData::scaleZoneCooling(Real64 const ratio)
109 : {
110 : // Apply scaling ratio to TermUnitFinalZoneSizing cooling flow and load
111 25 : this->DesCoolVolFlow *= ratio;
112 25 : this->DesCoolMassFlow *= ratio;
113 25 : this->DesCoolLoad *= ratio;
114 2425 : for (auto &cfs : this->CoolFlowSeq) {
115 2400 : cfs *= ratio;
116 : }
117 25 : }
118 :
119 17 : void TermUnitZoneSizingData::scaleZoneHeating(Real64 const ratio)
120 : {
121 : // Apply scaling ratio to TermUnitFinalZoneSizing heating flow and load
122 17 : this->DesHeatVolFlow *= ratio;
123 17 : this->DesHeatMassFlow *= ratio;
124 17 : this->DesHeatLoad *= ratio;
125 1649 : for (auto &cfs : this->HeatFlowSeq) {
126 1632 : cfs *= ratio;
127 : }
128 17 : }
129 :
130 214 : void ZoneSizingData::zeroMemberData()
131 : {
132 214 : if (!allocated(this->DOASSupMassFlowSeq)) {
133 10 : return;
134 : }
135 204 : std::fill(this->DOASSupMassFlowSeq.begin(), this->DOASSupMassFlowSeq.end(), 0.0);
136 204 : std::fill(this->DOASHeatLoadSeq.begin(), this->DOASHeatLoadSeq.end(), 0.0);
137 204 : std::fill(this->DOASCoolLoadSeq.begin(), this->DOASCoolLoadSeq.end(), 0.0);
138 204 : std::fill(this->DOASHeatAddSeq.begin(), this->DOASHeatAddSeq.end(), 0.0);
139 204 : std::fill(this->DOASLatAddSeq.begin(), this->DOASLatAddSeq.end(), 0.0);
140 204 : std::fill(this->DOASSupTempSeq.begin(), this->DOASSupTempSeq.end(), 0.0);
141 204 : std::fill(this->DOASSupHumRatSeq.begin(), this->DOASSupHumRatSeq.end(), 0.0);
142 204 : std::fill(this->DOASTotCoolLoadSeq.begin(), this->DOASTotCoolLoadSeq.end(), 0.0);
143 204 : std::fill(this->HeatFlowSeq.begin(), this->HeatFlowSeq.end(), 0.0);
144 204 : std::fill(this->HeatFlowSeqNoOA.begin(), this->HeatFlowSeqNoOA.end(), 0.0);
145 204 : std::fill(this->HeatLoadSeq.begin(), this->HeatLoadSeq.end(), 0.0);
146 204 : std::fill(this->HeatZoneTempSeq.begin(), this->HeatZoneTempSeq.end(), 0.0);
147 204 : std::fill(this->DesHeatSetPtSeq.begin(), this->DesHeatSetPtSeq.end(), 0.0);
148 204 : std::fill(this->HeatOutTempSeq.begin(), this->HeatOutTempSeq.end(), 0.0);
149 204 : std::fill(this->HeatZoneRetTempSeq.begin(), this->HeatZoneRetTempSeq.end(), 0.0);
150 204 : std::fill(this->HeatTstatTempSeq.begin(), this->HeatTstatTempSeq.end(), 0.0);
151 204 : std::fill(this->HeatZoneHumRatSeq.begin(), this->HeatZoneHumRatSeq.end(), 0.0);
152 204 : std::fill(this->HeatOutHumRatSeq.begin(), this->HeatOutHumRatSeq.end(), 0.0);
153 204 : std::fill(this->CoolFlowSeq.begin(), this->CoolFlowSeq.end(), 0.0);
154 204 : std::fill(this->CoolFlowSeqNoOA.begin(), this->CoolFlowSeqNoOA.end(), 0.0);
155 204 : std::fill(this->CoolLoadSeq.begin(), this->CoolLoadSeq.end(), 0.0);
156 204 : std::fill(this->CoolZoneTempSeq.begin(), this->CoolZoneTempSeq.end(), 0.0);
157 204 : std::fill(this->DesCoolSetPtSeq.begin(), this->DesCoolSetPtSeq.end(), 0.0);
158 204 : std::fill(this->CoolOutTempSeq.begin(), this->CoolOutTempSeq.end(), 0.0);
159 204 : std::fill(this->CoolZoneRetTempSeq.begin(), this->CoolZoneRetTempSeq.end(), 0.0);
160 204 : std::fill(this->CoolTstatTempSeq.begin(), this->CoolTstatTempSeq.end(), 0.0);
161 204 : std::fill(this->CoolZoneHumRatSeq.begin(), this->CoolZoneHumRatSeq.end(), 0.0);
162 204 : std::fill(this->CoolOutHumRatSeq.begin(), this->CoolOutHumRatSeq.end(), 0.0);
163 204 : std::fill(this->HeatLoadNoDOASSeq.begin(), this->HeatLoadNoDOASSeq.end(), 0.0);
164 204 : std::fill(this->CoolLoadNoDOASSeq.begin(), this->CoolLoadNoDOASSeq.end(), 0.0);
165 204 : std::fill(this->LatentHeatLoadSeq.begin(), this->LatentHeatLoadSeq.end(), 0.0);
166 204 : std::fill(this->LatentCoolLoadSeq.begin(), this->LatentCoolLoadSeq.end(), 0.0);
167 204 : std::fill(this->HeatLatentLoadNoDOASSeq.begin(), this->HeatLatentLoadNoDOASSeq.end(), 0.0);
168 204 : std::fill(this->CoolLatentLoadNoDOASSeq.begin(), this->CoolLatentLoadNoDOASSeq.end(), 0.0);
169 204 : std::fill(this->LatentCoolFlowSeq.begin(), this->LatentCoolFlowSeq.end(), 0.0);
170 204 : std::fill(this->LatentHeatFlowSeq.begin(), this->LatentHeatFlowSeq.end(), 0.0);
171 :
172 204 : this->CoolDesDay = ""; // name of a sensible cooling design day
173 204 : this->HeatDesDay = ""; // name of a sensible heating design day
174 204 : this->CoolNoDOASDesDay = ""; // name of a sensible cooling design day without DOAS
175 204 : this->HeatNoDOASDesDay = ""; // name of a sensible heating design day without DOAS
176 204 : this->LatCoolDesDay = ""; // name of a latent cooling design day
177 204 : this->LatHeatDesDay = ""; // name of a latent heating design day
178 204 : this->LatCoolNoDOASDesDay = ""; // name of a latent cooling design day without DOAS
179 204 : this->LatHeatNoDOASDesDay = ""; // name of a latent heating design day without DOAS
180 :
181 204 : this->DesHeatMassFlow = 0.0; // zone design heating air mass flow rate [kg/s]
182 204 : this->DesCoolMassFlow = 0.0; // zone design cooling air mass flow rate [kg/s]
183 204 : this->DesHeatLoad = 0.0; // zone design heating load [W]
184 204 : this->DesCoolLoad = 0.0; // zone design cooling load [W]
185 204 : this->DesHeatDens = 0.0; // zone design heating air density [kg/m3]
186 204 : this->DesCoolDens = 0.0; // zone design cooling air density [kg/m3]
187 204 : this->DesHeatVolFlow = 0.0; // zone design heating air volume flow rate [m3/s]
188 204 : this->DesCoolVolFlow = 0.0; // zone design cooling air volume flow rate [m3/s]
189 204 : this->DesHeatVolFlowMax = 0.0; // zone design heating maximum air volume flow rate [m3/s]
190 204 : this->DesCoolVolFlowMin = 0.0; // zone design cooling minimum air volume flow rate [m3/s]
191 204 : this->DesHeatCoilInTemp = 0.0; // zone heating coil design air inlet temperature [C]
192 204 : this->DesCoolCoilInTemp = 0.0; // zone cooling coil design air inlet temperature [C]
193 204 : this->DesHeatCoilInHumRat = 0.0; // zone heating coil design air inlet humidity ratio [kg/kg]
194 204 : this->DesCoolCoilInHumRat = 0.0; // zone cooling coil design air inlet humidity ratio [kg/kg]
195 204 : this->DesHeatCoilInTempTU = 0.0; // zone heating coil design air inlet temperature (supply air)([C]
196 204 : this->DesCoolCoilInTempTU = 0.0; // zone cooling coil design air inlet temperature (supply air)[C]
197 204 : this->DesHeatCoilInHumRatTU = 0.0; // zone heating coil design air inlet humidity ratio
198 204 : this->DesCoolCoilInHumRatTU = 0.0; // zone cooling coil design air inlet humidity ratio
199 204 : this->HeatMassFlow = 0.0; // current zone heating air mass flow rate (HVAC time step)
200 204 : this->CoolMassFlow = 0.0; // current zone cooling air mass flow rate (HVAC time step)
201 204 : this->HeatLoad = 0.0; // current zone heating load (HVAC time step)
202 204 : this->CoolLoad = 0.0; // current zone heating load (HVAC time step)
203 204 : this->HeatZoneTemp = 0.0; // current zone temperature (heating, time step)
204 204 : this->HeatOutTemp = 0.0; // current outdoor temperature (heating, time step)
205 204 : this->HeatZoneRetTemp = 0.0; // current zone return temperature (heating, time step)
206 204 : this->HeatTstatTemp = 0.0; // current zone thermostat temperature (heating, time step)
207 204 : this->CoolZoneTemp = 0.0; // current zone temperature (cooling, time step)
208 204 : this->CoolOutTemp = 0.0; // current Outdoor temperature (cooling, time step)
209 204 : this->CoolZoneRetTemp = 0.0; // current zone return temperature (cooling, time step)
210 204 : this->CoolTstatTemp = 0.0; // current zone thermostat temperature (cooling, time step)
211 204 : this->HeatZoneHumRat = 0.0; // current zone humidity ratio (heating, time step)
212 204 : this->CoolZoneHumRat = 0.0; // current zone humidity ratio (cooling, time step)
213 204 : this->HeatOutHumRat = 0.0; // current outdoor humidity ratio (heating, time step)
214 204 : this->CoolOutHumRat = 0.0; // current outdoor humidity ratio (cooling, time step)
215 204 : this->ZoneTempAtHeatPeak = 0.0; // zone temp at max heating [C]
216 204 : this->ZoneRetTempAtHeatPeak = 0.0; // zone return temp at max heating [C]
217 204 : this->OutTempAtHeatPeak = 0.0; // outdoor temperature at max heating [C]
218 204 : this->ZoneTempAtCoolPeak = 0.0; // zone temp at max cooling [C]
219 204 : this->ZoneRetTempAtCoolPeak = 0.0; // zone return temp at max cooling [C]
220 204 : this->OutTempAtCoolPeak = 0.0; // outdoor temperature at max cooling [C]
221 204 : this->ZoneHumRatAtHeatPeak = 0.0; // zone humidity ratio at max heating [kg/kg]
222 204 : this->ZoneHumRatAtCoolPeak = 0.0; // zone humidity ratio at max cooling [kg/kg]
223 204 : this->OutHumRatAtHeatPeak = 0.0; // outdoor humidity at max heating [kg/kg]
224 204 : this->OutHumRatAtCoolPeak = 0.0; // outdoor humidity at max cooling [kg/kg]
225 204 : this->TimeStepNumAtHeatMax = 0; // time step number (in day) at Heating peak
226 204 : this->TimeStepNumAtCoolMax = 0; // time step number (in day) at cooling peak
227 204 : this->HeatDDNum = 0; // design day index of design day causing heating peak
228 204 : this->CoolDDNum = 0; // design day index of design day causing heating peak
229 204 : this->LatentHeatDDNum = 0; // design day index of design day causing heating peak
230 204 : this->LatentCoolDDNum = 0; // design day index of design day causing cooling peak
231 204 : this->LatentHeatNoDOASDDNum = 0; // design day index of design day causing latent heating peak without DOAS
232 204 : this->LatentCoolNoDOASDDNum = 0; // design day index of design day causing latent cooling peak without DOAS
233 204 : this->cHeatDDDate = ""; // date of design day causing heating peak
234 204 : this->cCoolDDDate = ""; // date of design day causing cooling peak
235 204 : this->cLatentHeatDDDate = ""; // date of design day causing heating peak
236 204 : this->cLatentCoolDDDate = ""; // date of design day causing cooling peak
237 204 : this->DOASHeatLoad = 0.0; // current heating load from DOAS supply air [W]
238 204 : this->DOASCoolLoad = 0.0; // current cooling load from DOAS supply air [W]
239 204 : this->DOASSupMassFlow = 0.0; // current mass flow rate of DOAS supply air [kg/s]
240 204 : this->DOASSupTemp = 0.0; // current DOAS supply air temperature [C]
241 204 : this->DOASSupHumRat = 0.0; // current DOAS supply air humidity ratio [kgWater/kgDryAir]
242 204 : this->DOASTotCoolLoad = 0.0; // current total cooling load imposed by DOAS supply air [W]
243 204 : this->HeatLoadNoDOAS = 0.0; // current zone heating load no DOAS (HVAC time step)
244 204 : this->CoolLoadNoDOAS = 0.0; // current zone heating load no DOAS (HVAC time step)
245 204 : this->HeatLatentLoad = 0.0; // current zone humidification load (HVAC time step)
246 204 : this->CoolLatentLoad = 0.0; // current zone dehumidification load (HVAC time step)
247 204 : this->HeatLatentLoadNoDOAS = 0.0; // current zone humidification load without DOAS (HVAC time step)
248 204 : this->CoolLatentLoadNoDOAS = 0.0; // current zone dehumidification load without DOAS (HVAC time step)
249 204 : this->ZoneHeatLatentMassFlow = 0.0; // current mass flow rate required to meet humidification load [kg/s]
250 204 : this->ZoneCoolLatentMassFlow = 0.0; // current mass flow rate required to meet dehumidification load [kg/s]
251 204 : this->ZoneHeatLatentVolFlow = 0.0; // current volume flow rate required to meet humidification load [m3/s]
252 204 : this->ZoneCoolLatentVolFlow = 0.0; // current volume flow rate required to meet dehumidification load [m3/s]
253 204 : this->DesHeatLoadNoDOAS = 0.0; // zone design heating load without DOAS [W]
254 204 : this->DesCoolLoadNoDOAS = 0.0; // zone design cooling load without DOAS [W]
255 204 : this->DesLatentHeatLoad = 0.0; // current zone humidification load (HVAC time step)
256 204 : this->DesLatentCoolLoad = 0.0; // current zone dehumidification load (HVAC time step)
257 204 : this->DesLatentHeatLoadNoDOAS = 0.0; // current zone humidification load no DOAS (HVAC time step)
258 204 : this->DesLatentCoolLoadNoDOAS = 0.0; // current zone dehumidification load no DOAS (HVAC time step)
259 204 : this->DesLatentHeatMassFlow = 0.0; // current mass flow rate required to meet humidification load [kg/s]
260 204 : this->DesLatentCoolMassFlow = 0.0; // current mass flow rate required to meet dehumidification load [kg/s]
261 204 : this->DesLatentHeatVolFlow = 0.0; // current volume flow rate required to meet humidification load [m3/s]
262 204 : this->DesLatentCoolVolFlow = 0.0; // current volume flow rate required to meet dehumidification load [m3/s]
263 204 : this->DesLatentHeatCoilInTemp = 0.0; // zone heating coil design air inlet temperature [C]
264 204 : this->DesLatentCoolCoilInTemp = 0.0; // zone cooling coil design air inlet temperature [C]
265 204 : this->DesLatentHeatCoilInHumRat = 0.0; // zone heating coil design air inlet humidity ratio [kg/kg]
266 204 : this->DesLatentCoolCoilInHumRat = 0.0; // zone cooling coil design air inlet humidity ratio [kg/kg]
267 204 : this->TimeStepNumAtLatentHeatMax = 0; // time step number (in day) at latent heating peak
268 204 : this->TimeStepNumAtLatentCoolMax = 0; // time step number (in day) at latent cooling peak
269 204 : this->TimeStepNumAtLatentHeatNoDOASMax = 0; // time step number (in day) at latent heating peak without DOAS
270 204 : this->TimeStepNumAtLatentCoolNoDOASMax = 0; // time step number (in day) at latent cooling peak without DOAS
271 204 : this->OutTempAtLatentCoolPeak = 0.0; // outdoor temperature at max latent cooling [C]
272 204 : this->OutHumRatAtLatentCoolPeak = 0.0; // outdoor humrat at max latent cooling [C]
273 204 : this->OutTempAtLatentHeatPeak = 0.0; // outdoor temperature at max latent heating [C]
274 204 : this->OutHumRatAtLatentHeatPeak = 0.0; // outdoor humrat at max latent heating [C]
275 204 : this->ZoneRetTempAtLatentCoolPeak = 0.0; // zone return temp at max cooling [C]
276 204 : this->ZoneRetTempAtLatentHeatPeak = 0.0; // zone return temp at max heating [C]
277 : }
278 :
279 547 : void ZoneSizingData::allocateMemberArrays(int const numOfTimeStepInDay)
280 : {
281 547 : this->HeatFlowSeq.dimension(numOfTimeStepInDay, 0.0);
282 547 : this->CoolFlowSeq.dimension(numOfTimeStepInDay, 0.0);
283 547 : this->HeatFlowSeqNoOA.dimension(numOfTimeStepInDay, 0.0);
284 547 : this->CoolFlowSeqNoOA.dimension(numOfTimeStepInDay, 0.0);
285 547 : this->HeatLoadSeq.dimension(numOfTimeStepInDay, 0.0);
286 547 : this->CoolLoadSeq.dimension(numOfTimeStepInDay, 0.0);
287 547 : this->HeatZoneTempSeq.dimension(numOfTimeStepInDay, 0.0);
288 547 : this->DesHeatSetPtSeq.dimension(numOfTimeStepInDay, 0.0);
289 547 : this->CoolZoneTempSeq.dimension(numOfTimeStepInDay, 0.0);
290 547 : this->DesCoolSetPtSeq.dimension(numOfTimeStepInDay, 0.0);
291 547 : this->HeatOutTempSeq.dimension(numOfTimeStepInDay, 0.0);
292 547 : this->CoolOutTempSeq.dimension(numOfTimeStepInDay, 0.0);
293 547 : this->HeatZoneRetTempSeq.dimension(numOfTimeStepInDay, 0.0);
294 547 : this->HeatTstatTempSeq.dimension(numOfTimeStepInDay, 0.0);
295 547 : this->CoolZoneRetTempSeq.dimension(numOfTimeStepInDay, 0.0);
296 547 : this->CoolTstatTempSeq.dimension(numOfTimeStepInDay, 0.0);
297 547 : this->HeatZoneHumRatSeq.dimension(numOfTimeStepInDay, 0.0);
298 547 : this->CoolZoneHumRatSeq.dimension(numOfTimeStepInDay, 0.0);
299 547 : this->HeatOutHumRatSeq.dimension(numOfTimeStepInDay, 0.0);
300 547 : this->CoolOutHumRatSeq.dimension(numOfTimeStepInDay, 0.0);
301 547 : this->DOASHeatLoadSeq.dimension(numOfTimeStepInDay, 0.0);
302 547 : this->DOASCoolLoadSeq.dimension(numOfTimeStepInDay, 0.0);
303 547 : this->DOASHeatAddSeq.dimension(numOfTimeStepInDay, 0.0);
304 547 : this->DOASLatAddSeq.dimension(numOfTimeStepInDay, 0.0);
305 547 : this->DOASSupMassFlowSeq.dimension(numOfTimeStepInDay, 0.0);
306 547 : this->DOASSupTempSeq.dimension(numOfTimeStepInDay, 0.0);
307 547 : this->DOASSupHumRatSeq.dimension(numOfTimeStepInDay, 0.0);
308 547 : this->DOASTotCoolLoadSeq.dimension(numOfTimeStepInDay, 0.0);
309 547 : this->HeatLoadNoDOASSeq.dimension(numOfTimeStepInDay, 0.0);
310 547 : this->CoolLoadNoDOASSeq.dimension(numOfTimeStepInDay, 0.0);
311 547 : this->LatentHeatLoadSeq.dimension(numOfTimeStepInDay, 0.0);
312 547 : this->LatentCoolLoadSeq.dimension(numOfTimeStepInDay, 0.0);
313 547 : this->HeatLatentLoadNoDOASSeq.dimension(numOfTimeStepInDay, 0.0);
314 547 : this->CoolLatentLoadNoDOASSeq.dimension(numOfTimeStepInDay, 0.0);
315 547 : this->LatentCoolFlowSeq.dimension(numOfTimeStepInDay, 0.0);
316 547 : this->LatentHeatFlowSeq.dimension(numOfTimeStepInDay, 0.0);
317 547 : }
318 :
319 78 : void TermUnitZoneSizingData::allocateMemberArrays(int const numOfTimeStepInDay)
320 : {
321 78 : this->HeatFlowSeq.dimension(numOfTimeStepInDay, 0.0);
322 78 : this->CoolFlowSeq.dimension(numOfTimeStepInDay, 0.0);
323 78 : this->HeatFlowSeqNoOA.dimension(numOfTimeStepInDay, 0.0);
324 78 : this->CoolFlowSeqNoOA.dimension(numOfTimeStepInDay, 0.0);
325 78 : this->HeatZoneTempSeq.dimension(numOfTimeStepInDay, 0.0);
326 78 : this->HeatZoneRetTempSeq.dimension(numOfTimeStepInDay, 0.0);
327 78 : this->CoolZoneTempSeq.dimension(numOfTimeStepInDay, 0.0);
328 78 : this->CoolZoneRetTempSeq.dimension(numOfTimeStepInDay, 0.0);
329 78 : }
330 :
331 82 : void TermUnitZoneSizingData::copyFromZoneSizing(ZoneSizingData const &sourceData)
332 : {
333 82 : this->ZoneName = sourceData.ZoneName;
334 82 : this->ADUName = sourceData.ADUName;
335 82 : this->CoolDesTemp = sourceData.CoolDesTemp;
336 82 : this->HeatDesTemp = sourceData.HeatDesTemp;
337 82 : this->CoolDesHumRat = sourceData.CoolDesHumRat;
338 82 : this->HeatDesHumRat = sourceData.HeatDesHumRat;
339 82 : this->DesOAFlowPPer = sourceData.DesOAFlowPPer;
340 82 : this->DesOAFlowPerArea = sourceData.DesOAFlowPerArea;
341 82 : this->DesCoolMinAirFlow = sourceData.DesCoolMinAirFlow;
342 82 : this->DesCoolMinAirFlowFrac = sourceData.DesCoolMinAirFlowFrac;
343 82 : this->DesHeatMaxAirFlow = sourceData.DesHeatMaxAirFlow;
344 82 : this->DesHeatMaxAirFlowFrac = sourceData.DesHeatMaxAirFlowFrac;
345 82 : this->ZoneNum = sourceData.ZoneNum;
346 82 : this->DesHeatMassFlow = sourceData.DesHeatMassFlow;
347 82 : this->DesHeatMassFlowNoOA = sourceData.DesHeatMassFlowNoOA;
348 82 : this->DesHeatOAFlowFrac = sourceData.DesHeatOAFlowFrac;
349 82 : this->DesCoolMassFlow = sourceData.DesCoolMassFlow;
350 82 : this->DesCoolMassFlowNoOA = sourceData.DesCoolMassFlowNoOA;
351 82 : this->DesCoolOAFlowFrac = sourceData.DesCoolOAFlowFrac;
352 82 : this->DesHeatLoad = sourceData.DesHeatLoad;
353 82 : this->NonAirSysDesHeatLoad = sourceData.NonAirSysDesHeatLoad;
354 82 : this->DesCoolLoad = sourceData.DesCoolLoad;
355 82 : this->NonAirSysDesCoolLoad = sourceData.NonAirSysDesCoolLoad;
356 82 : this->DesHeatVolFlow = sourceData.DesHeatVolFlow;
357 82 : this->DesHeatVolFlowNoOA = sourceData.DesHeatVolFlowNoOA;
358 82 : this->NonAirSysDesHeatVolFlow = sourceData.NonAirSysDesHeatVolFlow;
359 82 : this->DesCoolVolFlow = sourceData.DesCoolVolFlow;
360 82 : this->DesCoolVolFlowNoOA = sourceData.DesCoolVolFlowNoOA;
361 82 : this->NonAirSysDesCoolVolFlow = sourceData.NonAirSysDesCoolVolFlow;
362 82 : this->DesHeatVolFlowMax = sourceData.DesHeatVolFlowMax;
363 82 : this->DesCoolVolFlowMin = sourceData.DesCoolVolFlowMin;
364 82 : this->DesHeatCoilInTempTU = sourceData.DesHeatCoilInTempTU;
365 82 : this->DesCoolCoilInTempTU = sourceData.DesCoolCoilInTempTU;
366 82 : this->DesHeatCoilInHumRatTU = sourceData.DesHeatCoilInHumRatTU;
367 82 : this->DesCoolCoilInHumRatTU = sourceData.DesCoolCoilInHumRatTU;
368 82 : this->ZoneTempAtHeatPeak = sourceData.ZoneTempAtHeatPeak;
369 82 : this->ZoneRetTempAtHeatPeak = sourceData.ZoneRetTempAtHeatPeak;
370 82 : this->ZoneTempAtCoolPeak = sourceData.ZoneTempAtCoolPeak;
371 82 : this->ZoneRetTempAtCoolPeak = sourceData.ZoneRetTempAtCoolPeak;
372 82 : this->ZoneHumRatAtHeatPeak = sourceData.ZoneHumRatAtHeatPeak;
373 82 : this->ZoneHumRatAtCoolPeak = sourceData.ZoneHumRatAtCoolPeak;
374 82 : this->TimeStepNumAtHeatMax = sourceData.TimeStepNumAtHeatMax;
375 82 : this->TimeStepNumAtCoolMax = sourceData.TimeStepNumAtCoolMax;
376 82 : this->HeatDDNum = sourceData.HeatDDNum;
377 82 : this->CoolDDNum = sourceData.CoolDDNum;
378 82 : this->MinOA = sourceData.MinOA;
379 82 : this->DesCoolMinAirFlow2 = sourceData.DesCoolMinAirFlow2;
380 82 : this->DesHeatMaxAirFlow2 = sourceData.DesHeatMaxAirFlow2;
381 8698 : for (size_t t = 1; t <= this->HeatFlowSeq.size(); ++t) {
382 8616 : this->HeatFlowSeq(t) = sourceData.HeatFlowSeq(t);
383 8616 : this->HeatFlowSeqNoOA(t) = sourceData.HeatFlowSeqNoOA(t);
384 8616 : this->CoolFlowSeq(t) = sourceData.CoolFlowSeq(t);
385 8616 : this->CoolFlowSeqNoOA(t) = sourceData.CoolFlowSeqNoOA(t);
386 8616 : this->HeatZoneTempSeq(t) = sourceData.HeatZoneTempSeq(t);
387 8616 : this->HeatZoneRetTempSeq(t) = sourceData.HeatZoneRetTempSeq(t);
388 8616 : this->CoolZoneTempSeq(t) = sourceData.CoolZoneTempSeq(t);
389 8616 : this->CoolZoneRetTempSeq(t) = sourceData.CoolZoneRetTempSeq(t);
390 : }
391 82 : this->ZoneADEffCooling = sourceData.ZoneADEffCooling;
392 82 : this->ZoneADEffHeating = sourceData.ZoneADEffHeating;
393 82 : this->ZoneSecondaryRecirculation = sourceData.ZoneSecondaryRecirculation;
394 82 : this->ZoneVentilationEff = sourceData.ZoneVentilationEff;
395 82 : this->ZonePrimaryAirFraction = sourceData.ZonePrimaryAirFraction;
396 82 : this->ZonePrimaryAirFractionHtg = sourceData.ZonePrimaryAirFractionHtg;
397 82 : this->ZoneOAFracCooling = sourceData.ZoneOAFracCooling;
398 82 : this->ZoneOAFracHeating = sourceData.ZoneOAFracHeating;
399 82 : this->TotalOAFromPeople = sourceData.TotalOAFromPeople;
400 82 : this->TotalOAFromArea = sourceData.TotalOAFromArea;
401 82 : this->TotPeopleInZone = sourceData.TotPeopleInZone;
402 82 : this->TotalZoneFloorArea = sourceData.TotalZoneFloorArea;
403 82 : this->SupplyAirAdjustFactor = sourceData.SupplyAirAdjustFactor;
404 82 : this->ZpzClgByZone = sourceData.ZpzClgByZone;
405 82 : this->ZpzHtgByZone = sourceData.ZpzHtgByZone;
406 82 : this->VozClgByZone = sourceData.VozClgByZone;
407 82 : this->VozHtgByZone = sourceData.VozHtgByZone;
408 82 : this->VpzMinByZoneSPSized = sourceData.VpzMinByZoneSPSized;
409 82 : this->ZoneSizThermSetPtHi = sourceData.ZoneSizThermSetPtHi;
410 82 : this->ZoneSizThermSetPtLo = sourceData.ZoneSizThermSetPtLo;
411 82 : }
412 :
413 76 : void resetHVACSizingGlobals(EnergyPlusData &state,
414 : int const curZoneEqNum,
415 : int const curSysNum,
416 : bool &firstPassFlag) // called in zone equipment Report function
417 : {
418 : // reset Data globals so that previously set variables are not used in other equipment models
419 76 : state.dataSize->DataTotCapCurveIndex = 0;
420 76 : state.dataSize->DataPltSizCoolNum = 0;
421 76 : state.dataSize->DataPltSizHeatNum = 0;
422 76 : state.dataSize->DataWaterLoopNum = 0;
423 76 : state.dataSize->DataCoilNum = 0;
424 76 : state.dataSize->DataFanOp = HVAC::FanOp::Invalid;
425 76 : state.dataSize->DataCoilIsSuppHeater = false;
426 76 : state.dataSize->DataIsDXCoil = false;
427 76 : state.dataSize->DataAutosizable = true;
428 76 : state.dataSize->DataEMSOverrideON = false;
429 76 : state.dataSize->DataScalableSizingON = false;
430 76 : state.dataSize->DataScalableCapSizingON = false;
431 76 : state.dataSize->DataSysScalableFlowSizingON = false;
432 76 : state.dataSize->DataSysScalableCapSizingON = false;
433 76 : state.dataSize->DataDesAccountForFanHeat = true;
434 76 : state.dataSize->DataDXCoolsLowSpeedsAutozize = false;
435 :
436 76 : state.dataSize->DataDesInletWaterTemp = 0.0;
437 76 : state.dataSize->DataDesInletAirHumRat = 0.0;
438 76 : state.dataSize->DataDesInletAirTemp = 0.0;
439 76 : state.dataSize->DataDesOutletAirTemp = 0.0;
440 76 : state.dataSize->DataDesOutletAirHumRat = 0.0;
441 76 : state.dataSize->DataCoolCoilCap = 0.0;
442 76 : state.dataSize->DataFlowUsedForSizing = 0.0;
443 76 : state.dataSize->DataAirFlowUsedForSizing = 0.0;
444 76 : state.dataSize->DataWaterFlowUsedForSizing = 0.0;
445 76 : state.dataSize->DataCapacityUsedForSizing = 0.0;
446 76 : state.dataSize->DataDesignCoilCapacity = 0.0;
447 76 : state.dataSize->DataHeatSizeRatio = 1.0;
448 76 : state.dataSize->DataEMSOverride = 0.0;
449 76 : state.dataSize->DataBypassFrac = 0.0;
450 76 : state.dataSize->DataFracOfAutosizedCoolingAirflow = 1.0;
451 76 : state.dataSize->DataFracOfAutosizedHeatingAirflow = 1.0;
452 76 : state.dataSize->DataFlowPerCoolingCapacity = 0.0;
453 76 : state.dataSize->DataFlowPerHeatingCapacity = 0.0;
454 76 : state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
455 76 : state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
456 76 : state.dataSize->DataAutosizedCoolingCapacity = 0.0;
457 76 : state.dataSize->DataAutosizedHeatingCapacity = 0.0;
458 76 : state.dataSize->DataConstantUsedForSizing = 0.0;
459 76 : state.dataSize->DataFractionUsedForSizing = 0.0;
460 76 : state.dataSize->DataNonZoneNonAirloopValue = 0.0;
461 76 : state.dataSize->DataZoneNumber = 0;
462 76 : state.dataSize->DataFanType = HVAC::FanType::Invalid;
463 76 : state.dataSize->DataFanIndex = 0;
464 76 : state.dataSize->DataWaterCoilSizCoolDeltaT = 0.0;
465 76 : state.dataSize->DataWaterCoilSizHeatDeltaT = 0.0;
466 76 : state.dataSize->DataNomCapInpMeth = false;
467 76 : state.dataSize->DataFanPlacement = HVAC::FanPlace::Invalid;
468 76 : state.dataSize->DataDXSpeedNum = 0;
469 76 : state.dataSize->DataCoilSizingAirInTemp = 0.0;
470 76 : state.dataSize->DataCoilSizingAirInHumRat = 0.0;
471 76 : state.dataSize->DataCoilSizingAirOutTemp = 0.0;
472 76 : state.dataSize->DataCoilSizingAirOutHumRat = 0.0;
473 76 : state.dataSize->DataCoolCoilType = -1;
474 76 : state.dataSize->DataCoolCoilIndex = -1;
475 :
476 : // These zone specific sizing variables are set in zone equipment to use for sizing.
477 : // Reset to avoid chance that second zone equipment will size using these variables set by first zone equipment to be sized
478 76 : if (curZoneEqNum > 0) {
479 :
480 58 : if (state.dataSize->ZoneEqSizing.size() == 0) {
481 1 : firstPassFlag = false;
482 1 : return;
483 : }
484 :
485 57 : auto &ZoneEqSizing = state.dataSize->ZoneEqSizing(curZoneEqNum);
486 57 : ZoneEqSizing.AirFlow = false;
487 57 : ZoneEqSizing.CoolingAirFlow = false;
488 57 : ZoneEqSizing.HeatingAirFlow = false;
489 57 : ZoneEqSizing.SystemAirFlow = false;
490 57 : ZoneEqSizing.Capacity = false;
491 57 : ZoneEqSizing.CoolingCapacity = false;
492 57 : ZoneEqSizing.HeatingCapacity = false;
493 57 : ZoneEqSizing.AirVolFlow = 0.0;
494 57 : ZoneEqSizing.MaxHWVolFlow = 0.0;
495 57 : ZoneEqSizing.MaxCWVolFlow = 0.0;
496 57 : ZoneEqSizing.OAVolFlow = 0.0;
497 57 : ZoneEqSizing.DesCoolingLoad = 0.0;
498 57 : ZoneEqSizing.DesHeatingLoad = 0.0;
499 57 : ZoneEqSizing.CoolingAirVolFlow = 0.0;
500 57 : ZoneEqSizing.HeatingAirVolFlow = 0.0;
501 57 : ZoneEqSizing.SystemAirVolFlow = 0.0;
502 57 : ZoneEqSizing.DesignSizeFromParent = false;
503 : }
504 :
505 75 : if (curSysNum > 0) {
506 :
507 16 : if (state.dataSize->UnitarySysEqSizing.size() == 0) {
508 0 : firstPassFlag = false;
509 0 : return;
510 : }
511 :
512 16 : auto &UnitarySysEqSizing = state.dataSize->UnitarySysEqSizing(curSysNum);
513 16 : UnitarySysEqSizing.AirFlow = false;
514 16 : UnitarySysEqSizing.CoolingAirFlow = false;
515 16 : UnitarySysEqSizing.HeatingAirFlow = false;
516 16 : UnitarySysEqSizing.Capacity = false;
517 16 : UnitarySysEqSizing.CoolingCapacity = false;
518 16 : UnitarySysEqSizing.HeatingCapacity = false;
519 : }
520 :
521 75 : firstPassFlag = false;
522 : }
523 :
524 33 : void GetCoilDesFlowT(EnergyPlusData &state,
525 : int SysNum, // central air system index
526 : Real64 CpAir, // specific heat to be used in calculations [J/kgC]
527 : Real64 &DesFlow, // returned design mass flow [kg/s]
528 : Real64 &DesExitTemp, // returned design coil exit temperature [kg/s]
529 : Real64 &DesExitHumRat // returned design coil exit humidity ratio [kg/kg]
530 : )
531 : {
532 : // FUNCTION INFORMATION:
533 : // AUTHOR Fred Buhl
534 : // DATE WRITTEN September 2014
535 :
536 : // PURPOSE OF THIS FUNCTION:
537 : // This function calculates the coil design air flow rate and exit temperature depending on the
538 : // cooling capacity control method
539 :
540 : // METHODOLOGY EMPLOYED:
541 : // energy and mass flow balance
542 :
543 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
544 33 : int TimeStepAtPeak = 0;
545 33 : Real64 ZoneCoolLoadSum = 0; // sum of zone cooling loads at the peak [W]
546 33 : Real64 AvgZoneTemp = 0; // average zone temperature [C]
547 :
548 33 : auto &finalSysSizing = state.dataSize->FinalSysSizing(SysNum);
549 33 : auto &sysSizPeakDDNum = state.dataSize->SysSizPeakDDNum(SysNum);
550 33 : auto &calcSysSizing = state.dataSize->CalcSysSizing(SysNum);
551 :
552 33 : int sysSizIndex = Util::FindItemInList(finalSysSizing.AirPriLoopName, state.dataSize->SysSizInput, &SystemSizingInputData::AirPriLoopName);
553 33 : if (sysSizIndex == 0) {
554 0 : sysSizIndex = 1;
555 : }
556 33 : auto &sysSizInput = state.dataSize->SysSizInput(sysSizIndex);
557 :
558 33 : if (sysSizPeakDDNum.SensCoolPeakDD > 0) {
559 29 : if (sysSizInput.coolingPeakLoad == PeakLoad::TotalCooling) {
560 11 : TimeStepAtPeak = sysSizPeakDDNum.TimeStepAtTotCoolPk(sysSizPeakDDNum.TotCoolPeakDD);
561 : } else {
562 18 : TimeStepAtPeak = sysSizPeakDDNum.TimeStepAtSensCoolPk(sysSizPeakDDNum.SensCoolPeakDD);
563 : }
564 : } else {
565 4 : if ((sysSizInput.CoolCapControl == CapacityControl::VT) || (sysSizInput.CoolCapControl == CapacityControl::Bypass)) {
566 4 : ShowWarningError(state,
567 4 : format("GetCoilDesFlow: AirLoopHVAC = {} has no time of peak cooling load for sizing.", sysSizInput.AirPriLoopName));
568 4 : ShowContinueError(state, "Using Central Cooling Capacity Control Method=VAV instead of Bypass or VT.");
569 2 : sysSizInput.CoolCapControl = CapacityControl::VAV;
570 : }
571 : }
572 :
573 33 : if (sysSizInput.CoolCapControl == CapacityControl::VAV) {
574 15 : DesExitTemp = finalSysSizing.CoolSupTemp;
575 15 : DesFlow = finalSysSizing.MassFlowAtCoolPeak / state.dataEnvrn->StdRhoAir;
576 15 : DesExitHumRat = finalSysSizing.CoolSupHumRat;
577 18 : } else if (sysSizInput.CoolCapControl == CapacityControl::OnOff) {
578 6 : DesExitTemp = finalSysSizing.CoolSupTemp;
579 6 : DesFlow = state.dataSize->DataAirFlowUsedForSizing;
580 6 : DesExitHumRat = finalSysSizing.CoolSupHumRat;
581 12 : } else if (sysSizInput.CoolCapControl == CapacityControl::VT) {
582 6 : ZoneCoolLoadSum = calcSysSizing.SumZoneCoolLoadSeq(TimeStepAtPeak);
583 6 : AvgZoneTemp = calcSysSizing.CoolZoneAvgTempSeq(TimeStepAtPeak);
584 6 : DesExitTemp =
585 6 : max(finalSysSizing.CoolSupTemp, AvgZoneTemp - ZoneCoolLoadSum / (state.dataEnvrn->StdRhoAir * CpAir * finalSysSizing.DesCoolVolFlow));
586 6 : DesFlow = finalSysSizing.DesCoolVolFlow;
587 6 : DesExitHumRat = Psychrometrics::PsyWFnTdbRhPb(state, DesExitTemp, 0.9, state.dataEnvrn->StdBaroPress, "GetCoilDesFlowT");
588 6 : } else if (sysSizInput.CoolCapControl == CapacityControl::Bypass) {
589 6 : ZoneCoolLoadSum = calcSysSizing.SumZoneCoolLoadSeq(TimeStepAtPeak);
590 6 : AvgZoneTemp = calcSysSizing.CoolZoneAvgTempSeq(TimeStepAtPeak);
591 6 : DesExitTemp = finalSysSizing.CoolSupTemp;
592 6 : if (calcSysSizing.MixTempAtCoolPeak > DesExitTemp) {
593 5 : Real64 AvgSupTemp = AvgZoneTemp - ZoneCoolLoadSum / (state.dataEnvrn->StdRhoAir * CpAir * finalSysSizing.DesCoolVolFlow);
594 5 : DesFlow = finalSysSizing.DesCoolVolFlow *
595 5 : max(0.0, min(1.0, ((calcSysSizing.MixTempAtCoolPeak - AvgSupTemp) / (calcSysSizing.MixTempAtCoolPeak - DesExitTemp))));
596 : } else {
597 1 : DesFlow = finalSysSizing.DesCoolVolFlow;
598 : }
599 6 : DesExitHumRat = Psychrometrics::PsyWFnTdbRhPb(state, DesExitTemp, 0.9, state.dataEnvrn->StdBaroPress, "GetCoilDesFlowT");
600 : }
601 33 : }
602 :
603 746 : Real64 ZoneAirDistributionData::calculateEz(EnergyPlusData &state, int const ZoneNum) // Zone index
604 : {
605 746 : Real64 zoneEz = 1.0;
606 : // Calc the zone supplied OA flow rate counting the zone air distribution effectiveness
607 : // First check whether the zone air distribution effectiveness schedule exists, if yes uses it;
608 : // otherwise uses the inputs of zone distribution effectiveness in cooling mode or heating mode
609 746 : if (this->zoneADEffSched != nullptr) {
610 : // Get schedule value for the zone air distribution effectiveness
611 0 : zoneEz = this->zoneADEffSched->getCurrentVal();
612 : } else {
613 746 : Real64 zoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired;
614 :
615 : // Zone in cooling mode
616 746 : if (zoneLoad < 0.0) {
617 166 : zoneEz = this->ZoneADEffCooling;
618 : }
619 :
620 : // Zone in heating mode
621 746 : if (zoneLoad > 0.0) {
622 227 : zoneEz = this->ZoneADEffHeating;
623 : }
624 : }
625 746 : if (zoneEz <= 0.0) {
626 : // Enforce defaults
627 0 : zoneEz = 1.0;
628 : }
629 746 : return zoneEz;
630 : }
631 :
632 52326 : Real64 calcDesignSpecificationOutdoorAir(EnergyPlusData &state,
633 : int const DSOAPtr, // Pointer to DesignSpecification:OutdoorAir object
634 : int const ActualZoneNum, // Zone index
635 : bool const UseOccSchFlag, // Zone occupancy schedule will be used instead of using total zone occupancy
636 : bool const UseMinOASchFlag, // Use min OA schedule in DesignSpecification:OutdoorAir object
637 : bool const PerPersonNotSet, // when calculation should not include occupants (e.g., dual duct)
638 : bool const MaxOAVolFlowFlag, // TRUE when calculation uses occupancy schedule (e.g., dual duct)
639 : int const spaceNum)
640 : {
641 52326 : Real64 totOAFlowRate = 0.0;
642 52326 : if (DSOAPtr == 0) {
643 342 : return totOAFlowRate;
644 : }
645 :
646 51984 : auto &thisDSOA = state.dataSize->OARequirements(DSOAPtr);
647 :
648 51984 : if (thisDSOA.numDSOA == 0) {
649 : // This is a simple DesignSpecification:OutdoorAir
650 51983 : return thisDSOA.calcOAFlowRate(state, ActualZoneNum, UseOccSchFlag, UseMinOASchFlag, PerPersonNotSet, MaxOAVolFlowFlag, spaceNum);
651 : } else {
652 : // This is a DesignSpecification:OutdoorAir:SpaceList
653 5 : for (int dsoaCount = 1; dsoaCount <= thisDSOA.numDSOA; ++dsoaCount) {
654 4 : if ((spaceNum == 0) || ((spaceNum > 0) && (spaceNum == thisDSOA.dsoaSpaceIndexes(dsoaCount)))) {
655 4 : totOAFlowRate += state.dataSize->OARequirements(thisDSOA.dsoaIndexes(dsoaCount))
656 4 : .calcOAFlowRate(state,
657 : ActualZoneNum,
658 : UseOccSchFlag,
659 : UseMinOASchFlag,
660 : PerPersonNotSet,
661 : MaxOAVolFlowFlag,
662 4 : thisDSOA.dsoaSpaceIndexes(dsoaCount));
663 : }
664 : }
665 1 : return totOAFlowRate;
666 : }
667 : }
668 :
669 92 : Real64 OARequirementsData::desFlowPerZoneArea(EnergyPlusData &state, int const zoneNum, int const spaceNum)
670 : {
671 92 : Real64 desFlowPA = 0.0;
672 92 : if (this->numDSOA == 0) {
673 : // This is a simple DesignSpecification:OutdoorAir
674 92 : if (this->OAFlowMethod != OAFlowCalcMethod::PerPerson && this->OAFlowMethod != OAFlowCalcMethod::PerZone &&
675 34 : this->OAFlowMethod != OAFlowCalcMethod::ACH) {
676 34 : desFlowPA = this->OAFlowPerArea;
677 : }
678 : } else {
679 : // This is a DesignSpecification:OutdoorAir:SpaceList
680 0 : Real64 sumAreaOA = 0.0;
681 0 : Real64 sumArea = 0.0;
682 0 : for (int dsoaCount = 1; dsoaCount <= this->numDSOA; ++dsoaCount) {
683 0 : auto const &thisDSOA = state.dataSize->OARequirements(this->dsoaIndexes(dsoaCount));
684 0 : int const dsoaSpaceNum = this->dsoaSpaceIndexes(dsoaCount);
685 0 : if (thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerPerson && thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerZone &&
686 0 : thisDSOA.OAFlowMethod != OAFlowCalcMethod::ACH) {
687 0 : if ((spaceNum == 0) || (spaceNum == dsoaSpaceNum)) {
688 0 : Real64 spaceArea = state.dataHeatBal->space(this->dsoaSpaceIndexes(dsoaCount)).FloorArea;
689 : sumArea + -spaceArea;
690 0 : sumAreaOA += thisDSOA.OAFlowPerArea * spaceArea;
691 : }
692 : }
693 : }
694 0 : if ((spaceNum == 0) && (state.dataHeatBal->Zone(zoneNum).FloorArea)) {
695 0 : desFlowPA = sumAreaOA / state.dataHeatBal->Zone(zoneNum).FloorArea;
696 0 : } else if (sumArea > 0.0) {
697 0 : desFlowPA = sumAreaOA / sumArea;
698 : }
699 : }
700 92 : return desFlowPA;
701 : }
702 :
703 92 : Real64 OARequirementsData::desFlowPerZonePerson(EnergyPlusData &state, int const actualZoneNum, int const spaceNum)
704 : {
705 92 : Real64 desFlowPP = 0.0;
706 92 : if (this->numDSOA == 0) {
707 : // This is a simple DesignSpecification:OutdoorAir
708 92 : if (this->OAFlowMethod != OAFlowCalcMethod::PerArea && this->OAFlowMethod != OAFlowCalcMethod::PerZone &&
709 87 : this->OAFlowMethod != OAFlowCalcMethod::ACH) {
710 87 : desFlowPP = this->OAFlowPerPerson;
711 : }
712 : } else {
713 : // This is a DesignSpecification:OutdoorAir:SpaceList
714 0 : Real64 sumPeopleOA = 0.0;
715 0 : Real64 sumPeople = 0.0;
716 0 : for (int dsoaCount = 1; dsoaCount <= this->numDSOA; ++dsoaCount) {
717 0 : auto const &thisDSOA = state.dataSize->OARequirements(this->dsoaIndexes(dsoaCount));
718 0 : int const dsoaSpaceNum = this->dsoaSpaceIndexes(dsoaCount);
719 0 : if (thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerArea && thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerZone &&
720 0 : thisDSOA.OAFlowMethod != OAFlowCalcMethod::ACH) {
721 0 : if ((spaceNum == 0) || (spaceNum == dsoaSpaceNum)) {
722 0 : Real64 spacePeople = state.dataHeatBal->space(dsoaSpaceNum).TotOccupants;
723 0 : sumPeople += spacePeople;
724 0 : sumPeopleOA += thisDSOA.OAFlowPerPerson * spacePeople;
725 : }
726 : }
727 : }
728 0 : if ((spaceNum == 0) && (state.dataHeatBal->Zone(actualZoneNum).TotOccupants > 0.0)) {
729 0 : desFlowPP = sumPeopleOA / state.dataHeatBal->Zone(actualZoneNum).TotOccupants;
730 0 : } else if (sumPeople > 0.0) {
731 0 : desFlowPP = sumPeopleOA / sumPeople;
732 : }
733 : }
734 92 : return desFlowPP;
735 : }
736 :
737 51987 : Real64 OARequirementsData::calcOAFlowRate(EnergyPlusData &state,
738 : int const ActualZoneNum, // Zone index
739 : bool const UseOccSchFlag, // Zone occupancy schedule will be used instead of using total zone occupancy
740 : bool const UseMinOASchFlag, // Use min OA schedule in DesignSpecification:OutdoorAir object
741 : bool const PerPersonNotSet, // when calculation should not include occupants (e.g., dual duct)
742 : bool const MaxOAVolFlowFlag, // TRUE when calculation uses occupancy schedule (e.g., dual duct)
743 : int const spaceNum // Space index (if applicable)
744 : )
745 : {
746 :
747 : // FUNCTION INFORMATION:
748 : // AUTHOR Richard Raustad, FSEC
749 : // DATE WRITTEN October 2012
750 :
751 : // PURPOSE OF THIS FUNCTION:
752 : // This function returns the air volume flow rate based on DesignSpecification:OutdoorAir object.
753 :
754 : // METHODOLOGY EMPLOYED:
755 : // User inputs and zone index allows calculation of outdoor air quantity.
756 : // Sizing does not use occupancy or min OA schedule and will call with flags set to FALSE
757 : // Ventilation Rate Procedure uses occupancy schedule based on user input.
758 :
759 : // Return value
760 : Real64 OAVolumeFlowRate; // Return value for calculated outdoor air volume flow rate [m3/s]
761 :
762 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
763 : Real64 DSOAFlowPeople; // Outdoor air volume flow rate based on occupancy (m3/s)
764 : Real64 DSOAFlowPerZone; // Outdoor air volume flow rate (m3/s)
765 : Real64 DSOAFlowPerArea; // Outdoor air volume flow rate based on zone floor area (m3/s)
766 : Real64 DSOAFlowACH; // Outdoor air volume flow rate based on air changes per hour (m3/s)
767 : Real64 ZoneOAPeople; // Zone OA flow rate based on number of occupants [m3/s]
768 : Real64 ZoneOAArea; // Zone OA flow rate based on space floor area [m3/s]
769 : Real64 ZoneOAMin; // Minimum Zone OA flow rate when the zone is unoccupied (i.e. ZoneOAPeople = 0)
770 : // used for "ProportionalControl" System outdoor air method
771 : Real64 ZoneOAMax; // Maximum Zone OA flow rate (ZoneOAPeople + ZoneOAArea)
772 : // used for "ProportionalControl" System outdoor air method
773 : Real64 ZoneMaxCO2; // Breathing-zone CO2 concentration
774 : Real64 ZoneMinCO2; // Minimum CO2 concentration in zone
775 : Real64 ZoneContamControllerSched; // Schedule value for ZoneControl:ContaminantController
776 : Real64 CO2PeopleGeneration; // CO2 generation from people at design level
777 :
778 51987 : OAVolumeFlowRate = 0.0;
779 :
780 51987 : auto &thisZone = state.dataHeatBal->Zone(ActualZoneNum);
781 51987 : Real64 floorArea = 0.0;
782 51987 : Real64 volume = 0.0;
783 51987 : Real64 nomTotOccupants = 0.0;
784 51987 : Real64 curNumOccupants = 0.0;
785 51987 : Real64 maxOccupants = 0.0;
786 51987 : if (spaceNum > 0) {
787 25 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
788 25 : floorArea = thisSpace.FloorArea;
789 25 : volume = thisSpace.Volume;
790 25 : nomTotOccupants = thisSpace.TotOccupants;
791 25 : curNumOccupants = state.dataHeatBal->spaceIntGain(spaceNum).NOFOCC;
792 25 : maxOccupants = thisSpace.maxOccupants;
793 : } else {
794 51962 : floorArea = thisZone.FloorArea;
795 51962 : volume = thisZone.Volume;
796 51962 : nomTotOccupants = thisZone.TotOccupants;
797 51962 : curNumOccupants = state.dataHeatBal->ZoneIntGain(ActualZoneNum).NOFOCC;
798 51962 : maxOccupants = thisZone.maxOccupants;
799 : }
800 :
801 51987 : if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::IAQProcedure && this->myEnvrnFlag) {
802 0 : if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
803 0 : ShowSevereError(state,
804 0 : format("DesignSpecification:OutdoorAir=\"{}{}",
805 0 : this->Name,
806 : R"(" valid Outdoor Air Method =" IndoorAirQualityProcedure" requires CO2 simulation.)"));
807 0 : ShowContinueError(state, "The choice must be Yes for the field Carbon Dioxide Concentration in ZoneAirContaminantBalance");
808 0 : ShowFatalError(state, "CalcDesignSpecificationOutdoorAir: Errors found in input. Preceding condition(s) cause termination.");
809 : }
810 0 : this->myEnvrnFlag = false;
811 : }
812 51987 : if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCOccSch && this->myEnvrnFlag) {
813 1 : if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
814 0 : ShowSevereError(state,
815 0 : format("DesignSpecification:OutdoorAir=\"{}{}",
816 0 : this->Name,
817 : R"(" valid Outdoor Air Method =" ProportionalControlBasedOnDesignOccupancy" requires CO2 simulation.)"));
818 0 : ShowContinueError(state, "The choice must be Yes for the field Carbon Dioxide Concentration in ZoneAirContaminantBalance");
819 0 : ShowFatalError(state, "CalcDesignSpecificationOutdoorAir: Errors found in input. Preceding condition(s) cause termination.");
820 : }
821 1 : this->myEnvrnFlag = false;
822 : }
823 51987 : if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc && this->myEnvrnFlag) {
824 0 : if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
825 0 : ShowSevereError(state,
826 0 : format("DesignSpecification:OutdoorAir=\"{}{}",
827 0 : this->Name,
828 : R"(" valid Outdoor Air Method =" ProportionalControlBasedOnOccupancySchedule" requires CO2 simulation.)"));
829 0 : ShowContinueError(state, "The choice must be Yes for the field Carbon Dioxide Concentration in ZoneAirContaminantBalance");
830 0 : ShowFatalError(state, "CalcDesignSpecificationOutdoorAir: Errors found in input. Preceding condition(s) cause termination.");
831 : }
832 0 : this->myEnvrnFlag = false;
833 : }
834 :
835 : // Calculate people outdoor air flow rate as needed
836 51987 : switch (this->OAFlowMethod) {
837 50745 : case OAFlowCalcMethod::PerPerson:
838 : case OAFlowCalcMethod::Sum:
839 : case OAFlowCalcMethod::Max: {
840 50745 : if (UseOccSchFlag) {
841 50646 : if (MaxOAVolFlowFlag) {
842 : // OAPerPersonMode == PerPersonDCVByCurrentLevel (UseOccSchFlag = TRUE)
843 : // for dual duct, get max people according to max schedule value when requesting MaxOAFlow
844 0 : DSOAFlowPeople = maxOccupants * this->OAFlowPerPerson;
845 : } else {
846 50646 : DSOAFlowPeople = curNumOccupants * this->OAFlowPerPerson;
847 : }
848 : } else {
849 99 : if (MaxOAVolFlowFlag) {
850 : // OAPerPersonMode == PerPersonByDesignLevel (UseOccSchFlag = FALSE)
851 : // use total people when requesting MaxOAFlow
852 0 : DSOAFlowPeople = nomTotOccupants * this->OAFlowPerPerson;
853 : } else {
854 99 : DSOAFlowPeople = nomTotOccupants * this->OAFlowPerPerson;
855 : }
856 : }
857 50745 : if (PerPersonNotSet) {
858 1 : DSOAFlowPeople = 0.0; // for Dual Duct if Per Person Ventilation Rate Mode is not entered
859 : }
860 50745 : } break;
861 1242 : default: {
862 1242 : DSOAFlowPeople = 0.0;
863 1242 : } break;
864 : }
865 :
866 : // Calculate minimum outdoor air flow rate
867 51987 : switch (this->OAFlowMethod) {
868 46723 : case OAFlowCalcMethod::PerPerson: {
869 : // Multiplied by occupancy
870 46723 : OAVolumeFlowRate = DSOAFlowPeople;
871 46723 : } break;
872 1236 : case OAFlowCalcMethod::PerZone: {
873 : // User input
874 1236 : OAVolumeFlowRate = this->OAFlowPerZone;
875 1236 : } break;
876 1 : case OAFlowCalcMethod::PerArea: {
877 : // Multiplied by zone floor area
878 1 : OAVolumeFlowRate = this->OAFlowPerArea * floorArea;
879 1 : } break;
880 1 : case OAFlowCalcMethod::ACH: {
881 : // Multiplied by zone volume
882 1 : OAVolumeFlowRate = this->OAFlowACH * volume / 3600.0;
883 1 : } break;
884 4022 : case OAFlowCalcMethod::Sum:
885 : case OAFlowCalcMethod::Max: {
886 : // Use sum or max of per person and the following
887 4022 : DSOAFlowPerZone = this->OAFlowPerZone;
888 4022 : DSOAFlowPerArea = this->OAFlowPerArea * floorArea;
889 4022 : DSOAFlowACH = this->OAFlowACH * volume / 3600.0;
890 4022 : if (this->OAFlowMethod == OAFlowCalcMethod::Max) {
891 0 : OAVolumeFlowRate = max(DSOAFlowPeople, DSOAFlowPerZone, DSOAFlowPerArea, DSOAFlowACH);
892 : } else {
893 4022 : OAVolumeFlowRate = DSOAFlowPeople + DSOAFlowPerZone + DSOAFlowPerArea + DSOAFlowACH;
894 : }
895 4022 : } break;
896 1 : case DataSizing::OAFlowCalcMethod::IAQProcedure: {
897 1 : if (state.dataGlobal->DoingSizing) {
898 0 : DSOAFlowPeople = nomTotOccupants * this->OAFlowPerPerson;
899 0 : DSOAFlowPerZone = this->OAFlowPerZone;
900 0 : DSOAFlowPerArea = this->OAFlowPerArea * floorArea;
901 0 : DSOAFlowACH = this->OAFlowACH * volume / 3600.0;
902 0 : OAVolumeFlowRate = DSOAFlowPeople + DSOAFlowPerZone + DSOAFlowPerArea + DSOAFlowACH;
903 : } else {
904 1 : OAVolumeFlowRate = state.dataContaminantBalance->ZoneSysContDemand(ActualZoneNum).OutputRequiredToCO2SP / state.dataEnvrn->StdRhoAir;
905 : }
906 1 : } break;
907 3 : case DataSizing::OAFlowCalcMethod::PCOccSch:
908 : case DataSizing::OAFlowCalcMethod::PCDesOcc: {
909 3 : ZoneOAPeople = 0.0;
910 3 : if (this->OAFlowMethod != DataSizing::OAFlowCalcMethod::PCDesOcc) {
911 2 : ZoneOAPeople = curNumOccupants * thisZone.Multiplier * thisZone.ListMultiplier * this->OAFlowPerPerson;
912 : } else {
913 1 : ZoneOAPeople = nomTotOccupants * thisZone.Multiplier * thisZone.ListMultiplier * this->OAFlowPerPerson;
914 1 : CO2PeopleGeneration = 0.0;
915 1 : if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc) {
916 : // Accumulate CO2 generation from people at design occupancy and current activity level
917 2 : for (int PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) {
918 1 : if (spaceNum > 0) {
919 0 : if (state.dataHeatBal->People(PeopleNum).spaceIndex != spaceNum) {
920 0 : continue;
921 : }
922 : } else {
923 1 : if (state.dataHeatBal->People(PeopleNum).ZonePtr != ActualZoneNum) {
924 0 : continue;
925 : }
926 : }
927 2 : CO2PeopleGeneration += state.dataHeatBal->People(PeopleNum).NumberOfPeople * state.dataHeatBal->People(PeopleNum).CO2RateFactor *
928 1 : state.dataHeatBal->People(PeopleNum).activityLevelSched->getCurrentVal();
929 : }
930 : }
931 : }
932 3 : ZoneOAArea = floorArea * thisZone.Multiplier * thisZone.ListMultiplier * this->OAFlowPerArea;
933 3 : ZoneOAMin = ZoneOAArea;
934 3 : ZoneOAMax = (ZoneOAArea + ZoneOAPeople);
935 3 : if (thisZone.zoneContamControllerSched != nullptr) {
936 : // Check the availability schedule value for ZoneControl:ContaminantController
937 3 : ZoneContamControllerSched = thisZone.zoneContamControllerSched->getCurrentVal();
938 3 : if (ZoneContamControllerSched > 0.0) {
939 3 : if (ZoneOAPeople > 0.0) {
940 3 : if (state.dataContaminantBalance->ZoneCO2GainFromPeople(ActualZoneNum) > 0.0) {
941 3 : if (thisZone.zoneMinCO2Sched != nullptr) {
942 : // Take the schedule value of "Minimum Carbon Dioxide Concentration Schedule Name"
943 : // in the ZoneControl:ContaminantController
944 0 : ZoneMinCO2 = thisZone.zoneMinCO2Sched->getCurrentVal();
945 : } else {
946 3 : ZoneMinCO2 = state.dataContaminantBalance->OutdoorCO2;
947 : }
948 :
949 : // Calculate zone maximum target CO2 concentration in PPM
950 3 : if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc) {
951 1 : ZoneMaxCO2 = state.dataContaminantBalance->OutdoorCO2 +
952 1 : (CO2PeopleGeneration * thisZone.Multiplier * thisZone.ListMultiplier * 1.0e6) / ZoneOAMax;
953 : } else {
954 2 : ZoneMaxCO2 =
955 2 : state.dataContaminantBalance->OutdoorCO2 + (state.dataContaminantBalance->ZoneCO2GainFromPeople(ActualZoneNum) *
956 2 : thisZone.Multiplier * thisZone.ListMultiplier * 1.0e6) /
957 : ZoneOAMax;
958 : }
959 :
960 3 : if (ZoneMaxCO2 <= ZoneMinCO2) {
961 0 : ++this->CO2MaxMinLimitErrorCount;
962 0 : if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCOccSch) {
963 0 : if (this->CO2MaxMinLimitErrorCount < 2) {
964 0 : ShowSevereError(state,
965 0 : format("CalcDesignSpecificationOutdoorAir DesignSpecification:OutdoorAir = \"{}\".", this->Name));
966 0 : ShowContinueError(
967 : state,
968 0 : format("For System Outdoor Air Method = ProportionalControlBasedOnOccupancySchedule, maximum target "
969 : "CO2 concentration ({:.2R}), is not greater than minimum target CO2 concentration ({:.2R}).",
970 : ZoneMaxCO2,
971 : ZoneMinCO2));
972 0 : ShowContinueError(state,
973 : "\"ProportionalControlBasedOnOccupancySchedule\" will not be modeled. "
974 : "Default \"Flow/Person+Flow/Area\" will be modeled. Simulation continues...");
975 0 : ShowContinueErrorTimeStamp(state, "");
976 : } else {
977 0 : ShowRecurringWarningErrorAtEnd(
978 : state,
979 0 : format("DesignSpecification:OutdoorAir = \"{}\", For System Outdoor Air Method = "
980 : "ProportionalControlBasedOnOccupancySchedule, maximum target CO2 concentration is not greater than "
981 : "minimum target CO2 concentration. Error continues...",
982 0 : this->Name),
983 0 : this->CO2MaxMinLimitErrorIndex);
984 : }
985 : }
986 0 : if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc) {
987 0 : if (this->CO2MaxMinLimitErrorCount < 2) {
988 0 : ShowSevereError(state,
989 0 : format("CalcDesignSpecificationOutdoorAir DesignSpecification:OutdoorAir = \"{}\".", this->Name));
990 0 : ShowContinueError(
991 : state,
992 0 : format("For System Outdoor Air Method = ProportionalControlBasedOnDesignOccupancy, maximum target "
993 : "CO2 concentration ({:.2R}), is not greater than minimum target CO2 concentration ({:.2R}).",
994 : ZoneMaxCO2,
995 : ZoneMinCO2));
996 0 : ShowContinueError(state,
997 : "\"ProportionalControlBasedOnDesignOccupancy\" will not be modeled. "
998 : "Default \"Flow/Person+Flow/Area\" will be modeled. Simulation continues...");
999 0 : ShowContinueErrorTimeStamp(state, "");
1000 : } else {
1001 0 : ShowRecurringWarningErrorAtEnd(
1002 : state,
1003 0 : format("DesignSpecification:OutdoorAir = \"{}\", For System Outdoor Air Method = "
1004 : "ProportionalControlBasedOnDesignOccupancy, maximum target CO2 concentration is not greater than "
1005 : "minimum target CO2 concentration. Error continues...",
1006 0 : this->Name),
1007 0 : this->CO2MaxMinLimitErrorIndex);
1008 : }
1009 : }
1010 :
1011 0 : OAVolumeFlowRate = ZoneOAMax;
1012 : } else {
1013 :
1014 3 : if (state.dataContaminantBalance->ZoneAirCO2(ActualZoneNum) <= ZoneMinCO2) {
1015 : // Zone air CO2 concentration is less than minimum zone CO2 concentration, set the Zone OA flow rate to
1016 : // minimum Zone OA flow rate when the zone is unoccupied
1017 0 : OAVolumeFlowRate = ZoneOAMin;
1018 3 : } else if (state.dataContaminantBalance->ZoneAirCO2(ActualZoneNum) >= ZoneMaxCO2) {
1019 : // Zone air CO2 concentration is greater than maximum zone CO2 concentration, set the Zone OA flow rate to
1020 : // maximum Zone OA flow rate (i.e. ZoneOAArea + ZoneOAPeople)
1021 1 : OAVolumeFlowRate = ZoneOAMax;
1022 : } else {
1023 : // Zone air CO2 concentration is between maximum and minimum limits of zone CO2 concentration,
1024 : // set Zone OA flow rate by proportionally adjusting between ZoneOAMin and ZoneOAMax
1025 2 : OAVolumeFlowRate =
1026 2 : ZoneOAMin + (ZoneOAMax - ZoneOAMin) * ((state.dataContaminantBalance->ZoneAirCO2(ActualZoneNum) - ZoneMinCO2) /
1027 2 : (ZoneMaxCO2 - ZoneMinCO2));
1028 : }
1029 : }
1030 : } else {
1031 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1032 0 : ++this->CO2GainErrorCount;
1033 0 : if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCOccSch) {
1034 0 : if (this->CO2GainErrorCount < 2) {
1035 0 : ShowSevereError(state,
1036 0 : format("CalcDesignSpecificationOutdoorAir DesignSpecification:OutdoorAir = \"{}\".", this->Name));
1037 0 : ShowContinueError(state,
1038 0 : format("For System Outdoor Air Method = ProportionalControlBasedOnOccupancySchedule, CO2 "
1039 : "generation from people is not greater than zero. Occurs in Zone =\"{}\". ",
1040 0 : thisZone.Name));
1041 0 : ShowContinueError(state,
1042 : "\"ProportionalControlBasedOnOccupancySchedule\" will not be modeled. "
1043 : "Default \"Flow/Person+Flow/Area\" will be modeled. Simulation continues...");
1044 0 : ShowContinueErrorTimeStamp(state, "");
1045 : } else {
1046 0 : ShowRecurringWarningErrorAtEnd(state,
1047 0 : format("DesignSpecification:OutdoorAir = \"{}\", For System Outdoor Air Method = "
1048 : "ProportionalControlBasedOnOccupancySchedule, CO2 generation from people "
1049 : "is not greater than zero. Error continues...",
1050 0 : this->Name),
1051 0 : this->CO2GainErrorIndex);
1052 : }
1053 : }
1054 0 : if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc) {
1055 0 : if (this->CO2GainErrorCount < 2) {
1056 0 : ShowSevereError(state,
1057 0 : format("CalcDesignSpecificationOutdoorAir DesignSpecification:OutdoorAir = \"{}\".", this->Name));
1058 0 : ShowContinueError(state,
1059 0 : format("For System Outdoor Air Method = ProportionalControlBasedOnDesignOccupancy, CO2 "
1060 : "generation from people is not greater than zero. Occurs in Zone =\"{}\". ",
1061 0 : thisZone.Name));
1062 0 : ShowContinueError(state,
1063 : "\"ProportionalControlBasedOnDesignOccupancy\" will not be modeled. "
1064 : "Default \"Flow/Person+Flow/Area\" will be modeled. Simulation continues...");
1065 0 : ShowContinueErrorTimeStamp(state, "");
1066 : } else {
1067 0 : ShowRecurringWarningErrorAtEnd(state,
1068 0 : format("DesignSpecification:OutdoorAir = \"{}\", For System Outdoor Air Method = "
1069 : "ProportionalControlBasedOnDesignOccupancy, CO2 generation from people is "
1070 : "not greater than zero. Error continues...",
1071 0 : this->Name),
1072 0 : this->CO2GainErrorIndex);
1073 : }
1074 : }
1075 : }
1076 0 : OAVolumeFlowRate = ZoneOAMax;
1077 : }
1078 : } else {
1079 : // ZoneOAPeople is less than or equal to zero
1080 0 : OAVolumeFlowRate = ZoneOAMax;
1081 : }
1082 : } else {
1083 : // ZoneControl:ContaminantController is scheduled off (not available)
1084 0 : OAVolumeFlowRate = ZoneOAMax;
1085 : }
1086 : } else {
1087 : // "Carbon Dioxide Control Availability Schedule" for ZoneControl:ContaminantController not found
1088 0 : OAVolumeFlowRate = ZoneOAMax;
1089 : }
1090 3 : } break;
1091 0 : default: {
1092 : // Will never get here
1093 0 : OAVolumeFlowRate = 0.0;
1094 0 : } break;
1095 : }
1096 :
1097 : // Apply zone multipliers and zone list multipliers
1098 : // TODO MJW: this looks like it's double-counting the multipliers
1099 51987 : OAVolumeFlowRate *= thisZone.Multiplier * thisZone.ListMultiplier;
1100 :
1101 : // Apply schedule as needed. Sizing does not use schedule.
1102 51987 : if (this->oaFlowFracSched != nullptr && UseMinOASchFlag) {
1103 51868 : if (MaxOAVolFlowFlag) {
1104 0 : OAVolumeFlowRate *= this->oaFlowFracSched->getMaxVal(state);
1105 : } else {
1106 51868 : OAVolumeFlowRate *= this->oaFlowFracSched->getCurrentVal();
1107 : }
1108 : }
1109 :
1110 51987 : return OAVolumeFlowRate;
1111 : }
1112 :
1113 : } // namespace EnergyPlus::DataSizing
|