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 : // C++ Headers
49 : #include <algorithm>
50 : #include <cassert>
51 : #include <cmath>
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Array.functions.hh>
54 : #include <ObjexxFCL/Array1D.hh>
55 : #include <ObjexxFCL/Array2D.hh>
56 : #include <ObjexxFCL/Fmath.hh>
57 : #include <ObjexxFCL/string.functions.hh>
58 :
59 : // EnergyPlus Headers
60 : #include <AirflowNetwork/Solver.hpp>
61 : #include <EnergyPlus/ChilledCeilingPanelSimple.hh>
62 : #include <EnergyPlus/Construction.hh>
63 : #include <EnergyPlus/ConvectionCoefficients.hh>
64 : #include <EnergyPlus/CurveManager.hh>
65 : #include <EnergyPlus/Data/EnergyPlusData.hh>
66 : #include <EnergyPlus/DataContaminantBalance.hh>
67 : #include <EnergyPlus/DataDaylighting.hh>
68 : #include <EnergyPlus/DataDaylightingDevices.hh>
69 : #include <EnergyPlus/DataEnvironment.hh>
70 : #include <EnergyPlus/DataHeatBalFanSys.hh>
71 : #include <EnergyPlus/DataHeatBalSurface.hh>
72 : #include <EnergyPlus/DataHeatBalance.hh>
73 : #include <EnergyPlus/DataLoopNode.hh>
74 : #include <EnergyPlus/DataMoistureBalance.hh>
75 : #include <EnergyPlus/DataMoistureBalanceEMPD.hh>
76 : #include <EnergyPlus/DataRoomAirModel.hh>
77 : #include <EnergyPlus/DataRuntimeLanguage.hh>
78 : #include <EnergyPlus/DataSizing.hh>
79 : #include <EnergyPlus/DataSurfaces.hh>
80 : #include <EnergyPlus/DataSystemVariables.hh>
81 : #include <EnergyPlus/DataViewFactorInformation.hh>
82 : #include <EnergyPlus/DataWindowEquivalentLayer.hh>
83 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
84 : #include <EnergyPlus/DataZoneEquipment.hh>
85 : #include <EnergyPlus/DaylightingDevices.hh>
86 : #include <EnergyPlus/DaylightingManager.hh>
87 : #include <EnergyPlus/DisplayRoutines.hh>
88 : #include <EnergyPlus/EcoRoofManager.hh>
89 : #include <EnergyPlus/ElectricBaseboardRadiator.hh>
90 : #include <EnergyPlus/ExtendedHeatIndex.hh>
91 : #include <EnergyPlus/FileSystem.hh>
92 : #include <EnergyPlus/HWBaseboardRadiator.hh>
93 : #include <EnergyPlus/HeatBalFiniteDiffManager.hh>
94 : #include <EnergyPlus/HeatBalanceAirManager.hh>
95 : #include <EnergyPlus/HeatBalanceHAMTManager.hh>
96 : #include <EnergyPlus/HeatBalanceIntRadExchange.hh>
97 : #include <EnergyPlus/HeatBalanceKivaManager.hh>
98 : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
99 : #include <EnergyPlus/HighTempRadiantSystem.hh>
100 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
101 : #include <EnergyPlus/InternalHeatGains.hh>
102 : #include <EnergyPlus/LowTempRadiantSystem.hh>
103 : #include <EnergyPlus/MoistureBalanceEMPDManager.hh>
104 : #include <EnergyPlus/OutputProcessor.hh>
105 : #include <EnergyPlus/OutputReportPredefined.hh>
106 : #include <EnergyPlus/OutputReportTabular.hh>
107 : #include <EnergyPlus/Psychrometrics.hh>
108 : #include <EnergyPlus/ScheduleManager.hh>
109 : #include <EnergyPlus/SolarShading.hh>
110 : #include <EnergyPlus/SteamBaseboardRadiator.hh>
111 : #include <EnergyPlus/SurfaceGeometry.hh>
112 : #include <EnergyPlus/SwimmingPool.hh>
113 : #include <EnergyPlus/ThermalComfort.hh>
114 : #include <EnergyPlus/TranspiredCollector.hh>
115 : #include <EnergyPlus/UtilityRoutines.hh>
116 : #include <EnergyPlus/WindowComplexManager.hh>
117 : #include <EnergyPlus/WindowEquivalentLayer.hh>
118 : #include <EnergyPlus/WindowManager.hh>
119 : #include <EnergyPlus/WindowManagerExteriorData.hh>
120 : #include <EnergyPlus/WindowManagerExteriorThermal.hh>
121 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
122 : #include <WCECommon.hpp>
123 : #include <WCEMultiLayerOptics.hpp>
124 : #include <WCESingleLayerOptics.hpp>
125 : #include <WCETarcog.hpp>
126 :
127 : namespace EnergyPlus::HeatBalanceSurfaceManager {
128 :
129 : // Module containing the routines dealing with the Heat Balance of the surfaces
130 :
131 : // MODULE INFORMATION:
132 : // MODIFIED DJS (PSU Dec 2006) to add ecoroof
133 :
134 : // PURPOSE OF THIS MODULE:
135 : // To encapsulate the data and algorithms required to
136 : // manage the simulation of the surface heat balance for the building.
137 :
138 : // REFERENCES:
139 : // The heat balance method is outlined in the "TARP Reference Manual", NIST, NBSIR 83-2655, Feb 1983.
140 : // The methods are also summarized in many BSO Theses and papers.
141 :
142 : // OTHER NOTES:
143 : // This module was created from IBLAST subroutines
144 :
145 2828212 : void ManageSurfaceHeatBalance(EnergyPlusData &state)
146 : {
147 :
148 : // SUBROUTINE INFORMATION:
149 : // AUTHOR Richard Liesen
150 : // DATE WRITTEN January 1998
151 :
152 : // PURPOSE OF THIS SUBROUTINE:
153 : // This subroutine manages the heat surface balance method of calculating
154 : // building thermal loads. It is called from the HeatBalanceManager
155 : // at the time step level. This driver manages the calls to all of
156 : // the other drivers and simulation algorithms.
157 :
158 2828212 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
159 801 : DisplayString(state, "Initializing Surfaces");
160 : }
161 2828212 : InitSurfaceHeatBalance(state); // Initialize all heat balance related parameters
162 :
163 : // Solve the zone heat balance 'Detailed' solution
164 : // Call the outside and inside surface heat balances
165 2828212 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
166 801 : DisplayString(state, "Calculate Outside Surface Heat Balance");
167 : }
168 2828212 : CalcHeatBalanceOutsideSurf(state);
169 2828212 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
170 801 : DisplayString(state, "Calculate Inside Surface Heat Balance");
171 : }
172 2828212 : CalcHeatBalanceInsideSurf(state);
173 :
174 : // The air heat balance must be called before the temperature history
175 : // updates because there may be a radiant system in the building
176 2828212 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
177 801 : DisplayString(state, "Calculate Air Heat Balance");
178 : }
179 2828212 : HeatBalanceAirManager::ManageAirHeatBalance(state);
180 :
181 : // IF NECESSARY, do one final "average" heat balance pass. This is only
182 : // necessary if a radiant system is present and it was actually on for
183 : // part or all of the time step.
184 2828212 : UpdateFinalSurfaceHeatBalance(state);
185 :
186 : // Before we leave the Surface Manager the thermal histories need to be updated
187 2828212 : if (state.dataHeatBal->AnyCTF || state.dataHeatBal->AnyEMPD) {
188 2652853 : UpdateThermalHistories(state); // Update the thermal histories
189 : }
190 :
191 2828212 : if (state.dataHeatBal->AnyCondFD) {
192 1930572 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
193 1772040 : auto const &surface = state.dataSurface->Surface(SurfNum);
194 1772040 : int const ConstrNum = surface.Construction;
195 1772040 : if (ConstrNum <= 0) {
196 0 : continue; // Shading surface, not really a heat transfer surface
197 : }
198 1772040 : if (state.dataConstruction->Construct(ConstrNum).TypeIsWindow) {
199 67284 : continue; // Windows simulated in Window module
200 : }
201 1704756 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CondFD) {
202 50430 : continue;
203 : }
204 1654326 : state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).UpdateMoistureBalance();
205 : }
206 : }
207 :
208 2828212 : ThermalComfort::ManageThermalComfort(state, false); // "Record keeping" for the zone
209 :
210 2828212 : ReportSurfaceHeatBalance(state);
211 2828212 : if (state.dataGlobal->ZoneSizingCalc) {
212 830322 : OutputReportTabular::GatherComponentLoadsSurface(state);
213 : }
214 :
215 2828212 : CalcThermalResilience(state);
216 :
217 2828212 : if (state.dataOutRptTab->displayThermalResilienceSummary) {
218 1093515 : ReportThermalResilience(state);
219 : }
220 :
221 2828212 : if (state.dataOutRptTab->displayCO2ResilienceSummary) {
222 19097 : ReportCO2Resilience(state);
223 : }
224 :
225 2828212 : if (state.dataOutRptTab->displayVisualResilienceSummary) {
226 93264 : ReportVisualResilience(state);
227 : }
228 :
229 2828212 : state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime = false;
230 2828212 : }
231 :
232 : // Beginning Initialization Section of the Module
233 : //******************************************************************************
234 :
235 2828408 : void UpdateVariableAbsorptances(EnergyPlusData &state)
236 : {
237 2828408 : auto &s_mat = state.dataMaterial;
238 2832257 : for (int surfNum : state.dataSurface->AllVaryAbsOpaqSurfaceList) {
239 3849 : auto const &thisConstruct = state.dataConstruction->Construct(state.dataSurface->Surface(surfNum).Construction);
240 3849 : auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
241 3849 : assert(thisMaterial != nullptr);
242 3849 : if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::Scheduled) {
243 0 : if (thisMaterial->absorpThermalVarSched != nullptr) {
244 0 : state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
245 : }
246 0 : if (thisMaterial->absorpSolarVarSched != nullptr) {
247 0 : state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
248 : }
249 : } else {
250 : Real64 triggerValue;
251 3849 : if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceTemperature) {
252 3849 : triggerValue = state.dataHeatBalSurf->SurfTempOut(surfNum);
253 0 : } else if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceReceivedSolarRadiation) {
254 0 : triggerValue = state.dataHeatBal->SurfQRadSWOutIncident(surfNum);
255 : } else { // controlled by heating cooling mode
256 0 : int zoneNum = state.dataSurface->Surface(surfNum).Zone;
257 0 : bool isCooling = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).TotalOutputRequired < 0);
258 0 : triggerValue = static_cast<Real64>(isCooling);
259 : }
260 3849 : if (thisMaterial->absorpThermalVarCurve != nullptr) {
261 3849 : state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) =
262 3849 : max(min(thisMaterial->absorpThermalVarCurve->value(state, triggerValue), 0.9999), 0.0001);
263 : }
264 3849 : if (thisMaterial->absorpSolarVarCurve != nullptr) {
265 3849 : state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) =
266 3849 : max(min(thisMaterial->absorpSolarVarCurve->value(state, triggerValue), 0.9999), 0.0001);
267 : }
268 : }
269 2828408 : }
270 2828408 : }
271 :
272 2828408 : void InitSurfaceHeatBalance(EnergyPlusData &state)
273 : {
274 :
275 : // SUBROUTINE INFORMATION:
276 : // AUTHOR Richard J. Liesen
277 : // DATE WRITTEN January 1998
278 : // MODIFIED Nov. 1999, FCW,
279 : // Move ComputeIntThermalAbsorpFactors
280 : // so called every timestep
281 : // MODIFIED Aug. 2017
282 : // Add initializations of surface data to linked air node value if defined
283 :
284 : // PURPOSE OF THIS SUBROUTINE:
285 : // This subroutine is for surface initializations within the
286 : // heat balance.
287 :
288 : // METHODOLOGY EMPLOYED:
289 : // Uses the status flags to trigger record keeping events.
290 :
291 : // // Using/Aliasing
292 : // using namespace SolarShading;
293 : // using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
294 : // using HeatBalFiniteDiffManager::InitHeatBalFiniteDiff;
295 : // using InternalHeatGains::ManageInternalHeatGains;
296 : //
297 : // auto &Surface = state.dataSurface->Surface;
298 : //
299 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
300 801 : DisplayString(state, "Initializing Outdoor environment for Surfaces");
301 : }
302 :
303 : // set zone level wind dir to global value
304 : // Initialize zone outdoor environmental variables
305 : // Bulk Initialization for Temperatures & WindSpeed
306 : // using the zone, modify the zone Dry/Wet BulbTemps
307 :
308 : // Initialize surface outdoor environmental variables
309 : // Bulk Initialization for Temperatures & WindSpeed
310 : // using the surface centroids, modify the surface Dry/Wet BulbTemps
311 2828408 : DataSurfaces::SetSurfaceOutBulbTempAt(state);
312 2828408 : DataSurfaces::CheckSurfaceOutBulbTempAt(state);
313 :
314 2828408 : DataSurfaces::SetSurfaceWindSpeedAt(state);
315 2828408 : DataSurfaces::SetSurfaceWindDirAt(state);
316 2828408 : if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
317 620862 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
318 613426 : if (state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode > 0) {
319 2706 : auto const &linkedNode = state.dataLoopNodes->Node(state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode);
320 2706 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) = linkedNode.OutAirDryBulb;
321 2706 : state.dataSurface->SurfOutWetBulbTemp(SurfNum) = linkedNode.OutAirWetBulb;
322 2706 : state.dataSurface->SurfOutWindSpeed(SurfNum) = linkedNode.OutAirWindSpeed;
323 2706 : state.dataSurface->SurfOutWindDir(SurfNum) = linkedNode.OutAirWindDir;
324 : }
325 : }
326 : }
327 : // Overwriting surface and zone level environmental data with EMS override value
328 2828408 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
329 46480807 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
330 46059363 : if (state.dataSurface->SurfOutDryBulbTempEMSOverrideOn(SurfNum)) {
331 0 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) = state.dataSurface->SurfOutDryBulbTempEMSOverrideValue(SurfNum);
332 : }
333 46059363 : if (state.dataSurface->SurfOutWetBulbTempEMSOverrideOn(SurfNum)) {
334 0 : state.dataSurface->SurfOutWetBulbTemp(SurfNum) = state.dataSurface->SurfOutWetBulbTempEMSOverrideValue(SurfNum);
335 : }
336 46059363 : if (state.dataSurface->SurfWindSpeedEMSOverrideOn(SurfNum)) {
337 0 : state.dataSurface->SurfOutWindSpeed(SurfNum) = state.dataSurface->SurfWindSpeedEMSOverrideValue(SurfNum);
338 : }
339 46059363 : if (state.dataSurface->SurfWindDirEMSOverrideOn(SurfNum)) {
340 0 : state.dataSurface->SurfOutWindDir(SurfNum) = state.dataSurface->SurfWindDirEMSOverrideValue(SurfNum);
341 : }
342 46059363 : if (state.dataSurface->SurfViewFactorGroundEMSOverrideOn(SurfNum)) {
343 0 : state.dataSurface->Surface(SurfNum).ViewFactorGround = state.dataSurface->SurfViewFactorGroundEMSOverrideValue(SurfNum);
344 : }
345 : }
346 : }
347 :
348 : // Do the Begin Simulation initializations
349 2828408 : if (state.dataGlobal->BeginSimFlag) {
350 801 : AllocateSurfaceHeatBalArrays(state); // Allocate the Module Arrays before any inits take place
351 1602 : state.dataHeatBalSurf->InterZoneWindow =
352 801 : std::any_of(state.dataViewFactor->EnclSolInfo.begin(),
353 1602 : state.dataViewFactor->EnclSolInfo.end(),
354 5192 : [](DataViewFactorInformation::EnclosureViewFactorInformation const &e) { return e.HasInterZoneWindow; });
355 : }
356 2828408 : if (state.dataGlobal->BeginSimFlag || state.dataGlobal->AnySurfPropOverridesInModel) {
357 6002 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
358 10414 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
359 5213 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
360 5213 : int const firstSurf = thisSpace.HTSurfaceFirst;
361 5213 : int const lastSurf = thisSpace.HTSurfaceLast;
362 50795 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
363 45582 : int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // SurfActiveConstruction set above
364 45582 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
365 45582 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
366 45582 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
367 45582 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisConstruct.OutsideRoughness;
368 45582 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisConstruct.OutsideAbsorpSolar;
369 45582 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisConstruct.OutsideAbsorpThermal;
370 : }
371 5201 : }
372 : }
373 : }
374 :
375 : // variable thermal solar absorptance overrides
376 2828408 : UpdateVariableAbsorptances(state);
377 :
378 : // Do the Begin Environment initializations
379 2828408 : if (state.dataGlobal->BeginEnvrnFlag) {
380 6496 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
381 801 : DisplayString(state, "Initializing Temperature and Flux Histories");
382 : }
383 6496 : InitThermalAndFluxHistories(state); // Set initial temperature and flux histories
384 : }
385 :
386 : // Calc movable insulation properties
387 2828408 : if (state.dataSurface->AnyMovableInsulation) {
388 10122 : EvalOutsideMovableInsulation(state);
389 10122 : EvalInsideMovableInsulation(state);
390 : }
391 :
392 : // There are no daily initializations done in this portion of the surface heat balance
393 : // There are no hourly initializations done in this portion of the surface heat balance
394 :
395 2828408 : GetGroundSurfacesReflectanceAverage(state);
396 :
397 : // Need to be called each timestep in order to check if surface points to new construction (EMS) and if does then
398 : // complex fenestration needs to be initialized for additional states
399 2828408 : SolarShading::TimestepInitComplexFenestration(state);
400 :
401 : // Calculate exterior-surface multipliers that account for anisotropy of
402 : // sky radiance
403 2828408 : if (state.dataEnvrn->SunIsUp && state.dataEnvrn->DifSolarRad > 0.0) {
404 925351 : SolarShading::AnisoSkyViewFactors(state);
405 : } else {
406 1903057 : state.dataSolarShading->SurfAnisoSkyMult = 0.0;
407 : }
408 :
409 : // Set shading flag for exterior windows (except flags related to daylighting) and
410 : // window construction (unshaded or shaded) to be used in heat balance calculation
411 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
412 801 : DisplayString(state, "Initializing Window Shading");
413 : }
414 :
415 2828408 : SolarShading::WindowShadingManager(state);
416 :
417 2828408 : SolarShading::CheckGlazingShadingStatusChange(state);
418 :
419 : // Calculate factors that are used to determine how much long-wave radiation from internal
420 : // gains is absorbed by interior surfaces
421 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
422 801 : DisplayString(state, "Computing Interior Absorption Factors");
423 : }
424 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
425 801 : HeatBalanceIntRadExchange::InitInteriorRadExchange(state);
426 : }
427 2828408 : ComputeIntThermalAbsorpFactors(state);
428 :
429 : // Calculate factors for diffuse solar absorbed by room surfaces and interior shades
430 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
431 801 : DisplayString(state, "Computing Interior Diffuse Solar Absorption Factors");
432 : }
433 2828408 : ComputeIntSWAbsorpFactors(state);
434 :
435 2828408 : if (state.dataHeatBalSurf->InterZoneWindow) {
436 12147 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
437 6 : DisplayString(state, "Computing Interior Diffuse Solar Exchange through Interzone Windows");
438 : }
439 12147 : ComputeDifSolExcZonesWIZWindows(state);
440 : }
441 :
442 2828408 : Dayltg::initDaylighting(state, state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime);
443 :
444 5656816 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
445 2828408 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, "Main");
446 :
447 2828408 : if (state.dataSurface->AirflowWindows) {
448 4044 : SolarShading::WindowGapAirflowControl(state);
449 : }
450 :
451 : // The order of these initializations is important currently. Over time we hope to
452 : // take the appropriate parts of these inits to the other heat balance managers
453 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
454 801 : DisplayString(state, "Initializing Solar Heat Gains");
455 : }
456 :
457 2828408 : InitSolarHeatGains(state);
458 :
459 2828408 : Dayltg::manageDaylighting(state);
460 :
461 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
462 801 : DisplayString(state, "Initializing Internal Heat Gains");
463 : }
464 2828408 : InternalHeatGains::ManageInternalHeatGains(state, false);
465 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
466 801 : DisplayString(state, "Initializing Interior Solar Distribution");
467 : }
468 2828408 : InitIntSolarDistribution(state);
469 :
470 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
471 801 : DisplayString(state, "Initializing Interior Convection Coefficients");
472 : }
473 2828408 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempInTmp);
474 :
475 2828408 : if (state.dataGlobal->BeginSimFlag) { // Now's the time to report surfaces, if desired
476 : // if (firstTime) CALL DisplayString('Reporting Surfaces')
477 : // CALL ReportSurfaces
478 801 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
479 801 : DisplayString(state, "Gathering Information for Predefined Reporting");
480 : }
481 801 : GatherForPredefinedReport(state);
482 : }
483 :
484 : // Initialize the temperature history terms for conduction through the surfaces
485 2828408 : if (state.dataHeatBal->AnyCondFD) {
486 158532 : HeatBalFiniteDiffManager::InitHeatBalFiniteDiff(state);
487 : }
488 :
489 23363819 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
490 41119422 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
491 20584011 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
492 20584011 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
493 20584011 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
494 174074299 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
495 153490288 : auto const &surface = state.dataSurface->Surface(SurfNum);
496 153490288 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
497 2094168 : surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) {
498 1944150 : continue;
499 : }
500 : // Outside surface temp of "normal" windows not needed in Window5 calculation approach
501 : // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
502 :
503 151546138 : int const ConstrNum = surface.Construction;
504 151546138 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
505 151546138 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) = 0.0;
506 151546138 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) = 0.0;
507 151546138 : if (construct.NumCTFTerms <= 1) {
508 9616021 : continue;
509 : }
510 :
511 1087541746 : for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
512 : // [ l11 ] == ( 1, Term + 1, SurfNum ), [ l12 ] == ( 1, Term + 1, SurfNum )
513 :
514 : // Sign convention for the various terms in the following two equations
515 : // is based on the form of the Conduction Transfer Function equation
516 : // given by:
517 : // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old)
518 : // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old)
519 : // In both equations, flux is positive from outside to inside.
520 :
521 : // Tuned Aliases and linear indexing
522 945611629 : Real64 const ctf_cross(construct.CTFCross[Term]);
523 :
524 945611629 : Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
525 945611629 : Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
526 945611629 : Real64 const QH11(state.dataHeatBalSurf->SurfOutsideFluxHist(Term + 1)(SurfNum));
527 945611629 : Real64 const QH12(state.dataHeatBalSurf->SurfInsideFluxHist(Term + 1)(SurfNum));
528 945611629 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) +=
529 945611629 : ctf_cross * TH11 - construct.CTFInside[Term] * TH12 + construct.CTFFlux[Term] * QH12;
530 :
531 945611629 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) +=
532 945611629 : construct.CTFOutside[Term] * TH11 - ctf_cross * TH12 + construct.CTFFlux[Term] * QH11;
533 : }
534 : }
535 20535411 : }
536 : }
537 2828408 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
538 646938 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
539 976482 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
540 488241 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
541 488241 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
542 488241 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
543 3778335 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
544 3290094 : auto const &surface = state.dataSurface->Surface(SurfNum);
545 3290094 : int const ConstrNum = surface.Construction;
546 3290094 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
547 3290094 : if (!construct.SourceSinkPresent) {
548 2730924 : continue;
549 : }
550 559170 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
551 161478 : surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) {
552 161478 : continue;
553 : }
554 397692 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) = 0.0;
555 397692 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) = 0.0;
556 397692 : if (construct.NumCTFTerms <= 1) {
557 0 : continue;
558 : }
559 4376034 : for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
560 3978342 : Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
561 3978342 : Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
562 3978342 : Real64 const QsrcHist1(state.dataHeatBalSurf->SurfQsrcHist(SurfNum, Term + 1));
563 :
564 3978342 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += construct.CTFSourceIn[Term] * QsrcHist1;
565 :
566 3978342 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += construct.CTFSourceOut[Term] * QsrcHist1;
567 :
568 3978342 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) +=
569 3978342 : construct.CTFTSourceOut[Term] * TH11 + construct.CTFTSourceIn[Term] * TH12 + construct.CTFTSourceQ[Term] * QsrcHist1 +
570 3978342 : construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTsrcHist(SurfNum, Term + 1);
571 :
572 3978342 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) +=
573 3978342 : construct.CTFTUserOut[Term] * TH11 + construct.CTFTUserIn[Term] * TH12 + construct.CTFTUserSource[Term] * QsrcHist1 +
574 3978342 : construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTuserHist(SurfNum, Term + 1);
575 : }
576 : }
577 488241 : } // ...end of surfaces DO loop for initializing temperature history terms for the surface heat balances
578 : }
579 : }
580 :
581 : // Zero out all of the radiant system heat balance coefficient arrays
582 23363819 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
583 41119422 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
584 20584011 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
585 20584011 : int const firstSurf = thisSpace.HTSurfaceFirst;
586 20584011 : int const lastSurf = thisSpace.HTSurfaceLast;
587 197920873 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
588 177336862 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) = 0.0;
589 177336862 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) = 0.0;
590 177336862 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) = 0.0;
591 177336862 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = 0.0;
592 177336862 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = 0.0;
593 177336862 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = 0.0;
594 :
595 177336862 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
596 177336862 : state.dataHeatBalFanSys->QPVSysSource(SurfNum) = 0.0;
597 177336862 : state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = 0.0;
598 177336862 : state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = 0.0;
599 :
600 : } // ...end of Zone Surf loop
601 20535411 : }
602 : } // ...end of Zone loop
603 :
604 3052220 : for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
605 223812 : auto &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
606 223812 : thisSurfQRadFromHVAC.HTRadSys = 0.0;
607 223812 : thisSurfQRadFromHVAC.HWBaseboard = 0.0;
608 223812 : thisSurfQRadFromHVAC.SteamBaseboard = 0.0;
609 223812 : thisSurfQRadFromHVAC.ElecBaseboard = 0.0;
610 223812 : thisSurfQRadFromHVAC.CoolingPanel = 0.0;
611 2828408 : }
612 :
613 2828408 : if (state.dataGlobal->ZoneSizingCalc) {
614 830322 : GatherComponentLoadsSurfAbsFact(state);
615 : }
616 :
617 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
618 801 : DisplayString(state, "Completed Initializing Surface Heat Balance");
619 : }
620 2828408 : state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime = false;
621 2828408 : }
622 :
623 801 : void GatherForPredefinedReport(EnergyPlusData &state)
624 : {
625 :
626 : // SUBROUTINE INFORMATION:
627 : // AUTHOR Jason Glazer
628 : // DATE WRITTEN August 2006
629 :
630 : // PURPOSE OF THIS SUBROUTINE:
631 : // This subroutine reports the information for the predefined reports
632 : // related to envelope components.
633 :
634 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
635 801 : std::string surfName;
636 : Real64 mult;
637 : Real64 curAzimuth;
638 : Real64 curTilt;
639 : Real64 windowArea;
640 : Real64 frameWidth;
641 : Real64 frameArea;
642 : Real64 dividerArea;
643 : // counts for object count report
644 801 : int SurfaceClassCount = int(DataSurfaces::SurfaceClass::Num);
645 801 : Array1D_int numSurfaces(SurfaceClassCount);
646 801 : Array1D_int numExtSurfaces(SurfaceClassCount);
647 : int frameDivNum;
648 : bool isExterior;
649 801 : Array1D<Real64> computedNetArea; // holds the gross wall area minus the window and door areas
650 :
651 : // the following variables are for the CalcNominalWindowCond call but only SHGCSummer is needed
652 : Real64 nomCond;
653 : Real64 SHGCSummer;
654 : Real64 TransSolNorm;
655 : Real64 TransVisNorm;
656 : Real64 nomUfact;
657 : int errFlag;
658 : int curWSC;
659 : // following variables are totals for fenestration table
660 801 : Real64 windowAreaWMult(0.0);
661 801 : Real64 fenTotArea(0.0);
662 801 : Real64 fenTotAreaNorth(0.0);
663 801 : Real64 fenTotAreaNonNorth(0.0);
664 801 : Real64 ufactArea(0.0);
665 801 : Real64 ufactAreaNorth(0.0);
666 801 : Real64 ufactAreaNonNorth(0.0);
667 801 : Real64 shgcArea(0.0);
668 801 : Real64 shgcAreaNorth(0.0);
669 801 : Real64 shgcAreaNonNorth(0.0);
670 801 : Real64 vistranArea(0.0);
671 801 : Real64 vistranAreaNorth(0.0);
672 801 : Real64 vistranAreaNonNorth(0.0);
673 801 : Real64 intFenTotArea(0.0);
674 801 : Real64 intUfactArea(0.0);
675 801 : Real64 intShgcArea(0.0);
676 801 : Real64 intVistranArea(0.0);
677 : bool isNorth;
678 :
679 801 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WinShadingType::Num)> WindowShadingTypeNames = {
680 : "No Shade", // 0
681 : "Shade Off", // 1
682 : "Interior Shade",
683 : "Switchable Glazing",
684 : "Exterior Shade",
685 : "Exterior Screen",
686 : "Interior Blind",
687 : "Exterior Blind",
688 : "Between Glass Shade",
689 : "Between Glass Blind",
690 : };
691 :
692 801 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WindowShadingControlType::Num)> WindowShadingControlTypeNames = {
693 : "Uncontrolled",
694 : "AlwaysOn",
695 : "AlwaysOff",
696 : "OnIfScheduleAllows",
697 : "OnIfHighSolarOnWindow",
698 : "OnIfHighHorizontalSolar",
699 : "OnIfHighOutdoorAirTemperature",
700 : "OnIfHighZoneAirTemperature",
701 : "OnIfHighZoneCooling",
702 : "OnIfHighGlare",
703 : "MeetDaylightIlluminanceSetpoint",
704 : "OnNightIfLowOutdoorTempAndOffDay",
705 : "OnNightIfLowInsideTempAndOffDay",
706 : "OnNightIfHeatingAndOffDay",
707 : "OnNightIfLowOutdoorTempAndOnDayIfCooling",
708 : "OnNightIfHeatingAndOnDayIfCooling",
709 : "OffNightAndOnDayIfCoolingAndHighSolarOnWindow",
710 : "OnNightAndOnDayIfCoolingAndHighSolarOnWindow",
711 : "OnIfHighOutdoorAirTempAndHighSolarOnWindow",
712 : "OnIfHighOutdoorAirTempAndHighHorizontalSolar",
713 : "OnIfHighZoneAirTempAndHighSolarOnWindow",
714 : "OnIfHighZoneAirTempAndHighHorizontalSolar"};
715 :
716 801 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcProductNames = {
717 : "CasementDouble", "CasementSingle", "DualAction",
718 : "Fixed", "Garage", "Greenhouse",
719 : "HingedEscape", "HorizontalSlider", "Jal",
720 : "Pivoted", "ProjectingSingle", "ProjectingDual",
721 : "DoorSidelite", "Skylight", "SlidingPatioDoor",
722 : "CurtainWall", "SpandrelPanel", "SideHingedDoor",
723 : "DoorTransom", "TropicalAwning", "TubularDaylightingDevice",
724 : "VerticalSlider"};
725 :
726 801 : constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcWidth = {
727 : // width in meters from Table 4-3 of NFRC 100-2020
728 : 1.200, 0.600, 1.200, // CasementDouble, CasementSingle, DualAction,
729 : 1.200, 2.134, 1.500, // Fixed, Garage, Greenhouse,
730 : 1.500, 1.500, 1.200, // HingedEscape, HorizontalSlider, Jal,
731 : 1.200, 1.500, 1.500, // Pivoted, ProjectingSingle, ProjectingDual,
732 : 0.600, 1.200, 2.000, // DoorSidelite, Skylight, SlidingPatioDoor,
733 : 2.000, 2.000, 1.920, // CurtainWall, SpandrelPanel, SideHingedDoor,
734 : 2.000, 1.500, 0.350, // DoorTransom, TropicalAwning, TubularDaylightingDevice,
735 : 1.200 // VerticalSlider,
736 : };
737 :
738 801 : constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcHeight = {
739 : // height in meters from Table 4-3 of NFRC 100-2020
740 : 1.500, 1.500, 1.500, // CasementDouble, CasementSingle, DualAction,
741 : 1.500, 2.134, 1.200, // Fixed, Garage, Greenhouse,
742 : 1.200, 1.200, 1.500, // HingedEscape, HorizontalSlider, Jal,
743 : 1.500, 1.200, 0.600, // Pivoted, ProjectingSingle, ProjectingDual,
744 : 2.090, 1.200, 2.000, // DoorSidelite, Skylight, SlidingPatioDoor,
745 : 2.000, 1.200, 2.090, // CurtainWall, SpandrelPanel, SideHingedDoor,
746 : 0.600, 1.200, 0.350, // DoorTransom, TropicalAwning, TubularDaylightingDevice,
747 : 1.500 // VerticalSlider,
748 : };
749 :
750 801 : constexpr std::array<DataSurfaces::NfrcVisionType, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcVision = {
751 : DataSurfaces::NfrcVisionType::DualHorizontal, DataSurfaces::NfrcVisionType::Single,
752 : DataSurfaces::NfrcVisionType::DualVertical, // CasementDouble, CasementSingle, DualAction,
753 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
754 : DataSurfaces::NfrcVisionType::Single, // Fixed, Garage, Greenhouse,
755 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::DualHorizontal,
756 : DataSurfaces::NfrcVisionType::Single, // HingedEscape, HorizontalSlider, Jal,
757 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
758 : DataSurfaces::NfrcVisionType::DualHorizontal, // Pivoted, ProjectingSingle, ProjectingDual,
759 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
760 : DataSurfaces::NfrcVisionType::DualHorizontal, // DoorSidelite, Skylight, SlidingPatioDoor,
761 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
762 : DataSurfaces::NfrcVisionType::Single, // CurtainWall, SpandrelPanel, SideHingedDoor,
763 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
764 : DataSurfaces::NfrcVisionType::Single, // DoorTransom, TropicalAwning, TubularDaylightingDevice,
765 : DataSurfaces::NfrcVisionType::DualVertical // VerticalSlider
766 : };
767 :
768 801 : numSurfaces = 0;
769 801 : numExtSurfaces = 0;
770 :
771 801 : computedNetArea.allocate(state.dataSurface->TotSurfaces);
772 801 : computedNetArea = 0.0; // start at zero, add wall area and subtract window and door area
773 :
774 : // set up for EIO <FenestrationAssembly> output
775 801 : if (state.dataHeatBal->TotFrameDivider > 0 && state.dataGeneral->Constructions) {
776 18 : print(state.files.eio,
777 : "{}\n",
778 : "! <FenestrationAssembly>,Construction Name,Frame and Divider Name,NFRC Product Type,"
779 : "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
780 : }
781 : static constexpr std::string_view FenestrationAssemblyFormat("FenestrationAssembly,{},{},{},{:.3R},{:.3R},{:.3R}\n");
782 801 : std::vector<std::pair<int, int>> uniqConsFrame;
783 801 : std::pair<int, int> consAndFrame;
784 :
785 : // set up for EIO <FenestrationShadedState> output
786 801 : bool fenestrationShadedStateHeaderShown(false);
787 : static constexpr std::string_view FenestrationShadedStateFormat("FenestrationShadedState,{},{:.3R},{:.3R},{:.3R},{},{},{:.3R},{:.3R},{:.3R}\n");
788 801 : std::vector<std::pair<int, int>> uniqShdConsFrame;
789 801 : std::pair<int, int> shdConsAndFrame;
790 :
791 48091 : for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
792 47290 : auto &surface = state.dataSurface->Surface(iSurf);
793 47290 : surfName = surface.Name;
794 : // only exterior surfaces including underground
795 47290 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
796 25183 : (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
797 22331 : isExterior = true;
798 22331 : switch (surface.Class) {
799 13893 : case DataSurfaces::SurfaceClass::Wall:
800 : case DataSurfaces::SurfaceClass::Floor:
801 : case DataSurfaces::SurfaceClass::Roof: {
802 13893 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
803 13893 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
804 13893 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
805 13893 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
806 13893 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpCons, surfName, construct.Name);
807 13893 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpZone, surfName, thisZone.Name);
808 13893 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpSpace, surfName, thisSpace.Name);
809 13893 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
810 13893 : OutputReportPredefined::PreDefTableEntry(
811 13893 : state, state.dataOutRptPredefined->pdchOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
812 13893 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpGrArea, surfName, surface.GrossArea * mult);
813 13893 : computedNetArea(iSurf) += surface.GrossArea * mult;
814 13893 : curAzimuth = surface.Azimuth;
815 : // Round to two decimals, like the display in tables
816 : // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
817 13893 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
818 13893 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpAzimuth, surfName, curAzimuth);
819 13893 : curTilt = surface.Tilt;
820 13893 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpTilt, surfName, curTilt);
821 13893 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
822 9261 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
823 2385 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "N");
824 6876 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
825 2200 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "E");
826 4676 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
827 2409 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "S");
828 2267 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
829 2267 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "W");
830 : }
831 : }
832 13893 : } break;
833 6347 : case DataSurfaces::SurfaceClass::Window:
834 : case DataSurfaces::SurfaceClass::TDD_Dome: {
835 6347 : auto &construct = state.dataConstruction->Construct(surface.Construction);
836 6347 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
837 6347 : mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
838 6347 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
839 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenCons, surfName, construct.Name);
840 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenZone, surfName, thisZone.Name);
841 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSpace, surfName, thisSpace.Name);
842 : // if the construction report is requested the SummerSHGC is already calculated
843 6347 : if (construct.SummerSHGC != 0) {
844 5679 : SHGCSummer = construct.SummerSHGC;
845 5679 : TransVisNorm = construct.VisTransNorm;
846 : } else {
847 : // must calculate Summer SHGC
848 668 : if (!construct.WindowTypeEQL) {
849 668 : Window::CalcNominalWindowCond(state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
850 668 : construct.SummerSHGC = SHGCSummer;
851 668 : construct.VisTransNorm = TransVisNorm;
852 668 : construct.SolTransNorm = TransSolNorm;
853 : }
854 : }
855 : // include the frame area if present
856 6347 : windowArea = surface.GrossArea;
857 6347 : frameArea = 0.0;
858 6347 : dividerArea = 0.0;
859 6347 : frameDivNum = surface.FrameDivider;
860 6347 : if (frameDivNum != 0) {
861 381 : auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
862 381 : frameWidth = frameDivider.FrameWidth;
863 381 : frameArea = (surface.Height + 2.0 * frameWidth) * (surface.Width + 2.0 * frameWidth) - (surface.Height * surface.Width);
864 381 : windowArea += frameArea;
865 381 : dividerArea = frameDivider.DividerWidth * (frameDivider.HorDividers * surface.Width + frameDivider.VertDividers * surface.Height -
866 381 : frameDivider.HorDividers * frameDivider.VertDividers * frameDivider.DividerWidth);
867 381 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameDivName, surfName, frameDivider.Name);
868 381 : OutputReportPredefined::PreDefTableEntry(
869 381 : state, state.dataOutRptPredefined->pdchFenFrameConductance, surfName, frameDivider.FrameConductance, 3);
870 381 : OutputReportPredefined::PreDefTableEntry(
871 381 : state, state.dataOutRptPredefined->pdchFenDividerConductance, surfName, frameDivider.DividerConductance, 3);
872 :
873 : // report the selected NRFC product type (specific sizes) and the NFRC rating for the assembly (glass + frame + divider)
874 381 : std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
875 381 : const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
876 381 : const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
877 381 : const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
878 :
879 381 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemNfrcType, surfName, NFRCname);
880 :
881 381 : Real64 uValueAssembly = 0.0;
882 381 : Real64 shgcAssembly = 0.0;
883 381 : Real64 vtAssembly = 0.0;
884 :
885 381 : Window::GetWindowAssemblyNfrcForReport(
886 : state, iSurf, surface.Construction, windowWidth, windowHeight, vision, uValueAssembly, shgcAssembly, vtAssembly);
887 381 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
888 0 : state.dataHeatBal->NominalU(surface.Construction) =
889 0 : Window::GetIGUUValueForNFRCReport(state, iSurf, surface.Construction, windowWidth, windowHeight);
890 0 : SHGCSummer = Window::GetSHGCValueForNFRCReporting(state, iSurf, surface.Construction, windowWidth, windowHeight);
891 : }
892 381 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemUfact, surfName, uValueAssembly, 3);
893 381 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemSHGC, surfName, shgcAssembly, 3);
894 381 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemVisTr, surfName, vtAssembly, 3);
895 :
896 : // output EIO <FenestrationAssembly> for each unique combination of construction and frame/divider
897 381 : if (state.dataGeneral->Constructions) {
898 340 : consAndFrame = std::make_pair(surface.Construction, frameDivNum);
899 340 : if (std::find(uniqConsFrame.begin(), uniqConsFrame.end(), consAndFrame) == uniqConsFrame.end()) {
900 30 : uniqConsFrame.push_back(consAndFrame);
901 30 : print(state.files.eio,
902 : FenestrationAssemblyFormat,
903 30 : construct.Name,
904 30 : frameDivider.Name,
905 : NFRCname,
906 : uValueAssembly,
907 : shgcAssembly,
908 : vtAssembly);
909 : }
910 : }
911 : }
912 6347 : windowAreaWMult = windowArea * mult;
913 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAreaOf1, surfName, windowArea);
914 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameAreaOf1, surfName, frameArea);
915 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDividerAreaOf1, surfName, dividerArea);
916 12694 : OutputReportPredefined::PreDefTableEntry(
917 6347 : state, state.dataOutRptPredefined->pdchFenGlassAreaOf1, surfName, windowArea - (frameArea + dividerArea));
918 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, surfName, windowAreaWMult);
919 6347 : computedNetArea(surface.BaseSurf) -= windowAreaWMult;
920 6347 : nomUfact = state.dataHeatBal->NominalU(surface.Construction);
921 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, surfName, nomUfact, 3);
922 :
923 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, surfName, SHGCSummer, 3);
924 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, surfName, TransVisNorm, 3);
925 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenParent, surfName, surface.BaseSurfName);
926 6347 : curAzimuth = surface.Azimuth;
927 : // Round to two decimals, like the display in tables
928 6347 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
929 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAzimuth, surfName, curAzimuth);
930 6347 : isNorth = false;
931 6347 : curTilt = surface.Tilt;
932 6347 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenTilt, surfName, curTilt);
933 6347 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
934 5950 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
935 1479 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "N");
936 1479 : isNorth = true;
937 4471 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
938 1089 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "E");
939 3382 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
940 2296 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "S");
941 1086 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
942 1086 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "W");
943 : }
944 : }
945 :
946 : // Report table for every shading control state
947 6347 : const unsigned int totalStates = surface.windowShadingControlList.size();
948 6347 : if (frameDivNum != 0) {
949 381 : auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
950 422 : for (unsigned int i = 0; i < totalStates; ++i) {
951 41 : const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
952 41 : const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
953 41 : const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
954 :
955 41 : const int stateConstrNum = surface.shadedConstructionList[i];
956 41 : const Real64 stateUValue = Window::GetIGUUValueForNFRCReport(state, iSurf, stateConstrNum, windowWidth, windowHeight);
957 41 : const Real64 stateSHGC = Window::GetSHGCValueForNFRCReporting(state, iSurf, stateConstrNum, windowWidth, windowHeight);
958 41 : std::string const &constructionName = state.dataConstruction->Construct(stateConstrNum).Name;
959 :
960 82 : OutputReportPredefined::PreDefTableEntry(
961 41 : state, state.dataOutRptPredefined->pdchFenShdFrameDiv, constructionName, frameDivider.Name);
962 82 : OutputReportPredefined::PreDefTableEntry(
963 82 : state, state.dataOutRptPredefined->pdchFenShdUfact, constructionName, stateUValue, 3);
964 41 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenShdSHGC, constructionName, stateSHGC, 3);
965 41 : OutputReportPredefined::PreDefTableEntry(state,
966 41 : state.dataOutRptPredefined->pdchFenShdVisTr,
967 : constructionName,
968 41 : state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
969 41 : 3);
970 :
971 41 : Real64 stateAssemblyUValue{0.0};
972 41 : Real64 stateAssemblySHGC{0.0};
973 41 : Real64 stateAssemblyVT{0.0};
974 :
975 41 : Window::GetWindowAssemblyNfrcForReport(
976 : state, iSurf, stateConstrNum, windowWidth, windowHeight, vision, stateAssemblyUValue, stateAssemblySHGC, stateAssemblyVT);
977 :
978 41 : std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
979 82 : OutputReportPredefined::PreDefTableEntry(
980 41 : state, state.dataOutRptPredefined->pdchFenShdAssemNfrcType, constructionName, NFRCname);
981 :
982 82 : OutputReportPredefined::PreDefTableEntry(
983 82 : state, state.dataOutRptPredefined->pdchFenShdAssemUfact, constructionName, stateAssemblyUValue, 3);
984 82 : OutputReportPredefined::PreDefTableEntry(
985 82 : state, state.dataOutRptPredefined->pdchFenShdAssemSHGC, constructionName, stateAssemblySHGC, 3);
986 82 : OutputReportPredefined::PreDefTableEntry(
987 82 : state, state.dataOutRptPredefined->pdchFenShdAssemVisTr, constructionName, stateAssemblyVT, 3);
988 :
989 41 : if (state.dataGeneral->Constructions) {
990 23 : if (!fenestrationShadedStateHeaderShown) {
991 4 : print(state.files.eio,
992 : "{}\n",
993 : "! <FenestrationShadedState>,Construction Name,Glass U-Factor {W/m2-K},"
994 : "Glass SHGC, Glass Visible Transmittance, Frame and Divider Name,NFRC Product Type,"
995 : "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
996 4 : fenestrationShadedStateHeaderShown = true;
997 : }
998 :
999 23 : shdConsAndFrame = std::make_pair(stateConstrNum, frameDivNum);
1000 23 : if (std::find(uniqShdConsFrame.begin(), uniqShdConsFrame.end(), shdConsAndFrame) == uniqShdConsFrame.end()) {
1001 14 : uniqShdConsFrame.push_back(shdConsAndFrame);
1002 14 : print(state.files.eio,
1003 : FenestrationShadedStateFormat,
1004 : constructionName,
1005 : stateUValue,
1006 : stateSHGC,
1007 14 : state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
1008 14 : frameDivider.Name,
1009 : NFRCname,
1010 : stateAssemblyUValue,
1011 : stateAssemblySHGC,
1012 : stateAssemblyVT);
1013 : }
1014 : }
1015 : }
1016 : }
1017 :
1018 6347 : curWSC = surface.activeWindowShadingControl;
1019 : // compute totals for area weighted averages
1020 6347 : fenTotArea += windowAreaWMult;
1021 6347 : ufactArea += nomUfact * windowAreaWMult;
1022 6347 : shgcArea += SHGCSummer * windowAreaWMult;
1023 6347 : vistranArea += TransVisNorm * windowAreaWMult;
1024 6347 : if (isNorth) {
1025 1479 : fenTotAreaNorth += windowAreaWMult;
1026 1479 : ufactAreaNorth += nomUfact * windowAreaWMult;
1027 1479 : shgcAreaNorth += SHGCSummer * windowAreaWMult;
1028 1479 : vistranAreaNorth += TransVisNorm * windowAreaWMult;
1029 : } else {
1030 4868 : fenTotAreaNonNorth += windowAreaWMult;
1031 4868 : ufactAreaNonNorth += nomUfact * windowAreaWMult;
1032 4868 : shgcAreaNonNorth += SHGCSummer * windowAreaWMult;
1033 4868 : vistranAreaNonNorth += TransVisNorm * windowAreaWMult;
1034 : }
1035 : // shading
1036 6347 : if (surface.HasShadeControl) {
1037 151 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "Yes");
1038 302 : OutputReportPredefined::PreDefTableEntry(
1039 302 : state, state.dataOutRptPredefined->pdchWscName, surfName, state.dataSurface->WindowShadingControl(curWSC).Name);
1040 : // shading report
1041 302 : OutputReportPredefined::PreDefTableEntry(
1042 : state,
1043 151 : state.dataOutRptPredefined->pdchWscShading,
1044 : surfName,
1045 151 : WindowShadingTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).ShadingType)]);
1046 302 : OutputReportPredefined::PreDefTableEntry(
1047 : state,
1048 151 : state.dataOutRptPredefined->pdchWscControl,
1049 : surfName,
1050 151 : WindowShadingControlTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).shadingControlType)]);
1051 :
1052 : // output list of all possible shading constructions for shaded windows including those with storms
1053 151 : std::string names;
1054 306 : for (int construction : surface.shadedConstructionList) {
1055 155 : if (!names.empty()) {
1056 4 : names.append("; ");
1057 : }
1058 155 : names.append(state.dataConstruction->Construct(construction).Name);
1059 151 : }
1060 151 : for (int construction : surface.shadedStormWinConstructionList) {
1061 0 : if (!names.empty()) {
1062 0 : names.append("; ");
1063 : }
1064 0 : names.append(state.dataConstruction->Construct(construction).Name);
1065 151 : }
1066 151 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscShadCons, surfName, names);
1067 :
1068 151 : if (state.dataSurface->WindowShadingControl(curWSC).GlareControlIsActive) {
1069 30 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "Yes");
1070 : } else {
1071 121 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "No");
1072 : }
1073 151 : } else {
1074 6196 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "No");
1075 : }
1076 6347 : } break;
1077 401 : case DataSurfaces::SurfaceClass::Door: {
1078 401 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1079 401 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1080 401 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1081 802 : OutputReportPredefined::PreDefTableEntry(
1082 802 : state, state.dataOutRptPredefined->pdchDrCons, surfName, state.dataConstruction->Construct(surface.Construction).Name);
1083 401 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrZone, surfName, thisZone.Name);
1084 401 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrSpace, surfName, thisSpace.Name);
1085 401 : OutputReportPredefined::PreDefTableEntry(
1086 401 : state, state.dataOutRptPredefined->pdchDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1087 401 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrGrArea, surfName, surface.GrossArea * mult);
1088 401 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrParent, surfName, surface.BaseSurfName);
1089 401 : computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
1090 401 : } break;
1091 1690 : default:
1092 1690 : break;
1093 : }
1094 22331 : } else {
1095 : // interior surfaces
1096 24959 : isExterior = false;
1097 24959 : if ((surface.Class == DataSurfaces::SurfaceClass::Wall) || (surface.Class == DataSurfaces::SurfaceClass::Floor) ||
1098 6320 : (surface.Class == DataSurfaces::SurfaceClass::Roof) || (surface.Class == DataSurfaces::SurfaceClass::IntMass)) {
1099 24865 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1100 24865 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1101 24865 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1102 24865 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1103 24865 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpCons, surfName, construct.Name);
1104 24865 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpZone, surfName, thisZone.Name);
1105 24865 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpSpace, surfName, thisSpace.Name);
1106 24865 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAdjSurf, surfName, surface.ExtBoundCondName);
1107 49730 : OutputReportPredefined::PreDefTableEntry(
1108 24865 : state, state.dataOutRptPredefined->pdchIntOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
1109 24865 : OutputReportPredefined::PreDefTableEntry(
1110 24865 : state, state.dataOutRptPredefined->pdchIntOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1111 24865 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpGrArea, surfName, surface.GrossArea * mult);
1112 24865 : computedNetArea(iSurf) += surface.GrossArea * mult;
1113 24865 : curAzimuth = surface.Azimuth;
1114 : // Round to two decimals, like the display in tables
1115 : // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
1116 24865 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
1117 24865 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAzimuth, surfName, curAzimuth);
1118 24865 : curTilt = surface.Tilt;
1119 24865 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpTilt, surfName, curTilt);
1120 24865 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
1121 16499 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
1122 6097 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "N");
1123 10402 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
1124 3421 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "E");
1125 6981 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
1126 3563 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "S");
1127 3418 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
1128 3418 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "W");
1129 : }
1130 : }
1131 : // interior window report
1132 24959 : } else if ((surface.Class == DataSurfaces::SurfaceClass::Window) || (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)) {
1133 14 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1134 14 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1135 14 : mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
1136 14 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1137 14 : if (!has_prefix(surface.Name,
1138 : "iz-")) { // don't count created interzone surfaces that are mirrors of other surfaces
1139 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenCons, surfName, construct.Name);
1140 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenZone, surfName, thisZone.Name);
1141 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSpace, surfName, thisSpace.Name);
1142 : // include the frame area if present
1143 12 : windowArea = surface.GrossArea;
1144 12 : if (surface.FrameDivider != 0) {
1145 0 : frameWidth = state.dataSurface->FrameDivider(surface.FrameDivider).FrameWidth;
1146 0 : frameArea = (surface.Height + 2 * frameWidth) * (surface.Width + 2 * frameWidth) - (surface.Height * surface.Width);
1147 0 : windowArea += frameArea;
1148 : }
1149 12 : windowAreaWMult = windowArea * mult;
1150 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenAreaOf1, surfName, windowArea);
1151 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, surfName, windowAreaWMult);
1152 12 : computedNetArea(surface.BaseSurf) -= windowAreaWMult;
1153 12 : nomUfact = state.dataHeatBal->NominalU(surface.Construction);
1154 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, surfName, nomUfact, 3);
1155 12 : if (!construct.TypeIsAirBoundary) {
1156 : // Solar properties not applicable for air boundary surfaces
1157 : // if the construction report is requested the SummerSHGC is already calculated
1158 12 : if (construct.SummerSHGC != 0) {
1159 12 : SHGCSummer = construct.SummerSHGC;
1160 12 : TransVisNorm = construct.VisTransNorm;
1161 : } else {
1162 : // must calculate Summer SHGC
1163 0 : if (!construct.WindowTypeEQL) {
1164 0 : Window::CalcNominalWindowCond(
1165 : state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
1166 : }
1167 : }
1168 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, surfName, SHGCSummer, 3);
1169 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, surfName, TransVisNorm, 3);
1170 : // compute totals for area weighted averages
1171 12 : intShgcArea += SHGCSummer * windowAreaWMult;
1172 12 : intVistranArea += TransVisNorm * windowAreaWMult;
1173 : }
1174 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenParent, surfName, surface.BaseSurfName);
1175 : // compute totals for area weighted averages
1176 12 : intFenTotArea += windowAreaWMult;
1177 12 : intUfactArea += nomUfact * windowAreaWMult;
1178 : }
1179 94 : } else if (surface.Class == DataSurfaces::SurfaceClass::Door) {
1180 80 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1181 80 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1182 80 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1183 80 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1184 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrCons, surfName, construct.Name);
1185 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrZone, surfName, thisZone.Name);
1186 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrSpace, surfName, thisSpace.Name);
1187 80 : OutputReportPredefined::PreDefTableEntry(
1188 80 : state, state.dataOutRptPredefined->pdchIntDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1189 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrGrArea, surfName, surface.GrossArea * mult);
1190 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrParent, surfName, surface.BaseSurfName);
1191 80 : computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
1192 : }
1193 : }
1194 47290 : int currSurfaceClass = int(surface.Class);
1195 47290 : assert(currSurfaceClass < int(DataSurfaces::SurfaceClass::Num));
1196 47290 : assert(currSurfaceClass > int(DataSurfaces::SurfaceClass::None));
1197 47290 : ++numSurfaces(currSurfaceClass);
1198 47290 : if (isExterior) {
1199 22331 : ++numExtSurfaces(currSurfaceClass);
1200 : }
1201 47290 : if (surface.Class == DataSurfaces::SurfaceClass::Window) {
1202 6359 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::GlassDoor || surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
1203 543 : ++numSurfaces((int)surface.OriginalClass);
1204 543 : if (isExterior) {
1205 541 : ++numExtSurfaces((int)surface.OriginalClass);
1206 : }
1207 : }
1208 : }
1209 801 : }
1210 : // for fins and overhangs just add them explicitly since not otherwise classified
1211 801 : int totOverhangs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang") +
1212 801 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang:Projection");
1213 801 : numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
1214 801 : numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
1215 801 : int totFins = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin") +
1216 801 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin:Projection");
1217 801 : numSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
1218 801 : numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
1219 : // go through all the surfaces again and this time insert the net area results
1220 48091 : for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
1221 47290 : auto const &surface = state.dataSurface->Surface(iSurf);
1222 47290 : DataSurfaces::SurfaceClass const SurfaceClass(surface.Class);
1223 : // exterior surfaces including underground
1224 47290 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
1225 25183 : (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
1226 22331 : if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
1227 : (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
1228 13893 : surfName = surface.Name;
1229 13893 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpNetArea, surfName, computedNetArea(iSurf));
1230 : }
1231 : } else {
1232 24959 : if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
1233 : (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
1234 22328 : surfName = surface.Name;
1235 22328 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpNetArea, surfName, computedNetArea(iSurf));
1236 : }
1237 : } // interior surfaces
1238 801 : }
1239 : // total
1240 801 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Total or Average", fenTotArea);
1241 801 : if (fenTotArea > 0.0) {
1242 704 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", ufactArea / fenTotArea, 3);
1243 704 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", shgcArea / fenTotArea, 3);
1244 704 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", vistranArea / fenTotArea, 3);
1245 : } else {
1246 97 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", "-");
1247 97 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", "-");
1248 97 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", "-");
1249 : }
1250 : // north
1251 801 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "North Total or Average", fenTotAreaNorth);
1252 801 : if (fenTotAreaNorth > 0.0) {
1253 818 : OutputReportPredefined::PreDefTableEntry(
1254 818 : state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", ufactAreaNorth / fenTotAreaNorth, 3);
1255 818 : OutputReportPredefined::PreDefTableEntry(
1256 818 : state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", shgcAreaNorth / fenTotAreaNorth, 3);
1257 818 : OutputReportPredefined::PreDefTableEntry(
1258 1227 : state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", vistranAreaNorth / fenTotAreaNorth, 3);
1259 : } else {
1260 392 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", "-");
1261 392 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", "-");
1262 392 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", "-");
1263 : }
1264 : // non-north
1265 801 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Non-North Total or Average", fenTotAreaNonNorth);
1266 801 : if (fenTotAreaNonNorth > 0.0) {
1267 1406 : OutputReportPredefined::PreDefTableEntry(
1268 1406 : state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", ufactAreaNonNorth / fenTotAreaNonNorth, 3);
1269 1406 : OutputReportPredefined::PreDefTableEntry(
1270 1406 : state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", shgcAreaNonNorth / fenTotAreaNonNorth, 3);
1271 1406 : OutputReportPredefined::PreDefTableEntry(
1272 2109 : state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", vistranAreaNonNorth / fenTotAreaNonNorth, 3);
1273 : } else {
1274 98 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", "-");
1275 98 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", "-");
1276 98 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", "-");
1277 : }
1278 : // interior fenestration totals
1279 801 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, "Total or Average", intFenTotArea);
1280 801 : if (intFenTotArea > 0.0) {
1281 12 : OutputReportPredefined::PreDefTableEntry(
1282 12 : state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", intUfactArea / intFenTotArea, 3);
1283 12 : OutputReportPredefined::PreDefTableEntry(
1284 12 : state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", intShgcArea / intFenTotArea, 3);
1285 12 : OutputReportPredefined::PreDefTableEntry(
1286 18 : state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", intVistranArea / intFenTotArea, 3);
1287 : } else {
1288 795 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", "-");
1289 795 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", "-");
1290 795 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", "-");
1291 : }
1292 : // counts
1293 801 : OutputReportPredefined::PreDefTableEntry(
1294 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Wall", numSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
1295 801 : OutputReportPredefined::PreDefTableEntry(
1296 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Wall", numExtSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
1297 801 : OutputReportPredefined::PreDefTableEntry(
1298 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Floor", numSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
1299 801 : OutputReportPredefined::PreDefTableEntry(
1300 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Floor", numExtSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
1301 801 : OutputReportPredefined::PreDefTableEntry(
1302 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Roof", numSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
1303 801 : OutputReportPredefined::PreDefTableEntry(
1304 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Roof", numExtSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
1305 801 : OutputReportPredefined::PreDefTableEntry(
1306 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Internal Mass", numSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
1307 801 : OutputReportPredefined::PreDefTableEntry(
1308 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Internal Mass", numExtSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
1309 801 : OutputReportPredefined::PreDefTableEntry(
1310 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Building Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
1311 801 : OutputReportPredefined::PreDefTableEntry(
1312 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Building Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
1313 801 : OutputReportPredefined::PreDefTableEntry(
1314 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Fixed Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
1315 801 : OutputReportPredefined::PreDefTableEntry(
1316 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Fixed Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
1317 801 : OutputReportPredefined::PreDefTableEntry(
1318 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Window", numSurfaces(int(DataSurfaces::SurfaceClass::Window)));
1319 801 : OutputReportPredefined::PreDefTableEntry(
1320 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Window", numExtSurfaces(int(DataSurfaces::SurfaceClass::Window)));
1321 801 : OutputReportPredefined::PreDefTableEntry(
1322 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Door", numSurfaces(int(DataSurfaces::SurfaceClass::Door)));
1323 801 : OutputReportPredefined::PreDefTableEntry(
1324 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::Door)));
1325 801 : OutputReportPredefined::PreDefTableEntry(
1326 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Glass Door", numSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
1327 801 : OutputReportPredefined::PreDefTableEntry(
1328 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Glass Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
1329 801 : OutputReportPredefined::PreDefTableEntry(
1330 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
1331 801 : OutputReportPredefined::PreDefTableEntry(
1332 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
1333 801 : OutputReportPredefined::PreDefTableEntry(
1334 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Overhang", numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
1335 801 : OutputReportPredefined::PreDefTableEntry(
1336 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Overhang", numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
1337 801 : OutputReportPredefined::PreDefTableEntry(
1338 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Fin", numSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
1339 801 : OutputReportPredefined::PreDefTableEntry(
1340 801 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Fin", numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
1341 801 : OutputReportPredefined::PreDefTableEntry(
1342 801 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Tubular Daylighting Device Dome", numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
1343 801 : OutputReportPredefined::PreDefTableEntry(state,
1344 801 : state.dataOutRptPredefined->pdchSurfCntExt,
1345 : "Tubular Daylighting Device Dome",
1346 801 : numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
1347 801 : OutputReportPredefined::PreDefTableEntry(state,
1348 801 : state.dataOutRptPredefined->pdchSurfCntTot,
1349 : "Tubular Daylighting Device Diffuser",
1350 801 : numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
1351 801 : OutputReportPredefined::PreDefTableEntry(state,
1352 801 : state.dataOutRptPredefined->pdchSurfCntExt,
1353 : "Tubular Daylighting Device Diffuser",
1354 801 : numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
1355 801 : }
1356 :
1357 801 : void AllocateSurfaceHeatBalArrays(EnergyPlusData &state)
1358 : {
1359 :
1360 : // SUBROUTINE INFORMATION:
1361 : // AUTHOR Richard Liesen
1362 : // DATE WRITTEN February 1998
1363 :
1364 : // METHODOLOGY EMPLOYED:
1365 : // Uses the status flags to trigger variable allocation.
1366 :
1367 : // Use the total number of surfaces to allocate variables to avoid a surface number limit
1368 801 : state.dataHeatBalSurf->SurfCTFConstInPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1369 801 : state.dataHeatBalSurf->SurfCTFConstOutPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1370 801 : state.dataHeatBalSurf->SurfCTFCross0.dimension(state.dataSurface->TotSurfaces, 0.0);
1371 801 : state.dataHeatBalSurf->SurfCTFInside0.dimension(state.dataSurface->TotSurfaces, 0.0);
1372 801 : state.dataHeatBalSurf->SurfTempOutHist.dimension(state.dataSurface->TotSurfaces, 0.0);
1373 801 : state.dataHeatBalSurf->SurfCTFSourceIn0.dimension(state.dataSurface->TotSurfaces, 0.0);
1374 801 : state.dataHeatBalSurf->SurfQSourceSinkHist.dimension(state.dataSurface->TotSurfaces, 0.0);
1375 801 : state.dataHeatBalSurf->SurfIsAdiabatic.dimension(state.dataSurface->TotSurfaces, 0);
1376 801 : state.dataHeatBalSurf->SurfIsSourceOrSink.dimension(state.dataSurface->TotSurfaces, 0);
1377 801 : state.dataHeatBalSurf->SurfIsOperatingPool.dimension(state.dataSurface->TotSurfaces, 0);
1378 801 : state.dataHeatBalSurf->SurfTempTerm.dimension(state.dataSurface->TotSurfaces, 0);
1379 801 : state.dataHeatBalSurf->SurfTempDiv.dimension(state.dataSurface->TotSurfaces, 0);
1380 801 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
1381 36 : state.dataHeatBalFanSys->CTFTsrcConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1382 36 : state.dataHeatBalFanSys->CTFTuserConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1383 : }
1384 :
1385 801 : state.dataHeatBal->SurfTempEffBulkAir.dimension(state.dataSurface->TotSurfaces, DataHeatBalance::ZoneInitialTemp);
1386 801 : state.dataHeatBalSurf->SurfHConvInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1387 801 : state.dataHeatBalSurf->SurfHConvExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1388 801 : state.dataHeatBalSurf->SurfHAirExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1389 801 : state.dataHeatBalSurf->SurfHSkyExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1390 801 : state.dataHeatBalSurf->SurfHGrdExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1391 801 : state.dataHeatBalSurf->SurfHSrdSurfExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1392 :
1393 801 : state.dataHeatBalSurf->SurfTempIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1394 801 : state.dataHeatBalSurf->SurfTempInsOld.dimension(state.dataSurface->TotSurfaces, 0.0);
1395 801 : state.dataHeatBalSurf->SurfTempInTmp.dimension(state.dataSurface->TotSurfaces, 0.0);
1396 801 : state.dataHeatBalSurfMgr->RefAirTemp.dimension(state.dataSurface->TotSurfaces, 0.0);
1397 801 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs.dimension(state.dataSurface->TotSurfaces, 0.0);
1398 :
1399 801 : state.dataHeatBal->SurfWinQRadSWwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL + 1, 0.0);
1400 801 : state.dataHeatBal->SurfWinInitialDifSolwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL, 0.0);
1401 801 : state.dataHeatBalSurf->SurfQRadSWOutMvIns.dimension(state.dataSurface->TotSurfaces, 0.0);
1402 801 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1403 801 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside.dimension(state.dataSurface->TotSurfaces, 0.0);
1404 801 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside.dimension(state.dataSurface->TotSurfaces, 0.0);
1405 :
1406 801 : state.dataHeatBalSurf->SurfInsideTempHist.allocate(Construction::MaxCTFTerms);
1407 801 : state.dataHeatBalSurf->SurfOutsideTempHist.allocate(Construction::MaxCTFTerms);
1408 801 : state.dataHeatBalSurf->SurfInsideFluxHist.allocate(Construction::MaxCTFTerms);
1409 801 : state.dataHeatBalSurf->SurfOutsideFluxHist.allocate(Construction::MaxCTFTerms);
1410 16020 : for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
1411 15219 : state.dataHeatBalSurf->SurfInsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1412 15219 : state.dataHeatBalSurf->SurfOutsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1413 15219 : state.dataHeatBalSurf->SurfInsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1414 15219 : state.dataHeatBalSurf->SurfOutsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1415 : }
1416 :
1417 801 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
1418 140 : state.dataHeatBalSurf->SurfCurrNumHist.dimension(state.dataSurface->TotSurfaces, 0);
1419 :
1420 140 : state.dataHeatBalSurf->SurfInsideTempHistMaster.allocate(Construction::MaxCTFTerms);
1421 140 : state.dataHeatBalSurf->SurfOutsideTempHistMaster.allocate(Construction::MaxCTFTerms);
1422 140 : state.dataHeatBalSurf->SurfInsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
1423 140 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
1424 :
1425 2800 : for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
1426 2660 : state.dataHeatBalSurf->SurfInsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1427 2660 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1428 2660 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1429 2660 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1430 : }
1431 : }
1432 :
1433 801 : state.dataHeatBalSurf->SurfTempOut.dimension(state.dataSurface->TotSurfaces, 0.0);
1434 801 : state.dataHeatBalSurf->SurfTempInMovInsRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1435 801 : state.dataHeatBalSurf->SurfQConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1436 801 : state.dataHeatBalSurf->SurfQdotConvInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1437 801 : state.dataHeatBalSurf->SurfQdotConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1438 :
1439 801 : state.dataHeatBalSurf->SurfQRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1440 801 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1441 :
1442 801 : state.dataHeatBalSurf->SurfQRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1443 801 : state.dataHeatBalSurf->SurfQdotRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1444 801 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1445 :
1446 801 : state.dataHeatBalSurf->SurfQRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1447 801 : state.dataHeatBalSurf->SurfQdotRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1448 :
1449 801 : state.dataHeatBalSurf->SurfQRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1450 801 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1451 :
1452 801 : state.dataHeatBalSurf->SurfQRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1453 801 : state.dataHeatBalSurf->SurfQdotRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1454 801 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1455 :
1456 801 : state.dataHeatBalSurf->SurfQConvOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1457 801 : state.dataHeatBalSurf->SurfQdotConvOutPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1458 801 : state.dataHeatBalSurf->SurfQdotConvOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1459 :
1460 801 : state.dataHeatBalSurf->SurfQdotRadOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1461 801 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1462 801 : state.dataHeatBalSurf->SurfQRadOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1463 :
1464 801 : state.dataHeatBalSurf->SurfQAirExtReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1465 801 : state.dataHeatBalSurf->SurfQHeatEmiReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1466 :
1467 801 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1468 801 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1469 :
1470 801 : state.dataHeatBalSurf->SurfOpaqInsFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1471 801 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1472 801 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1473 801 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1474 801 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1475 :
1476 801 : state.dataHeatBalSurf->SurfOpaqOutFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1477 801 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1478 801 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1479 801 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1480 801 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1481 :
1482 801 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1483 801 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1484 801 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1485 801 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1486 801 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1487 :
1488 801 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1489 801 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1490 801 : state.dataHeatBalSurf->SurfOpaqStorageCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1491 801 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1492 801 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1493 :
1494 801 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed.dimension(state.dataSurface->TotSurfaces, 0.0);
1495 :
1496 801 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1497 801 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1498 :
1499 801 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1500 801 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
1501 801 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
1502 :
1503 801 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1504 801 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1505 :
1506 801 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
1507 36 : state.dataHeatBalSurf->SurfTempSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1508 36 : state.dataHeatBalSurf->SurfTempUserLoc.dimension(state.dataSurface->TotSurfaces, 0.0);
1509 36 : state.dataHeatBalSurf->SurfTsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1510 36 : state.dataHeatBalSurf->SurfTuserHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1511 36 : state.dataHeatBalSurf->SurfQsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1512 36 : state.dataHeatBalSurf->SurfTsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1513 36 : state.dataHeatBalSurf->SurfTuserHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1514 36 : state.dataHeatBalSurf->SurfQsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1515 : }
1516 :
1517 801 : state.dataHeatBalFanSys->RadSysTiHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1518 801 : state.dataHeatBalFanSys->RadSysTiHBToutCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1519 801 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1520 801 : state.dataHeatBalFanSys->RadSysToHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1521 801 : state.dataHeatBalFanSys->RadSysToHBTinCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1522 801 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1523 801 : state.dataHeatBalFanSys->QRadSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1524 801 : state.dataHeatBalFanSys->TCondFDSourceNode.dimension(state.dataSurface->TotSurfaces, 15.0);
1525 801 : state.dataHeatBalFanSys->surfQRadFromHVAC.allocate(state.dataSurface->TotSurfaces);
1526 801 : state.dataHeatBalFanSys->QRadSurfAFNDuct.dimension(state.dataSurface->TotSurfaces, 0.0);
1527 :
1528 : // allocate terms used for pool surface heat balance
1529 801 : state.dataHeatBalFanSys->QPoolSurfNumerator.dimension(state.dataSurface->TotSurfaces, 0.0);
1530 801 : state.dataHeatBalFanSys->PoolHeatTransCoefs.dimension(state.dataSurface->TotSurfaces, 0.0);
1531 :
1532 : // allocate term used as sink for PV electricity
1533 801 : state.dataHeatBalFanSys->QPVSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1534 :
1535 : // Allocate the moisture balance arrays
1536 801 : state.dataMstBal->TempOutsideAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1537 801 : state.dataMstBal->RhoVaporAirOut.dimension(state.dataSurface->TotSurfaces, 0.0);
1538 801 : state.dataMstBal->RhoVaporSurfIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1539 801 : state.dataMstBal->RhoVaporAirIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1540 801 : state.dataMstBal->HConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1541 801 : state.dataMstBal->HMassConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1542 801 : state.dataMstBal->HConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1543 801 : state.dataMstBal->HMassConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1544 801 : state.dataMstBal->HSkyFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1545 801 : state.dataMstBal->HGrndFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1546 801 : state.dataMstBal->HAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1547 :
1548 801 : state.dataSurface->SurfSkySolarInc.dimension(state.dataSurface->TotSurfaces, 0);
1549 801 : state.dataSurface->SurfGndSolarInc.dimension(state.dataSurface->TotSurfaces, 0);
1550 :
1551 801 : state.dataHeatBalSurf->SurfAbsSolarExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1552 801 : state.dataHeatBalSurf->SurfAbsThermalExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1553 801 : state.dataHeatBalSurf->SurfRoughnessExt.dimension(state.dataSurface->TotSurfaces, Material::SurfaceRoughness::Invalid);
1554 801 : state.dataHeatBalSurf->SurfAbsSolarInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1555 801 : state.dataHeatBalSurf->SurfAbsThermalInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1556 :
1557 801 : DisplayString(state, "Setting up Surface Reporting Variables");
1558 : // Setup surface report variables CurrentModuleObject='Opaque Surfaces'
1559 48091 : for (int loop = 1; loop <= state.dataSurface->TotSurfaces; ++loop) {
1560 47290 : auto &surface = state.dataSurface->Surface(loop);
1561 47290 : if (!surface.HeatTransSurf) {
1562 1707 : continue;
1563 : }
1564 91166 : SetupOutputVariable(state,
1565 : "Surface Inside Face Temperature",
1566 : Constant::Units::C,
1567 45583 : state.dataHeatBalSurf->SurfTempIn(loop),
1568 : OutputProcessor::TimeStepType::Zone,
1569 : OutputProcessor::StoreType::Average,
1570 45583 : surface.Name);
1571 91166 : SetupOutputVariable(state,
1572 : "Surface Inside Face Interior Movable Insulation Temperature",
1573 : Constant::Units::C,
1574 45583 : state.dataHeatBalSurf->SurfTempInMovInsRep(loop),
1575 : OutputProcessor::TimeStepType::Zone,
1576 : OutputProcessor::StoreType::Average,
1577 45583 : surface.Name);
1578 :
1579 45583 : if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
1580 91086 : SetupOutputVariable(state,
1581 : "Surface Outside Face Temperature",
1582 : Constant::Units::C,
1583 45543 : state.dataHeatBalSurf->SurfTempOut(loop),
1584 : OutputProcessor::TimeStepType::Zone,
1585 : OutputProcessor::StoreType::Average,
1586 45543 : surface.Name);
1587 : }
1588 :
1589 91166 : SetupOutputVariable(state,
1590 : "Surface Inside Face Adjacent Air Temperature",
1591 : Constant::Units::C,
1592 45583 : state.dataHeatBal->SurfTempEffBulkAir(loop),
1593 : OutputProcessor::TimeStepType::Zone,
1594 : OutputProcessor::StoreType::Average,
1595 45583 : surface.Name);
1596 91166 : SetupOutputVariable(state,
1597 : "Surface Inside Face Convection Heat Transfer Coefficient",
1598 : Constant::Units::W_m2K,
1599 45583 : state.dataHeatBalSurf->SurfHConvInt(loop),
1600 : OutputProcessor::TimeStepType::Zone,
1601 : OutputProcessor::StoreType::Average,
1602 45583 : surface.Name);
1603 91166 : SetupOutputVariable(state,
1604 : "Surface Inside Face Convection Heat Gain Rate",
1605 : Constant::Units::W,
1606 45583 : state.dataHeatBalSurf->SurfQdotConvInRep(loop),
1607 : OutputProcessor::TimeStepType::Zone,
1608 : OutputProcessor::StoreType::Average,
1609 45583 : surface.Name);
1610 91166 : SetupOutputVariable(state,
1611 : "Surface Inside Face Convection Heat Gain Rate per Area",
1612 : Constant::Units::W_m2,
1613 45583 : state.dataHeatBalSurf->SurfQdotConvInPerArea(loop),
1614 : OutputProcessor::TimeStepType::Zone,
1615 : OutputProcessor::StoreType::Average,
1616 45583 : surface.Name);
1617 91166 : SetupOutputVariable(state,
1618 : "Surface Inside Face Convection Heat Gain Energy",
1619 : Constant::Units::J,
1620 45583 : state.dataHeatBalSurf->SurfQConvInRep(loop),
1621 : OutputProcessor::TimeStepType::Zone,
1622 : OutputProcessor::StoreType::Sum,
1623 45583 : surface.Name);
1624 :
1625 91166 : SetupOutputVariable(state,
1626 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate",
1627 : Constant::Units::W,
1628 45583 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(loop),
1629 : OutputProcessor::TimeStepType::Zone,
1630 : OutputProcessor::StoreType::Average,
1631 45583 : surface.Name);
1632 91166 : SetupOutputVariable(state,
1633 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate per Area",
1634 : Constant::Units::W_m2,
1635 45583 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(loop),
1636 : OutputProcessor::TimeStepType::Zone,
1637 : OutputProcessor::StoreType::Average,
1638 45583 : surface.Name);
1639 91166 : SetupOutputVariable(state,
1640 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy",
1641 : Constant::Units::J,
1642 45583 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(loop),
1643 : OutputProcessor::TimeStepType::Zone,
1644 : OutputProcessor::StoreType::Sum,
1645 45583 : surface.Name);
1646 :
1647 45583 : if (surface.Class != DataSurfaces::SurfaceClass::Window) {
1648 78448 : SetupOutputVariable(state,
1649 : "Surface Inside Face Solar Radiation Heat Gain Rate",
1650 : Constant::Units::W,
1651 39224 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(loop),
1652 : OutputProcessor::TimeStepType::Zone,
1653 : OutputProcessor::StoreType::Average,
1654 39224 : surface.Name);
1655 78448 : SetupOutputVariable(state,
1656 : "Surface Inside Face Solar Radiation Heat Gain Rate per Area",
1657 : Constant::Units::W_m2,
1658 39224 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(loop),
1659 : OutputProcessor::TimeStepType::Zone,
1660 : OutputProcessor::StoreType::Average,
1661 39224 : surface.Name);
1662 78448 : SetupOutputVariable(state,
1663 : "Surface Inside Face Solar Radiation Heat Gain Energy",
1664 : Constant::Units::J,
1665 39224 : state.dataHeatBalSurf->SurfQRadSolarInRep(loop),
1666 : OutputProcessor::TimeStepType::Zone,
1667 : OutputProcessor::StoreType::Sum,
1668 39224 : surface.Name);
1669 :
1670 78448 : SetupOutputVariable(state,
1671 : "Surface Inside Face Lights Radiation Heat Gain Rate",
1672 : Constant::Units::W,
1673 39224 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(loop),
1674 : OutputProcessor::TimeStepType::Zone,
1675 : OutputProcessor::StoreType::Average,
1676 39224 : surface.Name);
1677 78448 : SetupOutputVariable(state,
1678 : "Surface Inside Face Lights Radiation Heat Gain Rate per Area",
1679 : Constant::Units::W_m2,
1680 39224 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(loop),
1681 : OutputProcessor::TimeStepType::Zone,
1682 : OutputProcessor::StoreType::Average,
1683 39224 : surface.Name);
1684 78448 : SetupOutputVariable(state,
1685 : "Surface Inside Face Lights Radiation Heat Gain Energy",
1686 : Constant::Units::J,
1687 39224 : state.dataHeatBalSurf->SurfQRadLightsInRep(loop),
1688 : OutputProcessor::TimeStepType::Zone,
1689 : OutputProcessor::StoreType::Sum,
1690 39224 : surface.Name);
1691 : }
1692 :
1693 91166 : SetupOutputVariable(state,
1694 : "Surface Inside Face Internal Gains Radiation Heat Gain Rate",
1695 : Constant::Units::W,
1696 45583 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(loop),
1697 : OutputProcessor::TimeStepType::Zone,
1698 : OutputProcessor::StoreType::Average,
1699 45583 : surface.Name);
1700 91166 : SetupOutputVariable(state,
1701 : "Surface Inside Face Internal Gains Radiation Heat Gain Rate per Area",
1702 : Constant::Units::W_m2,
1703 45583 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(loop),
1704 : OutputProcessor::TimeStepType::Zone,
1705 : OutputProcessor::StoreType::Average,
1706 45583 : surface.Name);
1707 91166 : SetupOutputVariable(state,
1708 : "Surface Inside Face Internal Gains Radiation Heat Gain Energy",
1709 : Constant::Units::J,
1710 45583 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(loop),
1711 : OutputProcessor::TimeStepType::Zone,
1712 : OutputProcessor::StoreType::Sum,
1713 45583 : surface.Name);
1714 :
1715 91166 : SetupOutputVariable(state,
1716 : "Surface Inside Face System Radiation Heat Gain Rate",
1717 : Constant::Units::W,
1718 45583 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(loop),
1719 : OutputProcessor::TimeStepType::Zone,
1720 : OutputProcessor::StoreType::Average,
1721 45583 : surface.Name);
1722 91166 : SetupOutputVariable(state,
1723 : "Surface Inside Face System Radiation Heat Gain Rate per Area",
1724 : Constant::Units::W_m2,
1725 45583 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(loop),
1726 : OutputProcessor::TimeStepType::Zone,
1727 : OutputProcessor::StoreType::Average,
1728 45583 : surface.Name);
1729 91166 : SetupOutputVariable(state,
1730 : "Surface Inside Face System Radiation Heat Gain Energy",
1731 : Constant::Units::J,
1732 45583 : state.dataHeatBalSurf->SurfQRadHVACInRep(loop),
1733 : OutputProcessor::TimeStepType::Zone,
1734 : OutputProcessor::StoreType::Sum,
1735 45583 : surface.Name);
1736 :
1737 45583 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment || state.dataGlobal->DisplayAdvancedReportVariables) {
1738 36864 : SetupOutputVariable(state,
1739 : "Surface Outside Face Outdoor Air Drybulb Temperature",
1740 : Constant::Units::C,
1741 18432 : state.dataSurface->SurfOutDryBulbTemp(loop),
1742 : OutputProcessor::TimeStepType::Zone,
1743 : OutputProcessor::StoreType::Average,
1744 18432 : surface.Name);
1745 36864 : SetupOutputVariable(state,
1746 : "Surface Outside Face Outdoor Air Wetbulb Temperature",
1747 : Constant::Units::C,
1748 18432 : state.dataSurface->SurfOutWetBulbTemp(loop),
1749 : OutputProcessor::TimeStepType::Zone,
1750 : OutputProcessor::StoreType::Average,
1751 18432 : surface.Name);
1752 36864 : SetupOutputVariable(state,
1753 : "Surface Outside Face Outdoor Air Wind Speed",
1754 : Constant::Units::m_s,
1755 18432 : state.dataSurface->SurfOutWindSpeed(loop),
1756 : OutputProcessor::TimeStepType::Zone,
1757 : OutputProcessor::StoreType::Average,
1758 18432 : surface.Name);
1759 36864 : SetupOutputVariable(state,
1760 : "Surface Outside Face Outdoor Air Wind Direction",
1761 : Constant::Units::deg,
1762 18432 : state.dataSurface->SurfOutWindDir(loop),
1763 : OutputProcessor::TimeStepType::Zone,
1764 : OutputProcessor::StoreType::Average,
1765 18432 : surface.Name);
1766 36864 : SetupOutputVariable(state,
1767 : "Surface Outside Face Convection Heat Gain Rate",
1768 : Constant::Units::W,
1769 18432 : state.dataHeatBalSurf->SurfQdotConvOutRep(loop),
1770 : OutputProcessor::TimeStepType::Zone,
1771 : OutputProcessor::StoreType::Average,
1772 18432 : surface.Name);
1773 36864 : SetupOutputVariable(state,
1774 : "Surface Outside Face Convection Heat Gain Rate per Area",
1775 : Constant::Units::W_m2,
1776 18432 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(loop),
1777 : OutputProcessor::TimeStepType::Zone,
1778 : OutputProcessor::StoreType::Average,
1779 18432 : surface.Name);
1780 36864 : SetupOutputVariable(state,
1781 : "Surface Outside Face Convection Heat Gain Energy",
1782 : Constant::Units::J,
1783 18432 : state.dataHeatBalSurf->SurfQConvOutReport(loop),
1784 : OutputProcessor::TimeStepType::Zone,
1785 : OutputProcessor::StoreType::Sum,
1786 18432 : surface.Name);
1787 36864 : SetupOutputVariable(state,
1788 : "Surface Outside Face Convection Heat Transfer Coefficient",
1789 : Constant::Units::W_m2K,
1790 18432 : state.dataHeatBalSurf->SurfHConvExt(loop),
1791 : OutputProcessor::TimeStepType::Zone,
1792 : OutputProcessor::StoreType::Average,
1793 18432 : surface.Name);
1794 36864 : SetupOutputVariable(state,
1795 : "Surface Outside Face Net Thermal Radiation Heat Gain Rate",
1796 : Constant::Units::W,
1797 18432 : state.dataHeatBalSurf->SurfQdotRadOutRep(loop),
1798 : OutputProcessor::TimeStepType::Zone,
1799 : OutputProcessor::StoreType::Average,
1800 18432 : surface.Name);
1801 36864 : SetupOutputVariable(state,
1802 : "Surface Outside Face Net Thermal Radiation Heat Gain Rate per Area",
1803 : Constant::Units::W_m2,
1804 18432 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(loop),
1805 : OutputProcessor::TimeStepType::Zone,
1806 : OutputProcessor::StoreType::Average,
1807 18432 : surface.Name);
1808 36864 : SetupOutputVariable(state,
1809 : "Surface Outside Face Net Thermal Radiation Heat Gain Energy",
1810 : Constant::Units::J,
1811 18432 : state.dataHeatBalSurf->SurfQRadOutReport(loop),
1812 : OutputProcessor::TimeStepType::Zone,
1813 : OutputProcessor::StoreType::Sum,
1814 18432 : surface.Name);
1815 36864 : SetupOutputVariable(state,
1816 : "Surface Outside Face Thermal Radiation to Air Heat Transfer Coefficient",
1817 : Constant::Units::W_m2K,
1818 18432 : state.dataHeatBalSurf->SurfHAirExt(loop),
1819 : OutputProcessor::TimeStepType::Zone,
1820 : OutputProcessor::StoreType::Average,
1821 18432 : surface.Name);
1822 36864 : SetupOutputVariable(state,
1823 : "Surface Outside Face Thermal Radiation to Sky Heat Transfer Coefficient",
1824 : Constant::Units::W_m2K,
1825 18432 : state.dataHeatBalSurf->SurfHSkyExt(loop),
1826 : OutputProcessor::TimeStepType::Zone,
1827 : OutputProcessor::StoreType::Average,
1828 18432 : surface.Name);
1829 36864 : SetupOutputVariable(state,
1830 : "Surface Outside Face Thermal Radiation to Ground Heat Transfer Coefficient",
1831 : Constant::Units::W_m2K,
1832 18432 : state.dataHeatBalSurf->SurfHGrdExt(loop),
1833 : OutputProcessor::TimeStepType::Zone,
1834 : OutputProcessor::StoreType::Average,
1835 18432 : surface.Name);
1836 36864 : SetupOutputVariable(state,
1837 : "Surface Outside Face Thermal Radiation to Air Heat Transfer Rate",
1838 : Constant::Units::W,
1839 18432 : state.dataHeatBalSurf->SurfQAirExtReport(loop),
1840 : OutputProcessor::TimeStepType::Zone,
1841 : OutputProcessor::StoreType::Average,
1842 18432 : surface.Name);
1843 36864 : SetupOutputVariable(state,
1844 : "Surface Outside Face Heat Emission to Air Rate",
1845 : Constant::Units::W,
1846 18432 : state.dataHeatBalSurf->SurfQHeatEmiReport(loop),
1847 : OutputProcessor::TimeStepType::Zone,
1848 : OutputProcessor::StoreType::Average,
1849 18432 : surface.Name);
1850 :
1851 18432 : if (surface.Class != DataSurfaces::SurfaceClass::Window) {
1852 24174 : SetupOutputVariable(state,
1853 : "Surface Outside Face Solar Radiation Heat Gain Rate",
1854 : Constant::Units::W,
1855 12087 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(loop),
1856 : OutputProcessor::TimeStepType::Zone,
1857 : OutputProcessor::StoreType::Average,
1858 12087 : surface.Name);
1859 24174 : SetupOutputVariable(state,
1860 : "Surface Outside Face Solar Radiation Heat Gain Rate per Area",
1861 : Constant::Units::W_m2,
1862 12087 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(loop),
1863 : OutputProcessor::TimeStepType::Zone,
1864 : OutputProcessor::StoreType::Average,
1865 12087 : surface.Name);
1866 24174 : SetupOutputVariable(state,
1867 : "Surface Outside Face Solar Radiation Heat Gain Energy",
1868 : Constant::Units::J,
1869 12087 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(loop),
1870 : OutputProcessor::TimeStepType::Zone,
1871 : OutputProcessor::StoreType::Sum,
1872 12087 : surface.Name);
1873 : }
1874 : }
1875 45583 : if (surface.Class == DataSurfaces::SurfaceClass::Floor || surface.Class == DataSurfaces::SurfaceClass::Wall ||
1876 15338 : surface.Class == DataSurfaces::SurfaceClass::IntMass || surface.Class == DataSurfaces::SurfaceClass::Roof ||
1877 6843 : surface.Class == DataSurfaces::SurfaceClass::Door) {
1878 : // IF (DisplayAdvancedReportVariables) THEN !CurrentModuleObject='Opaque Surfaces(Advanced)'
1879 78442 : SetupOutputVariable(state,
1880 : "Surface Inside Face Conduction Heat Transfer Rate",
1881 : Constant::Units::W,
1882 39221 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(loop),
1883 : OutputProcessor::TimeStepType::Zone,
1884 : OutputProcessor::StoreType::Average,
1885 39221 : surface.Name);
1886 78442 : SetupOutputVariable(state,
1887 : "Surface Inside Face Conduction Heat Gain Rate",
1888 : Constant::Units::W,
1889 39221 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(loop),
1890 : OutputProcessor::TimeStepType::Zone,
1891 : OutputProcessor::StoreType::Average,
1892 39221 : surface.Name);
1893 78442 : SetupOutputVariable(state,
1894 : "Surface Inside Face Conduction Heat Loss Rate",
1895 : Constant::Units::W,
1896 39221 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(loop),
1897 : OutputProcessor::TimeStepType::Zone,
1898 : OutputProcessor::StoreType::Average,
1899 39221 : surface.Name);
1900 78442 : SetupOutputVariable(state,
1901 : "Surface Inside Face Conduction Heat Transfer Rate per Area",
1902 : Constant::Units::W_m2,
1903 39221 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(loop),
1904 : OutputProcessor::TimeStepType::Zone,
1905 : OutputProcessor::StoreType::Average,
1906 39221 : surface.Name);
1907 78442 : SetupOutputVariable(state,
1908 : "Surface Inside Face Conduction Heat Transfer Energy",
1909 : Constant::Units::J,
1910 39221 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(loop),
1911 : OutputProcessor::TimeStepType::Zone,
1912 : OutputProcessor::StoreType::Sum,
1913 39221 : surface.Name);
1914 :
1915 39221 : if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
1916 78362 : SetupOutputVariable(state,
1917 : "Surface Outside Face Conduction Heat Transfer Rate",
1918 : Constant::Units::W,
1919 39181 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(loop),
1920 : OutputProcessor::TimeStepType::Zone,
1921 : OutputProcessor::StoreType::Average,
1922 39181 : surface.Name);
1923 78362 : SetupOutputVariable(state,
1924 : "Surface Outside Face Conduction Heat Gain Rate",
1925 : Constant::Units::W,
1926 39181 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(loop),
1927 : OutputProcessor::TimeStepType::Zone,
1928 : OutputProcessor::StoreType::Average,
1929 39181 : surface.Name);
1930 78362 : SetupOutputVariable(state,
1931 : "Surface Outside Face Conduction Heat Loss Rate",
1932 : Constant::Units::W,
1933 39181 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(loop),
1934 : OutputProcessor::TimeStepType::Zone,
1935 : OutputProcessor::StoreType::Average,
1936 39181 : surface.Name);
1937 78362 : SetupOutputVariable(state,
1938 : "Surface Outside Face Conduction Heat Transfer Rate per Area",
1939 : Constant::Units::W_m2,
1940 39181 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(loop),
1941 : OutputProcessor::TimeStepType::Zone,
1942 : OutputProcessor::StoreType::Average,
1943 39181 : surface.Name);
1944 78362 : SetupOutputVariable(state,
1945 : "Surface Outside Face Conduction Heat Transfer Energy",
1946 : Constant::Units::J,
1947 39181 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(loop),
1948 : OutputProcessor::TimeStepType::Zone,
1949 : OutputProcessor::StoreType::Sum,
1950 39181 : surface.Name);
1951 :
1952 78362 : SetupOutputVariable(state,
1953 : "Surface Average Face Conduction Heat Transfer Rate",
1954 : Constant::Units::W,
1955 39181 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(loop),
1956 : OutputProcessor::TimeStepType::Zone,
1957 : OutputProcessor::StoreType::Average,
1958 39181 : surface.Name);
1959 78362 : SetupOutputVariable(state,
1960 : "Surface Average Face Conduction Heat Gain Rate",
1961 : Constant::Units::W,
1962 39181 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(loop),
1963 : OutputProcessor::TimeStepType::Zone,
1964 : OutputProcessor::StoreType::Average,
1965 39181 : surface.Name);
1966 78362 : SetupOutputVariable(state,
1967 : "Surface Average Face Conduction Heat Loss Rate",
1968 : Constant::Units::W,
1969 39181 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(loop),
1970 : OutputProcessor::TimeStepType::Zone,
1971 : OutputProcessor::StoreType::Average,
1972 39181 : surface.Name);
1973 78362 : SetupOutputVariable(state,
1974 : "Surface Average Face Conduction Heat Transfer Rate per Area",
1975 : Constant::Units::W_m2,
1976 39181 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(loop),
1977 : OutputProcessor::TimeStepType::Zone,
1978 : OutputProcessor::StoreType::Average,
1979 39181 : surface.Name);
1980 78362 : SetupOutputVariable(state,
1981 : "Surface Average Face Conduction Heat Transfer Energy",
1982 : Constant::Units::J,
1983 39181 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(loop),
1984 : OutputProcessor::TimeStepType::Zone,
1985 : OutputProcessor::StoreType::Sum,
1986 39181 : surface.Name);
1987 :
1988 78362 : SetupOutputVariable(state,
1989 : "Surface Heat Storage Rate",
1990 : Constant::Units::W,
1991 39181 : state.dataHeatBalSurf->SurfOpaqStorageCond(loop),
1992 : OutputProcessor::TimeStepType::Zone,
1993 : OutputProcessor::StoreType::Average,
1994 39181 : surface.Name);
1995 78362 : SetupOutputVariable(state,
1996 : "Surface Heat Storage Gain Rate",
1997 : Constant::Units::W,
1998 39181 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(loop),
1999 : OutputProcessor::TimeStepType::Zone,
2000 : OutputProcessor::StoreType::Average,
2001 39181 : surface.Name);
2002 78362 : SetupOutputVariable(state,
2003 : "Surface Heat Storage Loss Rate",
2004 : Constant::Units::W,
2005 39181 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(loop),
2006 : OutputProcessor::TimeStepType::Zone,
2007 : OutputProcessor::StoreType::Average,
2008 39181 : surface.Name);
2009 78362 : SetupOutputVariable(state,
2010 : "Surface Heat Storage Rate per Area",
2011 : Constant::Units::W_m2,
2012 39181 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux(loop),
2013 : OutputProcessor::TimeStepType::Zone,
2014 : OutputProcessor::StoreType::Average,
2015 39181 : surface.Name);
2016 78362 : SetupOutputVariable(state,
2017 : "Surface Heat Storage Energy",
2018 : Constant::Units::J,
2019 39181 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(loop),
2020 : OutputProcessor::TimeStepType::Zone,
2021 : OutputProcessor::StoreType::Sum,
2022 39181 : surface.Name);
2023 : }
2024 :
2025 : // ENDIF
2026 : // CurrentModuleObject='Opaque Surfaces'
2027 :
2028 78442 : SetupOutputVariable(state,
2029 : "Surface Inside Face Beam Solar Radiation Heat Gain Rate",
2030 : Constant::Units::W,
2031 39221 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(loop),
2032 : OutputProcessor::TimeStepType::Zone,
2033 : OutputProcessor::StoreType::Average,
2034 39221 : surface.Name);
2035 : }
2036 45583 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
2037 284 : SetupOutputVariable(state,
2038 : "Surface Internal Source Location Temperature",
2039 : Constant::Units::C,
2040 142 : state.dataHeatBalSurf->SurfTempSource(loop),
2041 : OutputProcessor::TimeStepType::Zone,
2042 : OutputProcessor::StoreType::Average,
2043 142 : surface.Name);
2044 284 : SetupOutputVariable(state,
2045 : "Surface Internal User Specified Location Temperature",
2046 : Constant::Units::C,
2047 142 : state.dataHeatBalSurf->SurfTempUserLoc(loop),
2048 : OutputProcessor::TimeStepType::Zone,
2049 : OutputProcessor::StoreType::Average,
2050 142 : surface.Name);
2051 : }
2052 :
2053 45583 : if (surface.Class == DataSurfaces::SurfaceClass::Window) { // CurrentModuleObject='Windows'
2054 6359 : auto &surfShade = state.dataSurface->surfShades(loop);
2055 12718 : SetupOutputVariable(state,
2056 : "Surface Shading Device Is On Time Fraction",
2057 : Constant::Units::None,
2058 6359 : state.dataSurface->SurfWinFracTimeShadingDeviceOn(loop),
2059 : OutputProcessor::TimeStepType::Zone,
2060 : OutputProcessor::StoreType::Average,
2061 6359 : surface.Name);
2062 6359 : SetupOutputVariable(state,
2063 : "Surface Storm Window On Off Status",
2064 : Constant::Units::None,
2065 6359 : state.dataSurface->SurfWinStormWinFlag(loop),
2066 : OutputProcessor::TimeStepType::Zone,
2067 : OutputProcessor::StoreType::Average,
2068 6359 : surface.Name);
2069 12718 : SetupOutputVariable(state,
2070 : "Surface Window Blind Slat Angle",
2071 : Constant::Units::deg,
2072 6359 : surfShade.blind.slatAngDeg,
2073 : OutputProcessor::TimeStepType::Zone,
2074 : OutputProcessor::StoreType::Average,
2075 6359 : surface.Name);
2076 : }
2077 : // IF (DisplayAdvancedReportVariables) THEN !CurrentModuleObject='Opaque Surfaces(Advanced)'
2078 45583 : SetupOutputVariable(state,
2079 : "Surface Inside Face Convection Classification Index",
2080 : Constant::Units::None,
2081 45583 : state.dataSurface->surfIntConv(loop).convClassRpt,
2082 : OutputProcessor::TimeStepType::Zone,
2083 : OutputProcessor::StoreType::Average,
2084 45583 : surface.Name);
2085 45583 : SetupOutputVariable(state,
2086 : "Surface Inside Face Convection Model Equation Index",
2087 : Constant::Units::None,
2088 45583 : state.dataSurface->surfIntConv(loop).hcModelEqRpt,
2089 : OutputProcessor::TimeStepType::Zone,
2090 : OutputProcessor::StoreType::Average,
2091 45583 : surface.Name);
2092 45583 : SetupOutputVariable(state,
2093 : "Surface Inside Face Convection Reference Air Index",
2094 : Constant::Units::None,
2095 45583 : state.dataSurface->SurfTAirRefRpt(loop),
2096 : OutputProcessor::TimeStepType::Zone,
2097 : OutputProcessor::StoreType::Average,
2098 45583 : surface.Name);
2099 45583 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
2100 18172 : SetupOutputVariable(state,
2101 : "Surface Outside Face Convection Classification Index",
2102 : Constant::Units::None,
2103 18172 : state.dataSurface->surfExtConv(loop).convClassRpt,
2104 : OutputProcessor::TimeStepType::Zone,
2105 : OutputProcessor::StoreType::Average,
2106 18172 : surface.Name);
2107 18172 : SetupOutputVariable(state,
2108 : "Surface Outside Face Forced Convection Model Equation Index",
2109 : Constant::Units::None,
2110 18172 : state.dataSurface->surfExtConv(loop).hfModelEqRpt,
2111 : OutputProcessor::TimeStepType::Zone,
2112 : OutputProcessor::StoreType::Average,
2113 18172 : surface.Name);
2114 18172 : SetupOutputVariable(state,
2115 : "Surface Outside Face Natural Convection Model Equation Index",
2116 : Constant::Units::None,
2117 18172 : state.dataSurface->surfExtConv(loop).hnModelEqRpt,
2118 : OutputProcessor::TimeStepType::Zone,
2119 : OutputProcessor::StoreType::Average,
2120 18172 : surface.Name);
2121 : }
2122 :
2123 91166 : SetupOutputVariable(state,
2124 : "Surface Inside Face Heat Source Gain Rate per Area",
2125 : Constant::Units::W_m2,
2126 45583 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(loop),
2127 : OutputProcessor::TimeStepType::Zone,
2128 : OutputProcessor::StoreType::Average,
2129 45583 : surface.Name);
2130 91166 : SetupOutputVariable(state,
2131 : "Surface Outside Face Heat Source Gain Rate per Area",
2132 : Constant::Units::W_m2,
2133 45583 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(loop),
2134 : OutputProcessor::TimeStepType::Zone,
2135 : OutputProcessor::StoreType::Average,
2136 45583 : surface.Name);
2137 :
2138 : // ENDIF
2139 45583 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
2140 596 : SetupOutputVariable(state,
2141 : "Surface Construction Index",
2142 : Constant::Units::None,
2143 596 : surface.Construction,
2144 : OutputProcessor::TimeStepType::Zone,
2145 : OutputProcessor::StoreType::Average,
2146 596 : surface.Name);
2147 : }
2148 : }
2149 3204 : SetupOutputVariable(state,
2150 : "Site Total Surface Heat Emission to Air",
2151 : Constant::Units::J,
2152 801 : state.dataHeatBalSurf->SumSurfaceHeatEmission,
2153 : OutputProcessor::TimeStepType::Zone,
2154 : OutputProcessor::StoreType::Sum,
2155 : "Environment");
2156 801 : }
2157 :
2158 6496 : void InitThermalAndFluxHistories(EnergyPlusData &state)
2159 : {
2160 :
2161 : // SUBROUTINE INFORMATION:
2162 : // AUTHOR George Walton
2163 : // DATE WRITTEN March 1978
2164 : // RE-ENGINEERED Feb98 (RKS)
2165 :
2166 : // PURPOSE OF THIS SUBROUTINE:
2167 : // This subroutine sets the initial temperature and flux histories
2168 : // needed for a stable and reasonable heat balance solution starting
2169 : // point.
2170 :
2171 : // METHODOLOGY EMPLOYED:
2172 : // This subroutine assumes that the simulation is at steady state at
2173 : // the beginning and then begins to vary. Thus, the temperatures, the
2174 : // fluxes. and their histories can all be set to the same value. Some
2175 : // of the initializations depend on the surface characteristics. This
2176 : // requires a DO loop to perform the proper calculation.
2177 :
2178 : // REFERENCES:
2179 : // (I)BLAST legacy routine INITTH
2180 :
2181 : // First do the "bulk" initializations of arrays sized to NumOfZones
2182 57005 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2183 50509 : new (&state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum)) ZoneTempPredictorCorrector::ZoneHeatBalanceData();
2184 : // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
2185 50509 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
2186 50509 : thisZoneHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
2187 50509 : thisZoneHB.airHumRat = state.dataEnvrn->OutHumRat;
2188 50509 : state.dataHeatBalFanSys->TempTstatAir(zoneNum) = DataHeatBalance::ZoneInitialTemp;
2189 : }
2190 56995 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
2191 50499 : thisEnclosure.MRT = DataHeatBalance::ZoneInitialTemp;
2192 6496 : }
2193 : // Reset spaceHeatBalance even if doSpaceHeatBalance is false, because spaceHB is used to gether zoneHB in some cases
2194 57149 : for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
2195 50653 : new (&thisSpaceHB) ZoneTempPredictorCorrector::SpaceHeatBalanceData();
2196 : // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
2197 50653 : thisSpaceHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
2198 50653 : thisSpaceHB.airHumRat = state.dataEnvrn->OutHumRat;
2199 6496 : }
2200 :
2201 : // "Bulk" initializations of arrays sized to TotSurfaces
2202 57005 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2203 101162 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2204 50653 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2205 50653 : int const firstSurf = thisSpace.HTSurfaceFirst;
2206 50653 : int const lastSurf = thisSpace.HTSurfaceLast;
2207 494569 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2208 443916 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = DataHeatBalance::SurfInitialTemp;
2209 443916 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp; // module level array
2210 443916 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = DataHeatBalance::SurfInitialTemp; // module level array
2211 443916 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) = DataHeatBalance::SurfInitialConvCoeff; // module level array
2212 443916 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
2213 443916 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
2214 443916 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
2215 443916 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
2216 443916 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = 0.0;
2217 443916 : state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = 0.0;
2218 443916 : state.dataHeatBalSurf->SurfQConvInRep(SurfNum) = 0.0;
2219 443916 : state.dataHeatBalSurf->SurfQdotConvInRep(SurfNum) = 0.0;
2220 443916 : state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum) = 0.0;
2221 443916 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(SurfNum) = 0.0;
2222 443916 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(SurfNum) = 0.0;
2223 443916 : state.dataHeatBalSurf->SurfQRadSolarInRep(SurfNum) = 0.0;
2224 443916 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(SurfNum) = 0.0;
2225 443916 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(SurfNum) = 0.0;
2226 443916 : state.dataHeatBalSurf->SurfQRadLightsInRep(SurfNum) = 0.0;
2227 443916 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(SurfNum) = 0.0;
2228 443916 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(SurfNum) = 0.0;
2229 443916 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(SurfNum) = 0.0;
2230 443916 : state.dataHeatBalSurf->SurfQRadHVACInRep(SurfNum) = 0.0;
2231 443916 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(SurfNum) = 0.0;
2232 443916 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) = 0.0;
2233 443916 : state.dataHeatBalSurf->SurfQConvOutReport(SurfNum) = 0.0;
2234 443916 : state.dataHeatBalSurf->SurfQdotConvOutRep(SurfNum) = 0.0;
2235 443916 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = 0.0;
2236 443916 : state.dataHeatBalSurf->SurfQRadOutReport(SurfNum) = 0.0;
2237 443916 : state.dataHeatBalSurf->SurfQdotRadOutRep(SurfNum) = 0.0;
2238 443916 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = 0.0;
2239 443916 : state.dataHeatBalSurf->SurfQAirExtReport(SurfNum) = 0.0;
2240 443916 : state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) = 0.0;
2241 : } // end of Surf array
2242 50653 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
2243 50653 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
2244 50653 : if (firstSurfOpaq >= 0) {
2245 432364 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
2246 381711 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = 0.0;
2247 381711 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 0.0;
2248 381711 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(SurfNum) = 0.0;
2249 381711 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
2250 : } // end of Zone Surf
2251 : }
2252 50653 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2253 50653 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2254 50653 : if (firstSurfWin >= 0) {
2255 112848 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2256 : // Initialize window frame and divider temperatures
2257 62195 : state.dataSurface->SurfWinFrameTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
2258 62195 : state.dataSurface->SurfWinFrameTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
2259 62195 : state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
2260 62195 : state.dataSurface->SurfWinDividerTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
2261 62195 : state.dataSurface->SurfWinDividerTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
2262 62195 : state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
2263 :
2264 : // Initialize previous-timestep shading indicators
2265 62195 : state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) = DataSurfaces::WinShadingType::NoShade;
2266 62195 : state.dataSurface->SurfWinShadingFlag(SurfNum) = DataSurfaces::WinShadingType::NoShade;
2267 : } // end of Zone Surf
2268 : }
2269 50509 : }
2270 : } // end of Zone
2271 :
2272 : // "Bulk" initializations of temperature arrays with dimensions (TotSurface,MaxCTFTerms,2)
2273 57005 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2274 101162 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2275 50653 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2276 50653 : int const firstSurf = thisSpace.HTSurfaceFirst;
2277 50653 : int const lastSurf = thisSpace.HTSurfaceLast;
2278 1013060 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2279 9396811 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2280 8434404 : state.dataHeatBalSurf->SurfInsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2281 8434404 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2282 8434404 : state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
2283 8434404 : state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
2284 : }
2285 : }
2286 50509 : }
2287 : }
2288 6496 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
2289 17604 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2290 32844 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2291 16470 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2292 16470 : int const firstSurf = thisSpace.HTSurfaceFirst;
2293 16470 : int const lastSurf = thisSpace.HTSurfaceLast;
2294 170451 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2295 153981 : state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
2296 : }
2297 329400 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2298 3238569 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2299 2925639 : state.dataHeatBalSurf->SurfInsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2300 2925639 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2301 2925639 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
2302 2925639 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
2303 : }
2304 : }
2305 16374 : }
2306 : }
2307 : }
2308 6496 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
2309 1170 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2310 1770 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2311 885 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2312 885 : int const firstSurf = thisSpace.HTSurfaceFirst;
2313 885 : int const lastSurf = thisSpace.HTSurfaceLast;
2314 7313 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2315 128560 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2316 122132 : state.dataHeatBalSurf->SurfTsrcHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2317 122132 : state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2318 122132 : state.dataHeatBalSurf->SurfTuserHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2319 122132 : state.dataHeatBalSurf->SurfTuserHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2320 122132 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, CTFTermNum) = 0.0;
2321 122132 : state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, CTFTermNum) = 0.0;
2322 : }
2323 : }
2324 885 : }
2325 : }
2326 : }
2327 6496 : state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
2328 :
2329 : // Perform other initializations that depend on the surface characteristics
2330 72467 : for (int CTFTermNum = 1; CTFTermNum <= state.dataHeatBal->MaxCTFTerms + 1; ++CTFTermNum) {
2331 4896038 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2332 4830067 : auto &surface = state.dataSurface->Surface(SurfNum);
2333 : // Reset outside boundary conditions if necessary
2334 4830067 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
2335 1827268 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
2336 3002799 : } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
2337 224512 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
2338 224512 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
2339 2778287 : } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
2340 18169 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
2341 18169 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
2342 : }
2343 : // Initialize the flux histories
2344 4830067 : state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) =
2345 4830067 : state.dataConstruction->Construct(surface.Construction).UValue *
2346 4830067 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum));
2347 4830067 : state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2348 65971 : }
2349 : }
2350 450417 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2351 443921 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
2352 30 : state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TbaffleLast = 20.0;
2353 30 : state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TairLast = 20.0;
2354 : }
2355 6496 : }
2356 : // Initialize Kiva convection algorithms
2357 6760 : for (int SurfNum : state.dataSurface->AllHTKivaSurfaceList) {
2358 264 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = KIVA_CONST_CONV(3.076);
2359 264 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].f = KIVA_HF_DEF;
2360 264 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].out = KIVA_CONST_CONV(0.0);
2361 6496 : }
2362 6496 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
2363 155211 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2364 153981 : auto &surface = state.dataSurface->Surface(SurfNum);
2365 153981 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
2366 1133080 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2367 1076426 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
2368 : }
2369 153981 : } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
2370 88660 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2371 84227 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
2372 84227 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
2373 : }
2374 92894 : } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
2375 39820 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2376 37829 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
2377 37829 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
2378 : }
2379 : }
2380 943090 : for (int CTFTermNum = 2; CTFTermNum <= state.dataConstruction->Construct(surface.Construction).NumCTFTerms + 1; ++CTFTermNum) {
2381 789109 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2382 789109 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2383 : }
2384 1230 : }
2385 : }
2386 :
2387 6496 : if (state.dataSurface->TotOSCM >= 1) {
2388 292 : for (int OSCMnum = 1; OSCMnum <= state.dataSurface->TotOSCM; ++OSCMnum) {
2389 202 : auto &thisOSC = state.dataSurface->OSCM(OSCMnum);
2390 202 : thisOSC.TConv = 20.0;
2391 202 : thisOSC.HConv = 4.0;
2392 202 : thisOSC.TRad = 20.0;
2393 202 : thisOSC.HRad = 4.0;
2394 : }
2395 : }
2396 6496 : }
2397 :
2398 10122 : void EvalOutsideMovableInsulation(EnergyPlusData &state)
2399 : {
2400 : // This subroutine determines whether or not outside movable insulation on opaque surfaces is present at the current time.
2401 10122 : auto &s_mat = state.dataMaterial;
2402 10122 : auto &s_surf = state.dataSurface;
2403 :
2404 14169 : for (int SurfNum : s_surf->extMovInsulSurfNums) {
2405 4047 : auto &movInsul = s_surf->extMovInsuls(SurfNum);
2406 4047 : Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
2407 4047 : if (MovInsulSchedVal <= 0) { // Movable insulation not present at current time
2408 0 : movInsul.present = false;
2409 0 : int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
2410 0 : auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
2411 0 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisMaterial->AbsorpSolar;
2412 0 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisMaterial->AbsorpThermal;
2413 0 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisMaterial->Roughness;
2414 0 : continue;
2415 0 : }
2416 :
2417 4047 : auto const *mat = s_mat->materials(movInsul.matNum);
2418 4047 : movInsul.present = true;
2419 4047 : movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
2420 4047 : if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) {
2421 2022 : auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
2422 2022 : assert(matGlass != nullptr);
2423 2022 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
2424 2022 : } else {
2425 2025 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = mat->AbsorpSolar;
2426 : }
2427 4047 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = mat->AbsorpThermal;
2428 4047 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = mat->Roughness;
2429 10122 : }
2430 10122 : }
2431 :
2432 10122 : void EvalInsideMovableInsulation(EnergyPlusData &state)
2433 : {
2434 10122 : auto &s_mat = state.dataMaterial;
2435 10122 : auto &s_surf = state.dataSurface;
2436 : // This subroutine determines whether or not inside movable insulation is present at the current time.
2437 16197 : for (int SurfNum : s_surf->intMovInsulSurfNums) {
2438 6075 : auto &movInsul = s_surf->intMovInsuls(SurfNum);
2439 6075 : Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
2440 6075 : if (MovInsulSchedVal <= 0.0) { // Movable insulation not present at current time
2441 0 : movInsul.present = false;
2442 0 : int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
2443 0 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
2444 0 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
2445 0 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
2446 0 : continue;
2447 0 : }
2448 :
2449 6075 : auto const *mat = s_mat->materials(movInsul.matNum);
2450 :
2451 6075 : movInsul.present = true;
2452 6075 : movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
2453 6075 : if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) { // Glass is insulating?
2454 0 : auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
2455 0 : assert(matGlass != nullptr);
2456 0 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
2457 0 : } else {
2458 6075 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = mat->AbsorpSolar;
2459 : }
2460 6075 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = mat->AbsorpThermal;
2461 10122 : }
2462 10122 : }
2463 :
2464 2828408 : void InitSolarHeatGains(EnergyPlusData &state)
2465 : {
2466 :
2467 : // SUBROUTINE INFORMATION:
2468 : // AUTHOR Anonymous
2469 : // DATE WRITTEN July 1977
2470 : // MODIFIED Mar99 (FW): handle movable interior shades and
2471 : // switchable glazing
2472 : // Oct99 (FW): account for Window5 glass calculation approach
2473 : // May01 (FW): handle interior and exterior blinds
2474 : // Sep03 (FW): initialize SurfaceWindow%FrameQRadOutAbs
2475 : // May06 (RR): handle exterior window screens
2476 : // RE-ENGINEERED Feb98 (RKS)
2477 :
2478 : // PURPOSE OF THIS SUBROUTINE:
2479 : // This subroutine initializes the arrays associated with solar heat
2480 : // gains for both individual surfaces and for zones. As a result,
2481 : // this routine sets the following variable arrays:
2482 : // QBV(unused), QDV, QC, QD; SurfOpaqQRadSWOutAbs and SurfOpaqQRadSWInAbs (for opaque surfaces);
2483 : // SurfWinQRadSWwinAbs (for windows)
2484 :
2485 : // METHODOLOGY EMPLOYED:
2486 : // If the sun is down, all of the pertinent arrays are zeroed. If the
2487 : // sun is up, various calculations are made.
2488 :
2489 : // REFERENCES:
2490 : // (I)BLAST legacy routine QSUN
2491 :
2492 2828408 : auto &s_mat = state.dataMaterial;
2493 2828408 : auto &Surface = state.dataSurface->Surface;
2494 :
2495 : // Using/Aliasing
2496 : using Dayltg::TransTDD;
2497 : using SolarShading::CalcInteriorSolarDistribution;
2498 : using namespace DataWindowEquivalentLayer;
2499 : using SolarShading::SurfaceScheduledSolarInc;
2500 : using SolarShading::WindowScheduledSolarAbs;
2501 :
2502 : // Why are these globals?
2503 2828408 : auto &AbsDiffWin = state.dataHeatBalSurfMgr->AbsDiffWin;
2504 2828408 : auto &AbsDiffWinGnd = state.dataHeatBalSurfMgr->AbsDiffWinGnd;
2505 2828408 : auto &AbsDiffWinSky = state.dataHeatBalSurfMgr->AbsDiffWinSky;
2506 :
2507 23363819 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2508 20535411 : state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = 0.0;
2509 20535411 : state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = 0.0;
2510 20535411 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = 0.0;
2511 20535411 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = 0.0;
2512 20535411 : state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) = 0.0;
2513 20535411 : state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) = 0.0;
2514 :
2515 20535411 : state.dataHeatBal->ZoneWinHeatGain(zoneNum) = 0.0;
2516 20535411 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = 0.0;
2517 20535411 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = 0.0;
2518 20535411 : state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) = 0.0;
2519 20535411 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = 0.0;
2520 20535411 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = 0.0;
2521 20535411 : state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) = 0.0;
2522 20535411 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = 0.0;
2523 20535411 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = 0.0;
2524 : }
2525 23359775 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2526 20531367 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0;
2527 : }
2528 23363819 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2529 41119422 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2530 20584011 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2531 20584011 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
2532 20584011 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
2533 174074299 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
2534 153490288 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = 0.0;
2535 153490288 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = 0.0;
2536 153490288 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) = 0.0;
2537 153490288 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) = 0.0;
2538 153490288 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = 0.0;
2539 153490288 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum) = 0.0;
2540 153490288 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
2541 153490288 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(SurfNum) = 0.0;
2542 153490288 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(SurfNum) = 0.0;
2543 : }
2544 :
2545 20584011 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2546 20584011 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2547 44426535 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2548 : // Faster "inline" than calling SurfaceWindow( SurfNum ).InitSolarHeatGains()
2549 23842524 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = 0.0;
2550 23842524 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = 0.0;
2551 23842524 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = 0.0;
2552 23842524 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = 0.0;
2553 23842524 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = 0.0;
2554 23842524 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = 0.0;
2555 23842524 : state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) = 0.0;
2556 23842524 : state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = 0.0;
2557 23842524 : state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = 0.0;
2558 23842524 : state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0;
2559 : }
2560 :
2561 44426535 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2562 23842524 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0;
2563 23842524 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0;
2564 23842524 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0;
2565 23842524 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0;
2566 23842524 : state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0;
2567 23842524 : state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0;
2568 23842524 : state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
2569 23842524 : state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0;
2570 23842524 : state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
2571 : }
2572 44426535 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2573 23842524 : state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0;
2574 23842524 : state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0;
2575 23842524 : state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0;
2576 23842524 : state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0;
2577 23842524 : state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0;
2578 23842524 : state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
2579 23842524 : state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0;
2580 : }
2581 164672088 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
2582 310985745 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2583 166897668 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = 0.0;
2584 : }
2585 : }
2586 20535411 : }
2587 : }
2588 2828408 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
2589 48091 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2590 47290 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
2591 47290 : state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
2592 : }
2593 : }
2594 : bool currSolRadPositive =
2595 2828408 : state.dataEnvrn->SunIsUp && (state.dataEnvrn->BeamSolarRad + state.dataEnvrn->GndSolarRad + state.dataEnvrn->DifSolarRad > 0.0);
2596 2828408 : bool sunset = (!currSolRadPositive) && state.dataEnvrn->PreviousSolRadPositive;
2597 2828408 : bool sunIsUpNoRad = state.dataEnvrn->SunIsUp && (!currSolRadPositive);
2598 2828408 : bool resetSolar = state.dataGlobal->BeginEnvrnFlag || sunIsUpNoRad ||
2599 2828408 : sunset; // Reset at (1) Beginning of simulation (2) sunset time, and SunIsUp but not solar time.
2600 2828408 : state.dataEnvrn->PreviousSolRadPositive = currSolRadPositive;
2601 :
2602 2828408 : if (currSolRadPositive || resetSolar) {
2603 94215552 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2604 92782774 : state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
2605 92782774 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) = 0.0;
2606 92782774 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) = 0.0;
2607 92782774 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) = 0.0;
2608 92782774 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
2609 :
2610 92782774 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) = 0.0;
2611 92782774 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = 0.0;
2612 92782774 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = 0.0;
2613 92782774 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = 0.0;
2614 :
2615 92782774 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) = 0.0;
2616 92782774 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) = 0.0;
2617 92782774 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = 0.0;
2618 92782774 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) = 0.0;
2619 92782774 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = 0.0;
2620 :
2621 92782774 : state.dataSurface->SurfSkySolarInc(SurfNum) = 0.0;
2622 92782774 : state.dataSurface->SurfGndSolarInc(SurfNum) = 0.0;
2623 : }
2624 11873427 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2625 10440649 : state.dataHeatBal->ZoneTransSolar(enclNum) = 0.0;
2626 10440649 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclNum) = 0.0;
2627 10440649 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclNum) = 0.0;
2628 10440649 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclNum) = 0.0;
2629 10440649 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclNum) = 0.0;
2630 10440649 : state.dataHeatBal->ZoneTransSolarEnergy(enclNum) = 0.0;
2631 10440649 : state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclNum) = 0.0;
2632 10440649 : state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclNum) = 0.0;
2633 10440649 : state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclNum) = 0.0;
2634 10440649 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0;
2635 : }
2636 11875495 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2637 20910274 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2638 10467557 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2639 10467557 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2640 10467557 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2641 22644370 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2642 12176813 : state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = 0.0;
2643 12176813 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = 0.0;
2644 12176813 : state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = 0.0;
2645 12176813 : state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum) = 0.0;
2646 12176813 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
2647 12176813 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0;
2648 12176813 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0;
2649 12176813 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum) = 0.0;
2650 12176813 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum) = 0.0;
2651 12176813 : state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0;
2652 : }
2653 22644370 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2654 12176813 : state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = 0.0;
2655 12176813 : state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = 0.0;
2656 12176813 : state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = 0.0;
2657 12176813 : state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = 0.0;
2658 12176813 : state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = 0.0;
2659 12176813 : state.dataSurface->SurfWinScTsolBmBm(SurfNum) = 0.0;
2660 12176813 : state.dataSurface->SurfWinScTsolBmDif(SurfNum) = 0.0;
2661 12176813 : state.dataSurface->SurfWinScTsolDifDif(SurfNum) = 0.0;
2662 12176813 : state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = 0.0;
2663 12176813 : state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = 0.0;
2664 12176813 : state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = 0.0;
2665 12176813 : state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = 0.0;
2666 12176813 : state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = 0.0;
2667 : }
2668 22644370 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2669 12176813 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfNum) = 0.0;
2670 12176813 : state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
2671 12176813 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
2672 12176813 : state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
2673 12176813 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
2674 12176813 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
2675 12176813 : state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
2676 12176813 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
2677 12176813 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
2678 : }
2679 22644370 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2680 12176813 : state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
2681 12176813 : state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
2682 12176813 : state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
2683 12176813 : state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
2684 12176813 : state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
2685 12176813 : state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
2686 12176813 : state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfNum) = 0.0;
2687 12176813 : state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0;
2688 12176813 : state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0;
2689 : }
2690 :
2691 22644370 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2692 12176813 : state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0;
2693 12176813 : state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0;
2694 12176813 : state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0;
2695 12176813 : state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0;
2696 12176813 : state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0;
2697 12176813 : state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0;
2698 12176813 : state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0;
2699 12176813 : state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0;
2700 12176813 : state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0;
2701 12176813 : state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0;
2702 12176813 : state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = 0;
2703 12176813 : state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) = 0.0;
2704 12176813 : state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = 0.0;
2705 : }
2706 83782649 : for (int Lay = 1; Lay <= state.dataHeatBal->MaxSolidWinLayers; Lay++) {
2707 158629778 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2708 85314686 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = 0.0;
2709 : }
2710 : }
2711 73272899 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL; Lay++) {
2712 135866220 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2713 73060878 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay) = 0.0;
2714 : }
2715 : }
2716 10442717 : }
2717 : }
2718 : }
2719 2828408 : if (resetSolar) {
2720 4384152 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
2721 3876903 : state.dataHeatBal->EnclSolQD(enclosureNum) = 0.0;
2722 3876903 : state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) = 0.0;
2723 : }
2724 :
2725 : // TTD domes are currently not considered in the window list of a zone
2726 507249 : if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) {
2727 1233 : for (auto &e : state.dataDaylightingDevicesData->TDDPipe) {
2728 822 : e.TransSolBeam = 0.0;
2729 822 : e.TransSolDiff = 0.0;
2730 822 : e.TransVisBeam = 0.0;
2731 822 : e.TransVisDiff = 0.0;
2732 822 : e.TransmittedSolar = 0.0;
2733 822 : int SurfDome = e.Dome;
2734 822 : state.dataSurface->SurfWinTransSolar(SurfDome) = 0.0;
2735 822 : state.dataHeatBal->SurfQRadSWOutIncident(SurfDome) = 0.0;
2736 822 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfDome) = 0.0;
2737 6576 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
2738 5754 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfDome, Lay) = 0.0;
2739 : }
2740 : }
2741 : }
2742 :
2743 507249 : if (state.dataSurface->CalcSolRefl) {
2744 30175 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2745 27084 : state.dataSurface->SurfBmToBmReflFacObs(SurfNum) = 0.0;
2746 27084 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) = 0.0;
2747 27084 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = 0.0;
2748 : }
2749 : }
2750 35111532 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2751 34604283 : state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0;
2752 34604283 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = 0.0;
2753 34604283 : state.dataHeatBal->SurfSWInAbsTotalReport(SurfNum) = 0.0;
2754 34604283 : state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0;
2755 34604283 : state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0;
2756 34604283 : state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
2757 34604283 : state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
2758 : }
2759 : }
2760 2828408 : if (currSolRadPositive) { // Sun is up, calculate solar quantities
2761 925529 : assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
2762 : state.dataSurface->SurfReflFacBmToDiffSolObs)); // For linear indexing
2763 925529 : assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
2764 : state.dataSurface->SurfReflFacBmToDiffSolGnd)); // For linear indexing
2765 925529 : Real64 GndReflSolarRad = 0.0;
2766 925529 : Real64 GndSolarRadInc = max(state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad, 0.0);
2767 :
2768 59104020 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2769 58178491 : state.dataSurface->Surface(SurfNum).IncSolMultiplier = GetSurfIncidentSolarMultiplier(state, SurfNum);
2770 : }
2771 59104020 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2772 58178491 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2773 58178491 : state.dataSurface->SurfSkySolarInc(SurfNum) =
2774 58178491 : state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2775 58178491 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2776 9408 : GndReflSolarRad = GndSolarRadInc * SurfIncSolarMultiplier *
2777 4704 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2778 4704 : Surface(SurfNum).GndReflSolarRad = GndReflSolarRad;
2779 : } else {
2780 58173787 : GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
2781 : }
2782 58178491 : state.dataSurface->SurfGndSolarInc(SurfNum) = GndReflSolarRad * Surface(SurfNum).ViewFactorGround;
2783 58178491 : state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2784 58178491 : state.dataSurface->SurfWinBmGndSolarInc(SurfNum) = 0.0;
2785 : }
2786 925529 : if (state.dataSurface->CalcSolRefl) {
2787 : // [ lSH ] == ( HourOfDay, SurfNum ) // [ lSP ] == ( PreviousHour, SurfNum )
2788 22984 : Array1D<Real64>::size_type lSH = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->HourOfDay, 1) - 1;
2789 22984 : Array1D<Real64>::size_type lSP = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->PreviousHour, 1) - 1;
2790 : // For Complex Fenestrations:
2791 313999 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2792 291015 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2793 :
2794 291015 : Real64 GndSurfReflectance = 0.0;
2795 291015 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2796 0 : GndSurfReflectance =
2797 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2798 : } else {
2799 291015 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2800 : }
2801 291015 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2802 291015 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2803 291015 : state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) =
2804 291015 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2805 291015 : state.dataSurface->SurfWinBmGndSolarInc(SurfNum) =
2806 291015 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2807 291015 : state.dataSurface->SurfBmToBmReflFacObs(SurfNum) =
2808 291015 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToBmSolObs[lSH + SurfNum] +
2809 291015 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToBmSolObs[lSP + SurfNum];
2810 291015 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) =
2811 291015 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolObs[lSH + SurfNum] +
2812 291015 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolObs[lSP + SurfNum];
2813 291015 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) =
2814 291015 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSH + SurfNum] +
2815 291015 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSP + SurfNum];
2816 : // TH2 CR 9056
2817 291015 : state.dataSurface->SurfSkySolarInc(SurfNum) +=
2818 291015 : currBeamSolarRad * (state.dataSurface->SurfBmToBmReflFacObs(SurfNum) + state.dataSurface->SurfBmToDiffReflFacObs(SurfNum)) +
2819 291015 : currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
2820 291015 : state.dataSurface->SurfGndSolarInc(SurfNum) =
2821 291015 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) +
2822 291015 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2823 291015 : state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2824 : }
2825 : }
2826 :
2827 925529 : SolarShading::CalcWindowProfileAngles(state);
2828 :
2829 925529 : if (state.dataHeatBal->CalcWindowRevealReflection) {
2830 826 : SolarShading::CalcBeamSolarOnWinRevealSurface(state);
2831 : }
2832 :
2833 925529 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() && state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
2834 826 : SolarShading::CalcAbsorbedOnExteriorOpaqueSurfaces(state);
2835 826 : if (state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
2836 826 : SolarShading::CalcInteriorSolarDistributionWCESimple(state);
2837 : }
2838 : } else {
2839 924703 : SolarShading::CalcInteriorSolarDistribution(state);
2840 : }
2841 :
2842 7489275 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
2843 :
2844 : // TH 3/24/2010 - QBV is not used!
2845 : // unused QBV(ZoneNum) = (CBZone(ZoneNum) + EnclSolDB(ZoneNum))*BeamSolarRad
2846 :
2847 : // RJH 08/30/07 - QDV does not seem to ever be used. NOT USED!
2848 : // QDV(ZoneNum) = EnclSolDS(ZoneNum)*DifSolarRad &
2849 : // +EnclSolDG(ZoneNum)*GndSolarRad
2850 :
2851 : // Original QD calc used only for EnclSolQSDifSol and daylighting calcs
2852 : // QDforDaylight(ZoneNum) = EnclSolDB(ZoneNum)*BeamSolarRad &
2853 : // +EnclSolDS(ZoneNum)*DifSolarRad &
2854 : // +EnclSolDG(ZoneNum)*GndSolarRad
2855 :
2856 : // Beam from interior windows (EnclSolDBIntWin) reflected from floor is counted in DayltgInterReflIllFrIntWins,
2857 : // EnclSolDB needs to subtract this part since it is already counted in EnclSolDB.
2858 : // Use EnclSolInitialDifSolReflW (Rob's previous work) as it better counts initial distribution of
2859 : // diffuse solar rather than using weighted area*absorptance
2860 6563746 : state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) =
2861 6563746 : (state.dataHeatBal->EnclSolDB(enclosureNum) - state.dataHeatBal->EnclSolDBIntWin(enclosureNum)) * state.dataEnvrn->BeamSolarRad +
2862 6563746 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) + state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
2863 :
2864 : // to exclude diffuse solar now absorbed/transmitted in CalcWinTransDifSolInitialDistribution
2865 : // EnclSolDB(ZoneNum) is Diffuse Solar from beam reflected from interior surfaces
2866 : // and transmitted through interior windows
2867 : // EnclSolDB is a factor that when multiplied by BeamSolarRad [W/m2] gives Watts
2868 : // QD(ZoneNum) = EnclSolDB(ZoneNum)*BeamSolarRad &
2869 : // +EnclSolDS(ZoneNum)*DifSolarRad &
2870 : // +EnclSolDG(ZoneNum)*GndSolarRad
2871 13127492 : state.dataHeatBal->EnclSolQD(enclosureNum) = state.dataHeatBal->EnclSolDB(enclosureNum) * state.dataEnvrn->BeamSolarRad +
2872 6563746 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) +
2873 6563746 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
2874 : }
2875 :
2876 : // Flux of diffuse solar in each zone
2877 :
2878 7489275 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2879 6563746 : state.dataHeatBal->EnclSolQSDifSol(enclNum) = state.dataHeatBal->EnclSolQDforDaylight(enclNum);
2880 : }
2881 :
2882 925529 : if (state.dataHeatBalSurf->InterZoneWindow) {
2883 18955 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2884 15164 : if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclNum)) {
2885 7582 : Real64 EnclSolQSDifSol_sum(0.0); // Accumulator
2886 7582 : int lZone(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.index(enclNum,
2887 7582 : 1)); // Tuned Linear indexing
2888 37910 : for (int otherEnclNum = 1; otherEnclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++otherEnclNum, ++lZone) {
2889 30328 : if ((otherEnclNum != enclNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(otherEnclNum))) {
2890 7582 : EnclSolQSDifSol_sum += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[lZone] *
2891 7582 : state.dataHeatBal->EnclSolQDforDaylight(otherEnclNum); // [ lZone ] == ( enclNum, otherEnclNum )
2892 : }
2893 : }
2894 7582 : state.dataHeatBal->EnclSolQSDifSol(enclNum) += EnclSolQSDifSol_sum;
2895 : }
2896 : }
2897 : }
2898 :
2899 7489275 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2900 6563746 : if (state.dataHeatBalSurf->InterZoneWindow) {
2901 15164 : state.dataHeatBal->EnclSolQSDifSol(enclNum) *=
2902 15164 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclNum, enclNum) * state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
2903 : } else {
2904 6548582 : state.dataHeatBal->EnclSolQSDifSol(enclNum) *= state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
2905 : }
2906 : }
2907 :
2908 : // RJH - 09-12-07 commented out report variable calcs here since they refer to old distribution method
2909 : // DO SurfNum = 1, TotSurfaces
2910 : // IF (.NOT. Surface(SurfNum)%HeatTransSurf) CYCLE
2911 : //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
2912 : // IF (Surface(SurfNum)%Class == SurfaceClass::Shading) CYCLE
2913 : // ZoneNum = Surface(SurfNum)%Zone
2914 : // Diffuse solar entering zone through exterior windows is assumed to be uniformly
2915 : // distributed on inside face of surfaces of zone
2916 : // DifIncInsSurfIntensRep(SurfNum) = (EnclSolDS(ZoneNum)*DifSolarRad + EnclSolDG(ZoneNum)*GndSolarRad) / &
2917 : // Zone(ZoneNum)%TotalSurfArea
2918 : // DifIncInsSurfAmountRep(SurfNum) = (Surface(SurfNum)%Area + SurfaceWindow(SurfNum)%DividerArea) * &
2919 : // DifIncInsSurfIntensRep(SurfNum)
2920 : // DifIncInsSurfAmountRepEnergy(SurfNum) = DifIncInsSurfAmountRep(SurfNum) * TimeStepZoneSec
2921 : // END DO
2922 :
2923 : // Calculate Exterior Incident Short Wave (i.e. Solar) Radiation on shading surfaces
2924 925529 : if (state.dataSurface->BuildingShadingCount || state.dataSurface->FixedShadingCount || state.dataSurface->AttachedShadingCount) {
2925 2111992 : for (int SurfNum = state.dataSurface->ShadingSurfaceFirst; SurfNum <= state.dataSurface->ShadingSurfaceLast; SurfNum++) {
2926 1801646 : Real64 GndSurfReflectance = 0.0;
2927 1801646 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2928 0 : GndSurfReflectance =
2929 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2930 : } else {
2931 1801646 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2932 : }
2933 : // Cosine of incidence angle and solar incident on outside of surface, for reporting
2934 1801646 : Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
2935 1801646 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = CosInc;
2936 1801646 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2937 1801646 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2938 1801646 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2939 : // Incident direct (unreflected) beam
2940 1801646 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
2941 1801646 : currBeamSolarRad * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) * CosInc;
2942 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
2943 1801646 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2944 : // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
2945 1801646 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2946 : // Incident diffuse solar from beam-to-diffuse reflection from ground
2947 1801646 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
2948 1801646 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2949 : // Incident diffuse solar from sky diffuse reflection from ground
2950 1801646 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
2951 1801646 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
2952 : // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
2953 : // in SkySolarInc.
2954 1801646 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
2955 1801646 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
2956 1801646 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
2957 : }
2958 : }
2959 :
2960 925529 : Array1D<Real64> currBeamSolar(state.dataSurface->TotSurfaces); // Local variable for BeamSolarRad
2961 :
2962 24293602 : for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
2963 23368073 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2964 : // Regular surface
2965 23368073 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2966 23368073 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2967 : // Cosine of incidence angle and solar incident on outside of surface, for reporting
2968 23368073 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
2969 23368073 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
2970 :
2971 : // Report variables for various incident solar quantities
2972 : // Incident direct (unreflected) beam
2973 23368073 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
2974 23368073 : currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
2975 23368073 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum);
2976 :
2977 23368073 : Real64 GndSurfReflectance = 0.0;
2978 23368073 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2979 3528 : GndSurfReflectance =
2980 3528 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2981 : } else {
2982 23364545 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2983 : }
2984 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
2985 23368073 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2986 : // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
2987 23368073 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2988 : // Incident diffuse solar from beam-to-diffuse reflection from ground
2989 23368073 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
2990 23368073 : currBeamSolar(SurfNum) * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2991 :
2992 : // Incident diffuse solar from sky diffuse reflection from ground
2993 23368073 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
2994 23368073 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
2995 : // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
2996 : // in SkySolarInc.
2997 : // SurfQRadSWOutIncident(SurfNum) = SurfQRadSWOutIncidentBeam(SurfNum) + SkySolarInc + GndSolarInc
2998 : // TH2 CR 9056
2999 23368073 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
3000 23368073 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
3001 23368073 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
3002 :
3003 23368073 : if (state.dataSurface->CalcSolRefl) {
3004 : // Incident beam solar from beam-to-beam (specular) reflection from obstructions
3005 173799 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = state.dataSurface->SurfBmToBmReflFacObs(SurfNum) * currBeamSolar(SurfNum);
3006 : // Incident diffuse solar from beam-to-diffuse reflection from obstructions
3007 173799 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) =
3008 173799 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) * currBeamSolar(SurfNum);
3009 : // Incident diffuse solar from sky diffuse reflection from obstructions
3010 173799 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
3011 : // TH2 CR 9056: Add reflections from obstructions to the total incident
3012 347598 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) += state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) +
3013 173799 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) +
3014 173799 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum);
3015 : }
3016 925529 : }
3017 926761 : for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
3018 1232 : int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser; // TDD: Diffuser object number
3019 1232 : int const SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
3020 1232 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3021 1232 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3022 :
3023 : // Reconstruct the beam, sky, and ground radiation transmittance of just the TDD:DOME and TDD pipe
3024 : // by dividing out diffuse solar transmittance of TDD:DIFFUSER
3025 1232 : Real64 ConInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
3026 :
3027 1232 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = ConInc;
3028 1232 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3029 1232 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier *
3030 1232 : TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarBeam) / thisConstruct.TransDiff;
3031 :
3032 2464 : state.dataSurface->SurfSkySolarInc(SurfNum) = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier *
3033 1232 : state.dataSolarShading->SurfAnisoSkyMult(SurfNum2) *
3034 1232 : TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarAniso) / thisConstruct.TransDiff;
3035 :
3036 2464 : state.dataSurface->SurfGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum2) *
3037 1232 : state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolIso / thisConstruct.TransDiff;
3038 : // Incident direct (unreflected) beam
3039 2464 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = currBeamSolar(SurfNum) *
3040 2464 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay,
3041 1232 : state.dataGlobal->TimeStep,
3042 1232 : SurfNum2) *
3043 : ConInc; // NOTE: sunlit and coninc array set to SurfNum2
3044 :
3045 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
3046 1232 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = state.dataSurface->SurfSkySolarInc(SurfNum);
3047 1232 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
3048 1232 : (state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
3049 1232 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum));
3050 : }
3051 :
3052 926145 : for (int ShelfNum = 1; ShelfNum <= (int)state.dataDaylightingDevicesData->Shelf.size(); ++ShelfNum) {
3053 616 : int SurfNum = state.dataDaylightingDevicesData->Shelf(ShelfNum).Window; // Daylighting shelf object number
3054 616 : int OutShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf; // Outside daylighting shelf present if > 0
3055 616 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
3056 616 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
3057 616 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3058 616 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3059 : // Shelf diffuse solar radiation
3060 : Real64 ShelfSolarRad =
3061 616 : (currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) *
3062 616 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) +
3063 616 : state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(OutShelfSurf)) *
3064 616 : state.dataDaylightingDevicesData->Shelf(ShelfNum).OutReflectSol;
3065 :
3066 616 : GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
3067 616 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
3068 0 : GndReflSolarRad = state.dataSurface->Surface(SurfNum).GndReflSolarRad;
3069 : }
3070 : // Add all reflected solar from the outside shelf to the ground solar
3071 : // NOTE: If the shelf blocks part of the view to the ground, the user must reduce the ground view factor!!
3072 616 : state.dataSurface->SurfGndSolarInc(SurfNum) =
3073 616 : GndReflSolarRad * Surface(SurfNum).ViewFactorGround + ShelfSolarRad * state.dataDaylightingDevicesData->Shelf(ShelfNum).ViewFactor;
3074 : }
3075 :
3076 : // Calculate Exterior and Interior Absorbed Short Wave Radiation
3077 7490514 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3078 13144838 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3079 6579853 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
3080 6579853 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
3081 6579853 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
3082 55194254 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
3083 48614401 : int const ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
3084 48614401 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3085 48614401 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3086 48614401 : if (Surface(SurfNum).ExtSolar) {
3087 : Real64 AbsExt =
3088 13836027 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); // Absorptivity of outer most layer (or movable insulation if present)
3089 13836027 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
3090 13836027 : state.dataSurface->SurfOpaqAO(SurfNum) * currBeamSolar(SurfNum) +
3091 13836027 : AbsExt * (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum));
3092 : }
3093 48614401 : if (ConstrNum > 0) {
3094 48614401 : int SurfSolIncPtr = SolarShading::SurfaceScheduledSolarInc(state, SurfNum, ConstrNum);
3095 48614401 : if (SurfSolIncPtr == 0) {
3096 48613813 : if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Opaque surface
3097 48613813 : int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum); // Daylighting shelf object number
3098 48613813 : int InShelfSurf = 0; // Inside daylighting shelf surface number
3099 48613813 : if (ShelfNum > 0) {
3100 0 : InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf; // Inside daylighting shelf present if > 0
3101 : }
3102 48613813 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +=
3103 48613813 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum);
3104 48613813 : if (InShelfSurf > 0) { // Inside daylighting shelf
3105 : // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init)
3106 0 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
3107 0 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * (0.5 * Surface(SurfNum).Area);
3108 : } else { // Regular surface
3109 48613813 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
3110 48613813 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * Surface(SurfNum).Area;
3111 : }
3112 : }
3113 : } else {
3114 588 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum);
3115 : }
3116 : }
3117 : }
3118 6579853 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
3119 6579853 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
3120 14318763 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
3121 7738910 : auto &surf = state.dataSurface->Surface(SurfNum);
3122 7738910 : auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
3123 7738910 : if (surf.ExtSolar || surf.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
3124 : // Exclude special shading surfaces which required SurfOpaqQRadSWOut calculations above
3125 7730400 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3126 7730400 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3127 7730400 : Real64 CosInc = state.dataHeatBal->SurfCosIncidenceAngle(SurfNum); // Cosine of incidence angle of beam solar on glass
3128 7730400 : Real64 BeamSolar = currBeamSolar(SurfNum); // Local variable for BeamSolarRad
3129 7730400 : Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum); // Sky diffuse solar incident on a surface
3130 7730400 : Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum); // Ground diffuse solar incident on a surface
3131 :
3132 7730400 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
3133 :
3134 15446079 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed &&
3135 7715679 : !state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
3136 7714853 : int TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
3137 17668319 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3138 9953466 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
3139 : }
3140 :
3141 7714853 : if (IS_SHADED(ShadeFlag)) { // Shaded window
3142 :
3143 184702 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); // Shaded window construction
3144 184702 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3145 :
3146 184702 : if (ANY_SHADE_SCREEN(ShadeFlag)) { // Shade/screen on
3147 116218 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3148 74732 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = constructionSh.AbsDiff(Lay);
3149 : }
3150 41486 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = constructionSh.AbsDiffShade * (SkySolarInc + GndSolarInc);
3151 :
3152 143216 : } else if (ANY_BLIND(ShadeFlag)) { // Blind on
3153 71430 : auto &surfShade = state.dataSurface->surfShades(SurfNum);
3154 71430 : int slatIdxLo = surfShade.blind.slatAngIdxLo;
3155 71430 : int slatIdxHi = surfShade.blind.slatAngIdxHi;
3156 71430 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3157 : Real64 AbsDiffBlind;
3158 :
3159 : // For constructions, have to do interpolation whether we have movable slats or not
3160 147298 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3161 75868 : auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
3162 75868 : auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
3163 :
3164 75868 : AbsDiffWin(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.Abs, dfAbsSlatHi.Sol.Ft.Df.Abs, interpFac);
3165 75868 : AbsDiffWinGnd(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3166 75868 : AbsDiffWinSky(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3167 : }
3168 :
3169 71430 : auto const &tarSlatLo = constructionSh.blindTARs[slatIdxLo];
3170 71430 : auto const &tarSlatHi = constructionSh.blindTARs[slatIdxHi];
3171 71430 : AbsDiffBlind = Interp(tarSlatLo.Sol.Ft.Df.Abs, tarSlatHi.Sol.Ft.Df.Abs, interpFac);
3172 :
3173 71430 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = AbsDiffBlind * (SkySolarInc + GndSolarInc);
3174 :
3175 71430 : auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
3176 71430 : if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
3177 71430 : Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt);
3178 :
3179 : // Need to do these interpolations unless we want to cache this in surfShade.blind.
3180 71430 : Real64 AbsDiffBlindGnd = Interp(tarSlatLo.Sol.Ft.Df.AbsGnd, tarSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3181 71430 : Real64 AbsDiffBlindSky = Interp(tarSlatLo.Sol.Ft.Df.AbsSky, tarSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3182 :
3183 71430 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) =
3184 71430 : SkySolarInc * (0.5 * ACosTlt * AbsDiffBlindGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffBlindSky) +
3185 71430 : GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffBlindGnd + 0.5 * ACosTlt * AbsDiffBlindSky);
3186 : }
3187 : }
3188 :
3189 : // Correct for shadowing of divider onto interior shading device (note that dividers are
3190 : // not allowed in windows with between-glass shade/blind)
3191 :
3192 184702 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
3193 742 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) *= surfWin.glazedFrac;
3194 : }
3195 :
3196 184702 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3197 71786 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for switchable glazing
3198 215358 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3199 143572 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) =
3200 143572 : Window::InterpSw(SwitchFac, state.dataHeatBalSurfMgr->AbsDiffWin(Lay), constructionSh.AbsDiff(Lay));
3201 : }
3202 : }
3203 :
3204 : } // End of check if window has shading device on
3205 :
3206 7714853 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3207 17668319 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3208 9953466 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3209 9953466 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc) +
3210 9953466 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3211 : // SurfWinA is from InteriorSolarDistribution
3212 9953466 : if (ANY_BLIND(ShadeFlag)) {
3213 75868 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3214 75868 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3215 75868 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3216 75868 : auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
3217 75868 : if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
3218 :
3219 75868 : Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); // Absolute value of cosine of surface tilt angle
3220 :
3221 75868 : int slatIdxLo = surfShade.blind.slatAngIdxLo;
3222 75868 : int slatIdxHi = surfShade.blind.slatAngIdxLo;
3223 75868 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3224 75868 : auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
3225 75868 : auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
3226 :
3227 75868 : Real64 AbsDiffGlassLayGnd = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3228 75868 : Real64 AbsDiffGlassLaySky = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3229 :
3230 75868 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3231 75868 : SkySolarInc * (0.5 * ACosTlt * AbsDiffGlassLayGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffGlassLaySky) +
3232 151736 : GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffGlassLayGnd + 0.5 * ACosTlt * AbsDiffGlassLaySky) +
3233 75868 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3234 : }
3235 : }
3236 : // Total solar absorbed in solid layer (W), for reporting
3237 9953466 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3238 9953466 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3239 :
3240 : // Total solar absorbed in all glass layers (W), for reporting
3241 9953466 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3242 : }
3243 7714853 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3244 7714853 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3245 : // Need to do it this way for now because of scheduled surface gains. They do work only with
3246 : // BSDF windows and overwriting absorbtances will work only for ordinary windows
3247 : // } else if ( SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: BSDF &&
3248 : // SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: EQL &&
3249 : // inExtWindowModel->isExternalLibraryModel() ) {
3250 : // TotSolidLay = Construct( ConstrNum ).TotSolidLayers;
3251 : // for ( Lay = 1; Lay <= TotSolidLay; ++Lay ) {
3252 : // SurfWinQRadSWwinAbs( Lay, SurfNum ) = SurfWinA( Lay, SurfNum ) *
3253 : // ( SurfQRadSWOutIncident( SurfNum ) + QS( Surface( SurfNum ).Zone ) );
3254 : // }
3255 15547 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
3256 12243 : int TotSolidLay = state.dataConstruction->Construct(ConstrNum).TotSolidLayers;
3257 : // Number of solid layers in fenestration system (glass + shading)
3258 12243 : int CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState;
3259 : // Current state for Complex Fenestration
3260 : // Examine for schedule surface gain
3261 12243 : Real64 SurfSolAbs = SolarShading::WindowScheduledSolarAbs(
3262 : state,
3263 : SurfNum,
3264 12243 : ConstrNum); // Pointer to scheduled surface gains object for fenestration systems
3265 :
3266 46277 : for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
3267 34034 : if (SurfSolAbs != 0) {
3268 294 : state.dataSurface->SurfWinA(SurfNum, Lay) =
3269 294 : state.dataSurface->FenLayAbsSSG(SurfSolAbs).scheds(Lay)->getCurrentVal();
3270 : // ABWin(Lay) = SurfWinA(SurfNum,Lay)
3271 294 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = state.dataSurface->SurfWinA(SurfNum, Lay);
3272 : } else {
3273 : // Several notes about this equation. First part is accounting for diffuse solar radiation for the ground
3274 : // and from the sky. Second item (SurfWinA(SurfNum,Lay) * BeamSolar) is accounting for absorbed solar
3275 : // radiation originating from beam on exterior side. Third item (SurfWinACFOverlap(SurfNum,Lay)) is
3276 : // accounting for absorptances from beam hitting back of the window which passes through rest of exterior
3277 : // windows
3278 33740 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3279 33740 : state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyFtAbs(Lay) * SkySolarInc +
3280 33740 : state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyGndAbs(Lay) * GndSolarInc +
3281 33740 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
3282 33740 : state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * BeamSolar;
3283 : }
3284 : // Total solar absorbed in solid layer (W), for reporting
3285 34034 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3286 34034 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3287 :
3288 : // Total solar absorbed in all glass layers (W), for reporting
3289 34034 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3290 : }
3291 12243 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3292 12243 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3293 :
3294 3304 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
3295 2478 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3296 : // EQLNum = Construct(Surface(SurfNum)%Construction)%EQLConsPtr
3297 : int TotSolidLay =
3298 2478 : state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(Surface(SurfNum).Construction).EQLConsPtr).NL;
3299 11564 : for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
3300 : // Absorbed window components include:
3301 : // (1) beam solar radiation absorbed by all layers in the fenestration
3302 : // (2) sky and ground reflected diffuse solar radiation absorbed by all layers
3303 : // (3) diffuse short wave incident on the inside face of the fenestration. The short wave internal sources
3304 : // include light, ...
3305 9086 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay);
3306 9086 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3307 9086 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
3308 9086 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc);
3309 :
3310 : // Total solar absorbed in solid layer (W), for reporting
3311 9086 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3312 9086 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3313 :
3314 : // Total solar absorbed in all glass layers (W), for reporting
3315 9086 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3316 : }
3317 :
3318 2478 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3319 2478 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3320 826 : } else if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
3321 826 : int SurfNum2 = SurfNum;
3322 826 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
3323 0 : SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
3324 : }
3325 :
3326 : std::pair<Real64, Real64> incomingAngle =
3327 826 : Window::getSunWCEAngles(state, SurfNum2, SingleLayerOptics::BSDFDirection::Incoming);
3328 826 : Real64 Theta = incomingAngle.first;
3329 826 : Real64 Phi = incomingAngle.second;
3330 :
3331 : std::shared_ptr<MultiLayerOptics::CMultiLayerScattered> aLayer =
3332 826 : Window::CWindowConstructionsSimplified::instance(state).getEquivalentLayer(
3333 826 : state, FenestrationCommon::WavelengthRange::Solar, ConstrNum);
3334 :
3335 826 : size_t totLayers = aLayer->getNumOfLayers();
3336 1652 : for (size_t Lay = 1; Lay <= totLayers; ++Lay) {
3337 826 : Real64 AbWinDiff = aLayer->getAbsorptanceLayer(
3338 : Lay, FenestrationCommon::Side::Front, FenestrationCommon::ScatteringSimple::Diffuse, Theta, Phi);
3339 :
3340 826 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3341 826 : AbWinDiff * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3342 :
3343 : // Total solar absorbed in solid layer (W), for reporting
3344 826 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3345 826 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3346 :
3347 : // Total solar absorbed in all glass layers (W), for reporting
3348 826 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3349 : }
3350 826 : }
3351 :
3352 : // Solar absorbed by window frame and dividers
3353 7730400 : int FrDivNum = Surface(SurfNum).FrameDivider; // Frame/divider number
3354 7730400 : if (FrDivNum > 0) {
3355 410342 : Real64 FrArea = state.dataSurface->SurfWinFrameArea(SurfNum); // Frame, divider area (m2)
3356 410342 : Real64 FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut; // Frame, divider outside projection (m)
3357 410342 : Real64 FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn;
3358 410342 : Real64 DivArea = state.dataSurface->SurfWinDividerArea(SurfNum);
3359 410342 : Real64 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
3360 410342 : Real64 DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut;
3361 410342 : Real64 DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn;
3362 410342 : Real64 CosIncAngHorProj = 0.0; // Cosine of incidence angle of sun on horizontal faces of a frame or divider projection
3363 410342 : Real64 CosIncAngVertProj = 0.0; // Cosine of incidence angle of sun on vertical faces of a frame or divider projection
3364 410342 : Real64 FracSunLit = 0.0; // Fraction of window sunlit this time step
3365 : Real64 BeamFaceInc; // Beam solar incident window plane this time step (W/m2)
3366 : Real64 DifSolarFaceInc; // Diffuse solar incident on window plane this time step (W/m2)
3367 410342 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3368 410342 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3369 410342 : if (FrArea > 0.0 || DivArea > 0.0) {
3370 240742 : FracSunLit = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
3371 240742 : BeamFaceInc = currBeamSolarRad *
3372 240742 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
3373 : CosInc;
3374 240742 : DifSolarFaceInc = SkySolarInc + GndSolarInc;
3375 : }
3376 410342 : if (FracSunLit > 0.0) {
3377 183755 : if ((FrArea > 0.0 && (FrProjOut > 0.0 || FrProjIn > 0.0)) ||
3378 19572 : (DivArea > 0.0 && (DivProjOut > 0.0 || DivProjIn > 0.0))) {
3379 : // Dot products used to calculate beam solar incident on faces of
3380 : // frame and divider perpendicular to the glass surface.
3381 : // Note that SOLCOS is the current timestep's solar direction cosines.
3382 : // PhiWin = ASIN(WALCOS(3,SurfNum))
3383 : Real64 PhiWin =
3384 155489 : std::asin(Surface(SurfNum).OutNormVec(3)); // Altitude and azimuth angle of outward window normal (radians)
3385 155489 : Real64 ThWin = std::atan2(Surface(SurfNum).OutNormVec(2), Surface(SurfNum).OutNormVec(1));
3386 155489 : Real64 PhiSun = std::asin(state.dataEnvrn->SOLCOS(3)); // Altitude and azimuth angle of sun (radians)
3387 155489 : Real64 ThSun = std::atan2(state.dataEnvrn->SOLCOS(2), state.dataEnvrn->SOLCOS(1));
3388 155489 : Real64 const cos_PhiWin(std::cos(PhiWin));
3389 155489 : Real64 const cos_PhiSun(std::cos(PhiSun));
3390 : CosIncAngHorProj =
3391 155489 : std::abs(std::sin(PhiWin) * cos_PhiSun * std::cos(ThWin - ThSun) - cos_PhiWin * std::sin(PhiSun));
3392 155489 : CosIncAngVertProj = std::abs(cos_PhiWin * cos_PhiSun * std::sin(ThWin - ThSun));
3393 : }
3394 : }
3395 : // Frame solar
3396 : // (A window shade or blind, if present, is assumed to not shade the frame, so no special
3397 : // treatment of frame solar needed if window has an exterior shade or blind.)
3398 410342 : if (FrArea > 0.0) {
3399 240742 : Real64 FrIncSolarOut = BeamFaceInc; // Total solar incident on outside of frame including solar
3400 240742 : Real64 FrIncSolarIn = 0.0; // Total solar incident on inside of frame including solar on frame projection (W/m2)
3401 240742 : Real64 TransDiffGl = 0.0; // Diffuse solar transmittance
3402 240742 : if (FrProjOut > 0.0 || FrProjIn > 0.0) {
3403 : Real64 BeamFrHorFaceInc =
3404 372244 : currBeamSolarRad * CosIncAngHorProj *
3405 186122 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit /
3406 186122 : FrArea;
3407 : Real64 BeamFrVertFaceInc =
3408 372244 : currBeamSolarRad * CosIncAngVertProj *
3409 186122 : (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
3410 186122 : FrArea;
3411 : // Beam solar on outside of frame
3412 186122 : FrIncSolarOut += (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjOut;
3413 186122 : if (FrProjIn > 0.0) {
3414 186122 : Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
3415 186122 : TransDiffGl = thisConstruct.TransDiff;
3416 186122 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3417 71044 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3418 71044 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3419 71044 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3420 71044 : Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
3421 71044 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3422 71044 : Real64 TransDiffGlSh = constructionSh.TransDiff;
3423 71044 : TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
3424 : }
3425 : // Beam solar on inside of frame
3426 186122 : FrIncSolarIn = (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjIn * TransGl;
3427 : }
3428 : }
3429 : // Beam plus diffuse solar on outside of frame
3430 240742 : FrIncSolarOut += DifSolarFaceInc * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum));
3431 240742 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) =
3432 240742 : FrIncSolarOut * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3433 : // Add diffuse from beam reflected from window outside reveal surfaces
3434 240742 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) += currBeamSolarRad *
3435 240742 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) *
3436 240742 : state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3437 :
3438 : // Beam plus diffuse solar on inside of frame
3439 240742 : FrIncSolarIn += DifSolarFaceInc * TransDiffGl * 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum);
3440 240742 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = FrIncSolarIn * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3441 : // Add diffuse from beam reflected from window inside reveal surfaces
3442 240742 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += currBeamSolarRad *
3443 240742 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) *
3444 240742 : state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3445 : }
3446 :
3447 : // Divider solar
3448 : // (An exterior shade or blind, when in place, is assumed to completely cover the divider.
3449 : // Dividers are not allowed on windows with between-glass shade/blind so DivProjOut and
3450 : // DivProjIn will be zero in this case.)
3451 410342 : if (DivArea > 0.0) { // Solar absorbed by window divider
3452 140236 : Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
3453 140236 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
3454 : // Suspended (between-glass) divider; account for effect glass on outside of divider
3455 : // (note that outside and inside projection for this type of divider are both zero)
3456 8004 : int MatNumGl = thisConstruct.LayerPoint(1); // Outer glass layer material number
3457 8004 : auto const *thisMaterial = dynamic_cast<Material::MaterialFen *>(s_mat->materials(MatNumGl));
3458 8004 : assert(thisMaterial != nullptr);
3459 8004 : Real64 TransGl = thisMaterial->Trans; // Outer glass layer material number, switched construction
3460 8004 : Real64 ReflGl = thisMaterial->ReflectSolBeamFront;
3461 8004 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
3462 8004 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3463 8004 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3464 8004 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3465 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3466 0 : Real64 MatNumGlSh = constructionSh.LayerPoint(1);
3467 0 : auto const *thisMaterialSh = dynamic_cast<Material::MaterialGlass *>(s_mat->materials(MatNumGlSh));
3468 0 : assert(thisMaterialSh != nullptr);
3469 0 : Real64 TransGlSh = thisMaterialSh->Trans;
3470 0 : Real64 ReflGlSh = thisMaterialSh->ReflectSolBeamFront;
3471 0 : Real64 AbsGlSh = 1.0 - TransGlSh - ReflGlSh;
3472 0 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3473 0 : ReflGl = Window::InterpSw(SwitchFac, ReflGl, ReflGlSh);
3474 0 : AbsGl = Window::InterpSw(SwitchFac, AbsGl, AbsGlSh);
3475 : }
3476 8004 : Real64 DividerRefl = 1.0 - DividerAbs; // Window divider solar reflectance
3477 8004 : DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
3478 : }
3479 :
3480 140236 : Real64 BeamDivHorFaceInc = 0.0; // Beam solar on divider's horizontal outside projection faces (W/m2)
3481 140236 : Real64 BeamDivVertFaceInc = 0.0; // Beam solar on divider's vertical outside projection faces (W/m2)
3482 : // Beam incident on horizontal and vertical projection faces of divider if no exterior shading
3483 140236 : if (DivProjOut > 0.0 && !DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3484 95784 : BeamDivHorFaceInc = currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers *
3485 95784 : DivProjOut *
3486 95784 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
3487 : FracSunLit / DivArea;
3488 95784 : BeamDivVertFaceInc =
3489 95784 : currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivProjOut *
3490 95784 : (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
3491 : DivArea;
3492 : }
3493 140236 : Real64 DivIncSolarOutBm =
3494 : 0.0; // Diffuse solar incident on outside of divider including beam on divider projection (W/m2)
3495 140236 : Real64 DivIncSolarOutDif =
3496 : 0.0; // Diffuse solar incident on outside of divider including diffuse on divider projection (W/m2)
3497 140236 : Real64 DivIncSolarInBm =
3498 : 0.0; // Diffuse solar incident on inside of divider including beam on divider projection (W/m2)
3499 140236 : Real64 DivIncSolarInDif =
3500 : 0.0; // Diffuse solar incident on inside of divider including diffuse on divider projection (W/m2)
3501 271912 : if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) &&
3502 131676 : !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { // No exterior or between-glass shading
3503 131676 : DivIncSolarOutBm = BeamFaceInc + BeamDivHorFaceInc + BeamDivVertFaceInc;
3504 131676 : DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3505 131676 : if (DivProjIn > 0.0) {
3506 95784 : Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
3507 95784 : Real64 TransDiffGl = thisConstruct.TransDiff; // Diffuse solar transmittance
3508 95784 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3509 71044 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3510 71044 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3511 71044 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3512 :
3513 71044 : Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
3514 : // Outer glass solar trans, refl, absorptance if switched
3515 71044 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3516 71044 : Real64 TransDiffGlSh = constructionSh.TransDiff;
3517 : // Diffuse solar transmittance, switched construction
3518 71044 : TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
3519 : }
3520 : // Beam plus diffuse solar on inside of divider
3521 : // BeamDivHorFaceIncIn - Beam solar on divider's horizontal inside projection faces (W/m2)
3522 : // BeamDivVertFaceIncIn - Beam solar on divider's vertical inside projection faces (W/m2)
3523 : Real64 BeamDivHorFaceIncIn =
3524 95784 : currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivProjIn *
3525 95784 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
3526 95784 : FracSunLit / DivArea;
3527 : Real64 BeamDivVertFaceIncIn =
3528 95784 : currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers *
3529 95784 : DivProjIn * (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) *
3530 95784 : FracSunLit / DivArea;
3531 95784 : DivIncSolarInBm = TransGl * (BeamDivHorFaceIncIn + BeamDivVertFaceIncIn);
3532 95784 : DivIncSolarInDif = TransDiffGl * DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum);
3533 : }
3534 : } else { // Exterior shade, screen or blind present
3535 :
3536 8560 : DivIncSolarOutBm = BeamFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3537 8560 : DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3538 8560 : DivIncSolarInBm = BeamFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
3539 8560 : DivIncSolarInDif = DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
3540 : }
3541 :
3542 140236 : if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
3543 : // No exterior or between-glass shade, screen or blind
3544 131676 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = DividerAbs * (DivIncSolarOutBm + DivIncSolarOutDif);
3545 131676 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = DividerAbs * (DivIncSolarInBm + DivIncSolarInDif);
3546 : // Exterior shade, screen or blind
3547 :
3548 8560 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) { // Exterior blind
3549 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3550 :
3551 0 : int profIdxLo = surfShade.blind.profAngIdxLo;
3552 0 : int profIdxHi = surfShade.blind.profAngIdxHi;
3553 0 : Real64 profInterpFac = surfShade.blind.profAngInterpFac;
3554 :
3555 0 : auto const &btarLo = surfShade.blind.TAR.Sol.Ft.Bm[profIdxLo];
3556 0 : auto const &btarHi = surfShade.blind.TAR.Sol.Ft.Bm[profIdxHi];
3557 :
3558 0 : Real64 FrontDiffTrans = surfShade.blind.TAR.Sol.Ft.Df.Tra;
3559 0 : Real64 TBlBmDif = Interp(btarLo.DfTra, btarHi.DfTra, profInterpFac);
3560 :
3561 : // TBlBmBm - Blind beam-beam solar transmittance
3562 0 : Real64 TBlBmBm = surfShade.blind.bmBmTrans;
3563 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3564 0 : DividerAbs * (DivIncSolarOutBm * (TBlBmBm + TBlBmDif) + DivIncSolarOutDif * FrontDiffTrans);
3565 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3566 0 : DividerAbs * (DivIncSolarInBm * (TBlBmBm + TBlBmDif) + DivIncSolarInDif * FrontDiffTrans);
3567 :
3568 8560 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtShade) { // Exterior shade
3569 8560 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3570 8560 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3571 8560 : auto const *matFen = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(constructionSh.LayerPoint(1)));
3572 8560 : assert(matFen != nullptr);
3573 8560 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3574 8560 : DividerAbs * matFen->Trans * (DivIncSolarOutBm + DivIncSolarOutDif);
3575 8560 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3576 8560 : DividerAbs * matFen->Trans * (DivIncSolarInBm + DivIncSolarInDif);
3577 :
3578 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtScreen) { // Exterior screen
3579 0 : int screenNum = surfWin.screenNum;
3580 0 : auto const *screen = dynamic_cast<Material::MaterialScreen const *>(s_mat->materials(screenNum));
3581 0 : assert(screen != nullptr);
3582 :
3583 0 : auto &surf = state.dataSurface->Surface(SurfNum);
3584 : Real64 phi, theta;
3585 0 : Material::GetRelativePhiTheta(
3586 0 : surf.Tilt * Constant::DegToRad, surf.Azimuth * Constant::DegToRad, state.dataEnvrn->SOLCOS, phi, theta);
3587 : #ifdef PRECALC_INTERP_SCREEN
3588 : int ip1, ip2, it1, it2; // hi/lo phi and theta map indices
3589 : BilinearInterpCoeffs coeffs;
3590 0 : Material::GetPhiThetaIndices(phi, theta, screen->dPhi, screen->dTheta, ip1, ip2, it1, it2);
3591 0 : GetBilinearInterpCoeffs(
3592 0 : phi, theta, ip1 * screen->dPhi, ip2 * screen->dPhi, it1 * screen->dTheta, it2 * screen->dTheta, coeffs);
3593 0 : auto const &b11 = screen->btars[ip1][it1];
3594 0 : auto const &b12 = screen->btars[ip1][it2];
3595 0 : auto const &b21 = screen->btars[ip2][it1];
3596 0 : auto const &b22 = screen->btars[ip2][it2];
3597 0 : Real64 BmDfTrans = BilinearInterp(b11.DfTrans, b12.DfTrans, b21.DfTrans, b22.DfTrans, coeffs);
3598 0 : Real64 BmBmTrans = BilinearInterp(b11.BmTrans, b12.BmTrans, b21.BmTrans, b22.BmTrans, coeffs);
3599 :
3600 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3601 0 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
3602 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3603 0 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
3604 : #else // !PRECALC_INTERP_SCREEN
3605 : Material::ScreenBmTransAbsRef btar;
3606 :
3607 : Material::CalcScreenTransmittance(state, screen, phi, theta, btar);
3608 : Real64 BmDfTrans = btar.DfTrans;
3609 : Real64 BmBmTrans = btar.BmTrans;
3610 :
3611 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3612 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
3613 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3614 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
3615 : #endif // PRECALC_INTERP_SCREEN
3616 : }
3617 : }
3618 : }
3619 : } // Surface(SurfNum)%ExtSolar
3620 : } // end of surface window loop
3621 6564985 : } // end of space loop
3622 : } // end of zone loop
3623 926761 : for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
3624 1232 : int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
3625 1232 : int const ConstrNum = Surface(SurfNum).Construction;
3626 1232 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3627 1232 : int const TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
3628 1232 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3629 2464 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3630 1232 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
3631 1232 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3632 1232 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) *
3633 1232 : (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum)) +
3634 1232 : state.dataSurface->SurfWinA(SurfNum, Lay) * currBeamSolar(SurfNum);
3635 1232 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3636 1232 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3637 1232 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3638 1232 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3639 1232 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3640 : }
3641 : }
3642 :
3643 : // Average absorbed solar for representative surfaces
3644 925529 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
3645 9212 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3646 18032 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3647 9016 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
3648 9016 : int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
3649 9016 : int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
3650 87612 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
3651 78596 : auto &surface = state.dataSurface->Surface(surfNum);
3652 78596 : if (surface.ConstituentSurfaceNums.size() > 1) {
3653 2940 : Real64 QoutAtot = 0.0;
3654 2940 : Real64 QinAtot = 0.0;
3655 2940 : Real64 Atot = 0.0;
3656 9212 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3657 6272 : QoutAtot += state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
3658 6272 : QinAtot += state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
3659 6272 : Atot += state.dataSurface->Surface(constSurfNum).Area;
3660 2940 : }
3661 :
3662 2940 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = QoutAtot / Atot;
3663 2940 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = QinAtot / Atot;
3664 : }
3665 : }
3666 9016 : firstSurf = thisSpace.WindowSurfaceFirst;
3667 9016 : lastSurf = thisSpace.WindowSurfaceLast;
3668 43904 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
3669 34888 : auto const &surface = state.dataSurface->Surface(surfNum);
3670 34888 : if (surface.ExtSolar && surface.ConstituentSurfaceNums.size() > 1) {
3671 : // Absorbed in glazing
3672 : int totalGlassLayers =
3673 3724 : state.dataConstruction->Construct(state.dataSurface->SurfActiveConstruction(surfNum)).TotGlassLayers;
3674 11172 : for (int layer = 1; layer <= totalGlassLayers; ++layer) {
3675 7448 : Real64 QAtot = 0.0;
3676 7448 : Real64 Atot = 0.0;
3677 59584 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3678 52136 : QAtot +=
3679 52136 : state.dataHeatBal->SurfWinQRadSWwinAbs(constSurfNum, layer) * state.dataSurface->Surface(constSurfNum).Area;
3680 52136 : Atot += state.dataSurface->Surface(constSurfNum).Area;
3681 7448 : }
3682 :
3683 7448 : state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, layer) = QAtot / Atot;
3684 : }
3685 :
3686 : // Absorbed by frame and dividers
3687 3724 : if (surface.FrameDivider > 0) {
3688 392 : if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
3689 0 : Real64 QoutAtot = 0.0;
3690 0 : Real64 QinAtot = 0.0;
3691 0 : Real64 Atot = 0.0;
3692 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3693 0 : QoutAtot += state.dataSurface->SurfWinFrameQRadOutAbs(constSurfNum) *
3694 0 : state.dataSurface->SurfWinFrameArea(constSurfNum);
3695 0 : QinAtot += state.dataSurface->SurfWinFrameQRadInAbs(constSurfNum) *
3696 0 : state.dataSurface->SurfWinFrameArea(constSurfNum);
3697 0 : Atot += state.dataSurface->SurfWinFrameArea(constSurfNum);
3698 0 : }
3699 :
3700 0 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = QoutAtot / Atot;
3701 0 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = QinAtot / Atot;
3702 : }
3703 392 : if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
3704 0 : Real64 QoutAtot = 0.0;
3705 0 : Real64 QinAtot = 0.0;
3706 0 : Real64 Atot = 0.0;
3707 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3708 0 : QoutAtot += state.dataSurface->SurfWinDividerQRadOutAbs(constSurfNum) *
3709 0 : state.dataSurface->SurfWinDividerArea(constSurfNum);
3710 0 : QinAtot += state.dataSurface->SurfWinDividerQRadInAbs(constSurfNum) *
3711 0 : state.dataSurface->SurfWinDividerArea(constSurfNum);
3712 0 : Atot += state.dataSurface->SurfWinDividerArea(constSurfNum);
3713 0 : }
3714 :
3715 0 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = QoutAtot / Atot;
3716 0 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = QinAtot / Atot;
3717 : }
3718 : }
3719 : }
3720 : }
3721 9016 : }
3722 : }
3723 : }
3724 925529 : } // End of sun-up check
3725 2828408 : }
3726 :
3727 2828408 : void InitIntSolarDistribution(EnergyPlusData &state)
3728 : {
3729 :
3730 : // SUBROUTINE INFORMATION:
3731 : // AUTHOR Anonymous
3732 : // DATE WRITTEN July 1977
3733 : // MODIFIED Oct 1999 (FW) to handle movable shades
3734 : // May 2000 (FW) to handle window frame and dividers
3735 : // May 2001 (FW) to handle window blinds
3736 : // Jan 2002 (FW) mods for between-glass shade/blind
3737 : // May 2006 (RR) to handle exterior window screens
3738 : // RE-ENGINEERED Mar98 (RKS)
3739 :
3740 : // PURPOSE OF THIS SUBROUTINE:
3741 : // This subroutine initializes the arrays associated with solar heat
3742 : // gains for both individual surfaces and for zones.
3743 :
3744 : // METHODOLOGY EMPLOYED:
3745 : // If the sun is down, all of the pertinent arrays are zeroed. If the
3746 : // sun is up, various calculations are made.
3747 :
3748 : // REFERENCES:
3749 : // (I)BLAST legacy routine QSUN
3750 :
3751 : using Dayltg::DistributeTDDAbsorbedSolar;
3752 : using namespace DataWindowEquivalentLayer;
3753 :
3754 2828408 : auto &s_mat = state.dataMaterial;
3755 : // COMPUTE TOTAL SHORT-WAVE RADIATION ORIGINATING IN ZONE.
3756 : // Note: If sun is not up, QS is only internal gains
3757 23359775 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3758 20531367 : Real64 sumSpaceQLTSW = 0.0;
3759 41115378 : for (int spaceNum : state.dataViewFactor->EnclSolInfo(enclosureNum).spaceNums) {
3760 20584011 : sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
3761 20531367 : }
3762 20531367 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) = state.dataHeatBal->EnclSolQD(enclosureNum) + sumSpaceQLTSW;
3763 20531367 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) = sumSpaceQLTSW;
3764 : }
3765 :
3766 2828408 : if (state.dataHeatBalSurf->InterZoneWindow) { // DO INTERZONE DISTRIBUTION.
3767 :
3768 60735 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3769 :
3770 48588 : if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclosureNum)) {
3771 :
3772 120960 : for (int OtherenclosureNum = 1; OtherenclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++OtherenclosureNum) {
3773 :
3774 96768 : if ((OtherenclosureNum != enclosureNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(OtherenclosureNum))) {
3775 24192 : Real64 sumSpaceQLTSW = 0.0;
3776 48384 : for (int spaceNum : state.dataViewFactor->EnclSolInfo(OtherenclosureNum).spaceNums) {
3777 24192 : sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
3778 24192 : }
3779 24192 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) +=
3780 24192 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
3781 24192 : (state.dataHeatBal->EnclSolQD(OtherenclosureNum) + sumSpaceQLTSW);
3782 24192 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) +=
3783 24192 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) * sumSpaceQLTSW;
3784 24192 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) +=
3785 24192 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
3786 24192 : state.dataHeatBal->EnclSolQD(OtherenclosureNum);
3787 24192 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclosureNum) =
3788 24192 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec;
3789 : }
3790 : }
3791 : }
3792 : }
3793 : }
3794 :
3795 : // Beam and diffuse solar on inside surfaces from interior windows (for reporting)
3796 :
3797 2828408 : if (state.dataEnvrn->SunIsUp) {
3798 90285070 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
3799 88871625 : auto const &surface = state.dataSurface->Surface(SurfNum);
3800 : //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
3801 88871625 : if (surface.Class == DataSurfaces::SurfaceClass::Shading) {
3802 1129 : continue;
3803 : }
3804 88870496 : int const enclosureNum = surface.SolarEnclIndex;
3805 88870496 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) =
3806 88870496 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) / state.dataViewFactor->EnclSolInfo(enclosureNum).TotalSurfArea;
3807 88870496 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) =
3808 88870496 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) * (surface.Area + state.dataSurface->SurfWinDividerArea(SurfNum));
3809 88870496 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) =
3810 88870496 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3811 1413445 : }
3812 : }
3813 :
3814 : // COMPUTE CONVECTIVE GAINS AND ZONE FLUX DENSITY.
3815 23359775 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3816 20531367 : auto const &thisSolEnclosure = state.dataViewFactor->EnclSolInfo(enclosureNum);
3817 20531367 : if (state.dataHeatBalSurf->InterZoneWindow) {
3818 48588 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) *=
3819 48588 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
3820 : // CR 8695, VMULT not based on visible
3821 48588 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *=
3822 48588 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
3823 : } else {
3824 20482779 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) *= thisSolEnclosure.solVMULT;
3825 20482779 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *= thisSolEnclosure.solVMULT;
3826 : }
3827 : }
3828 :
3829 : // COMPUTE RADIANT GAINS ON SURFACES
3830 23363819 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3831 41119422 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3832 20584011 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
3833 20584011 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
3834 20584011 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
3835 174074299 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
3836 153490288 : auto const &surface = state.dataSurface->Surface(SurfNum);
3837 153490288 : int const solEnclosureNum = surface.SolarEnclIndex;
3838 153490288 : int const ConstrNum = surface.Construction;
3839 153490288 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3840 :
3841 153490288 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum);
3842 : // TODO - AbsIntSurfVis = InsideAbsorpSolar instead of InsideAbsorpVis?
3843 153490288 : Real64 AbsIntSurfVis = thisConstruct.InsideAbsorpSolar; // Inside opaque surface visible absorptance to fix CR 8695 change to
3844 :
3845 153490288 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsIntSurf;
3846 153490288 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) += state.dataHeatBal->EnclSolQSWRadLights(solEnclosureNum) * AbsIntSurfVis;
3847 :
3848 : // Calculate absorbed solar on outside if movable exterior insulation in place
3849 153490288 : if (state.dataSurface->AnyMovableInsulation) {
3850 60732 : auto &movInsul = state.dataSurface->extMovInsuls(SurfNum);
3851 60732 : if (movInsul.present) {
3852 4047 : Real64 AbsExt = state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum);
3853 4047 : auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
3854 4047 : state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) =
3855 4047 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) * AbsExt / thisMaterial->AbsorpSolar;
3856 : // For transparent insulation, allow some sunlight to get through the movable insulation.
3857 : // The equation below is derived by taking what is transmitted through the layer and applying
3858 : // the fraction that is absorbed plus the back reflected portion (first order reflection only)
3859 : // to the plane between the transparent insulation and the exterior surface face.
3860 4047 : auto const *matMovInsul = s_mat->materials(movInsul.matNum);
3861 4047 : auto const *matFenMovInsul = dynamic_cast<Material::MaterialFen const *>(matMovInsul);
3862 4047 : Real64 transMovInsul = (matFenMovInsul != nullptr) ? matFenMovInsul->Trans : 0.0;
3863 :
3864 4047 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
3865 4047 : transMovInsul * state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) *
3866 4047 : ((thisMaterial->AbsorpSolar / AbsExt) + (1 - thisMaterial->AbsorpSolar));
3867 : }
3868 : }
3869 : // RJH 08/30/07 - Add SurfWinInitialDifSolInAbs, SurfWinInitialDifSolwinAbs, and SurfWinInitialDifSolAbsByShade
3870 : // calced in CalcWinTransDifSolInitialDistribution to SurfOpaqQRadSWInAbs, SurfWinQRadSWwinAbs, and SurfWinIntSWAbsByShade here
3871 153490288 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum);
3872 : } // end of opaque
3873 :
3874 20584011 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
3875 20584011 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
3876 44426535 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { // Window
3877 23842524 : auto const &surface = state.dataSurface->Surface(SurfNum);
3878 23842524 : auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
3879 23842524 : int const radEnclosureNum = surface.RadEnclIndex;
3880 23842524 : int const solEnclosureNum = surface.SolarEnclIndex;
3881 23842524 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3882 23842524 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3883 :
3884 23842524 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) {
3885 23834415 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
3886 :
3887 23834415 : int TotGlassLayers = thisConstruct.TotGlassLayers;
3888 23834415 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
3889 :
3890 : // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
3891 23834415 : Real64 pulseMultipler = 0.01; // use to create a pulse for the load component report computations, the W/sqft pulse for the zone
3892 23834415 : if (!state.dataGlobal->doLoadComponentPulseNow) {
3893 23834015 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
3894 23834015 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3895 23834015 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
3896 : } else {
3897 : // radiant value prior to adjustment for pulse for load component report
3898 400 : Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
3899 : // for the loads component report during the special sizing run increase the radiant portion
3900 : // a small amount to create a "pulse" of heat that is used for the
3901 : // radiant value including adjustment for pulse for load component report
3902 400 : Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
3903 : // ITABSF is the Inside Thermal Absorptance
3904 : // EnclRadThermAbsMult is a multiplier for each zone/enclosure
3905 : // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
3906 400 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
3907 400 : adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
3908 400 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
3909 : }
3910 :
3911 23834415 : if (NOT_SHADED(ShadeFlag)) { // No window shading
3912 53703850 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
3913 30156236 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3914 30156236 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
3915 : }
3916 286801 : } else if (ConstrNumSh != 0 && ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
3917 : // Interior, exterior or between-glass shade, screen or blind in place
3918 188978 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
3919 433866 : for (int IGlass = 1; IGlass <= constrSh.TotGlassLayers; ++IGlass) {
3920 244888 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
3921 93965 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3922 93965 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBack(IGlass);
3923 150923 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind || ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) {
3924 129219 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3925 129219 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3926 129219 : auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxLo];
3927 129219 : auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxHi];
3928 : // Glass layer back diffuse solar absorptance when blind in place
3929 129219 : Real64 BlAbsDiffBk = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
3930 :
3931 129219 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3932 129219 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * BlAbsDiffBk;
3933 : }
3934 : }
3935 188978 : if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
3936 44850 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3937 44850 : constrSh.ShadeAbsorpThermal *
3938 22425 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
3939 166553 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
3940 128113 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3941 128113 : Real64 EffBlEmiss = surfShade.effShadeEmi; // Blind emissivity (thermal absorptance) as part of glazing system
3942 256226 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3943 128113 : EffBlEmiss *
3944 128113 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
3945 : }
3946 :
3947 188978 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
3948 50929 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) =
3949 50929 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBackShade;
3950 138049 : } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
3951 138049 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3952 138049 : auto const &btarLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
3953 138049 : auto const &btarHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
3954 138049 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3955 138049 : Real64 AbsDiffBkBl = Interp(btarLo.Sol.Bk.Df.Abs, btarHi.Sol.Bk.Df.Abs, interpFac);
3956 :
3957 138049 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsDiffBkBl;
3958 : }
3959 : // Correct for divider shadowing
3960 188978 : if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3961 21522 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) *= surfWin.glazedFrac;
3962 : }
3963 :
3964 286801 : } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3965 71786 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh); // What was here before?
3966 215358 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
3967 :
3968 143572 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3969 143572 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
3970 143572 : Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
3971 143572 : thisConstruct.AbsDiffBack(IGlass),
3972 143572 : constructionSh.AbsDiffBack(IGlass));
3973 : }
3974 :
3975 : } // End of shading flag check
3976 :
3977 : // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
3978 23834415 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
3979 660204 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) +=
3980 660204 : (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) +
3981 660204 : (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3982 660204 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
3983 660204 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
3984 660204 : state.dataSurface->SurfWinFrameEmis(SurfNum)) *
3985 660204 : (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)); // Window has a frame
3986 : }
3987 23834415 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) { // Window has dividers
3988 329931 : Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
3989 329931 : Real64 DividerSolAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
3990 329931 : if (state.dataSurface->SurfWinDividerType(SurfNum) ==
3991 : DataSurfaces::FrameDividerType::Suspended) { // Suspended divider; account for inside glass
3992 29589 : Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass layer material number
3993 29589 : auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
3994 29589 : assert(thisMaterial != nullptr);
3995 29589 : Real64 TransGl = thisMaterial->Trans; // Glass layer solar transmittance, reflectance, absorptance
3996 29589 : Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
3997 29589 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
3998 29589 : Real64 DividerSolRefl = 1.0 - DividerSolAbs; // Window divider solar reflectance
3999 29589 : DividerSolAbs = AbsGl + TransGl * (DividerSolAbs + DividerSolRefl * AbsGl) / (1.0 - DividerSolRefl * ReflGl);
4000 29589 : DividerThermAbs = thisMaterial->AbsorpThermalBack;
4001 : }
4002 : // Correct for interior shade transmittance
4003 329931 : if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
4004 742 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4005 742 : int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers); // Shade layer material number
4006 742 : auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
4007 742 : assert(matSh != nullptr);
4008 742 : DividerSolAbs *= matSh->Trans;
4009 742 : DividerThermAbs *= matSh->TransThermal;
4010 :
4011 329189 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
4012 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4013 0 : Real64 SolBackDiffDiffTrans = surfShade.blind.TAR.Sol.Bk.Df.Tra;
4014 0 : Real64 IRBackTrans = surfShade.blind.TAR.IR.Bk.Tra;
4015 :
4016 0 : DividerSolAbs *= SolBackDiffDiffTrans;
4017 0 : DividerThermAbs *= IRBackTrans;
4018 : }
4019 : // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
4020 329931 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) +=
4021 329931 : (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * DividerSolAbs +
4022 329931 : (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
4023 329931 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
4024 329931 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
4025 329931 : DividerThermAbs) *
4026 329931 : (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
4027 : }
4028 : } else {
4029 : // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
4030 8109 : Real64 pulseMultipler = 0.01; // the W/sqft pulse for the zone
4031 8109 : if (!state.dataGlobal->doLoadComponentPulseNow) {
4032 8109 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
4033 8109 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
4034 8109 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
4035 : } else {
4036 : // radiant value prior to adjustment for pulse for load component report
4037 0 : Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
4038 : // for the loads component report during the special sizing run increase the radiant portion
4039 : // a small amount to create a "pulse" of heat that is used for the
4040 : // radiant value including adjustment for pulse for load component report
4041 0 : Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
4042 : // ITABSF is the Inside Thermal Absorptance
4043 : // EnclRadThermAbsMult is a multiplier for each zone/radiant enclosure
4044 : // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
4045 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
4046 0 : adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
4047 0 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
4048 : }
4049 : // Radiations absorbed by the window layers coming from zone side
4050 8109 : int EQLNum = thisConstruct.EQLConsPtr;
4051 37842 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4052 29733 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) +=
4053 29733 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffBackEQL(Lay);
4054 : }
4055 : // Window frame has not been included for equivalent layer model yet
4056 :
4057 : } // end if for IF ( SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: EQL) THEN
4058 :
4059 23842524 : if (surface.ExtBoundCond > 0) { // Interzone surface
4060 : // Short-wave radiation absorbed in panes of corresponding window in adjacent zone
4061 27192 : int SurfNumAdjZone = surface.ExtBoundCond; // Surface number in adjacent zone for interzone surfaces
4062 27192 : if (state.dataSurface->SurfWinWindowModelType(SurfNumAdjZone) != DataSurfaces::WindowModel::EQL) {
4063 27192 : int TotGlassLayers = thisConstruct.TotGlassLayers;
4064 54384 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4065 27192 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, IGlass) +=
4066 27192 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
4067 27192 : state.dataConstruction->Construct(state.dataSurface->Surface(SurfNumAdjZone).Construction).AbsDiff(IGlass);
4068 : // Note that AbsDiff rather than AbsDiffBack is used in the above since the
4069 : // radiation from the current zone is incident on the outside of the adjacent
4070 : // zone's window.
4071 : }
4072 : } else { // IF (SurfaceWindow(SurfNumAdjZone)%WindowModelType == WindowModel:: EQL) THEN
4073 0 : int const AdjConstrNum = state.dataSurface->Surface(SurfNumAdjZone).Construction;
4074 0 : int const EQLNum = state.dataConstruction->Construct(AdjConstrNum).EQLConsPtr;
4075 0 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4076 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, Lay) +=
4077 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffFrontEQL(Lay);
4078 : // Note that AbsDiffFrontEQL rather than AbsDiffBackEQL is used in the above
4079 : // since the radiation from the current zone is incident on the outside of the
4080 : // adjacent zone's window.
4081 : }
4082 : }
4083 : }
4084 :
4085 23842524 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) {
4086 23794875 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
4087 23794875 : int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
4088 23794875 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4089 23794875 : if (DataSurfaces::NOT_SHADED(ShadeFlag)) { // No window shading
4090 53657266 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4091 30123155 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4092 : }
4093 260764 : } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
4094 215358 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4095 143572 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4096 : }
4097 : } else {
4098 188978 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4099 : // Interior, exterior or between-glass shade, screen or blind in place
4100 433866 : for (int IGlass = 1; IGlass <= constructionSh.TotGlassLayers; ++IGlass) {
4101 244888 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4102 : }
4103 188978 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag) || DataSurfaces::ANY_BLIND(ShadeFlag)) {
4104 188978 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum);
4105 : }
4106 : } // End of shading flag check
4107 47649 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
4108 39540 : int TotGlassLayers = thisConstruct.TotGlassLayers;
4109 119289 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4110 79749 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4111 : }
4112 8109 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
4113 :
4114 : // ConstrNum = Surface(SurfNum)%Construction
4115 8109 : int EQLNum = thisConstruct.EQLConsPtr;
4116 :
4117 37842 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4118 29733 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay);
4119 : }
4120 : }
4121 :
4122 : } // End of window
4123 20535411 : }
4124 : }
4125 2828408 : Dayltg::DistributeTDDAbsorbedSolar(state);
4126 2828408 : }
4127 :
4128 2828408 : void ComputeIntThermalAbsorpFactors(EnergyPlusData &state)
4129 : {
4130 :
4131 : // SUBROUTINE INFORMATION:
4132 : // AUTHOR Legacy Code (George Walton)
4133 : // DATE WRITTEN Legacy: Dec 1976
4134 : // MODIFIED Nov. 99, FCW: to take into account movable interior shades and switchable glazing
4135 : // June 01, FCW: to take into account interior blinds.
4136 :
4137 : // PURPOSE OF THIS SUBROUTINE:
4138 : // This routine computes the fractions of long-wave radiation from lights, equipment and people
4139 : // that is absorbed by each zone surface.
4140 :
4141 : // METHODOLOGY EMPLOYED:
4142 : // The fraction is assumed to be proportional to the product of the surface area times its thermal absorptivity.
4143 :
4144 : // REFERENCES:
4145 : // BLAST Routine: CITAF - Compute Interior Thermal Absorption Factors
4146 2828408 : auto &s_mat = state.dataMaterial;
4147 :
4148 23359775 : for (auto const &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
4149 20531367 : if (!thisEnclosure.radReCalc) {
4150 20352007 : continue;
4151 : }
4152 358874 : for (int spaceNum : thisEnclosure.spaceNums) {
4153 179514 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4154 179514 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
4155 179514 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
4156 604369 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
4157 424855 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4158 424855 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4159 10800 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4160 10800 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
4161 : } else {
4162 414055 : int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
4163 414055 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal;
4164 : }
4165 : }
4166 179360 : }
4167 2828408 : }
4168 2828408 : if (state.dataSurface->AnyMovableSlat) {
4169 12150 : for (int SurfNum : state.dataHeatBalSurf->SurfMovSlatsIndexList) {
4170 : // For window with an interior shade or blind, emissivity is a combination of glass and shade/blind emissivity
4171 6075 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4172 : // Not sure we need to do this anymore
4173 6075 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4174 2578 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4175 2578 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
4176 : }
4177 6075 : }
4178 : }
4179 :
4180 23359775 : for (auto &thisRadEnclosure : state.dataViewFactor->EnclRadInfo) {
4181 20531367 : if (!thisRadEnclosure.radReCalc) {
4182 20352007 : continue;
4183 : }
4184 179360 : Real64 SUM1 = 0.0;
4185 1929693 : for (int const SurfNum : thisRadEnclosure.SurfacePtr) {
4186 1750333 : auto &surf = state.dataSurface->Surface(SurfNum);
4187 1750333 : int const ConstrNum = surf.Construction;
4188 1750333 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
4189 1750333 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4190 1750333 : if (ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
4191 1750333 : SUM1 += surf.Area * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
4192 : } else { // Switchable glazing
4193 0 : SUM1 += surf.Area * Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
4194 0 : thisConstruct.InsideAbsorpThermal,
4195 0 : state.dataConstruction->Construct(surf.activeShadedConstruction).InsideAbsorpThermal);
4196 : }
4197 :
4198 : // Window frame and divider effects
4199 1750333 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
4200 122826 : SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) *
4201 122826 : state.dataSurface->SurfWinFrameEmis(SurfNum);
4202 : }
4203 1750333 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
4204 121637 : Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
4205 : // Suspended (between-glass) divider; relevant emissivity is inner glass emissivity
4206 121637 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
4207 95 : DividerThermAbs = thisConstruct.InsideAbsorpThermal;
4208 : }
4209 121637 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4210 : // Interior shade or blind in place
4211 14 : int const ConstrNumSh = surf.activeShadedConstruction;
4212 14 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4213 :
4214 14 : if (state.dataSurface->SurfWinHasShadeOrBlindLayer(SurfNum)) {
4215 14 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4216 : // Shade layer material number
4217 14 : int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers);
4218 14 : auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
4219 14 : assert(matSh != nullptr);
4220 : // Shade or blind IR transmittance
4221 14 : Real64 TauShIR = matSh->TransThermal;
4222 : // Effective emissivity of shade or blind
4223 14 : Real64 EffShDevEmiss = surfShade.effShadeEmi;
4224 :
4225 14 : if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
4226 0 : TauShIR = surfShade.blind.TAR.IR.Bk.Tra;
4227 : }
4228 14 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (EffShDevEmiss + DividerThermAbs * TauShIR);
4229 : } else {
4230 : // this is for EMS activated shade/blind but the window construction has no shade/blind layer
4231 0 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
4232 : DividerThermAbs;
4233 : }
4234 : } else {
4235 121623 : SUM1 +=
4236 121623 : state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * DividerThermAbs;
4237 : }
4238 : }
4239 :
4240 : } // End of loop over surfaces in zone/enclosure
4241 179360 : thisRadEnclosure.radThermAbsMult = 1.0 / SUM1;
4242 :
4243 2828408 : } // End of loop over enclosures
4244 2828408 : }
4245 :
4246 2828408 : void ComputeIntSWAbsorpFactors(EnergyPlusData &state)
4247 : {
4248 :
4249 : // SUBROUTINE INFORMATION:
4250 : // AUTHOR Legacy (George Walton)
4251 : // DATE WRITTEN Legacy (December 1980)
4252 : // MODIFIED Nov. 99, FW; now called every time step to account for movable
4253 : // window shades and insulation
4254 : // Mar. 00, FW; change name from ComputeVisLightingAbsorpFactors
4255 : // to ComputeIntSWAbsorpFactors
4256 : // May 00, FW; add window frame and divider effects
4257 : // June 01, FW: account for window blinds
4258 : // Nov 01, FW: account for absorptance of exterior shades and interior or exterior blinds
4259 : // Jan 03, FW: add between-glass shade/blind
4260 : // May 06, RR: account for exterior window screens
4261 :
4262 : // PURPOSE OF THIS SUBROUTINE:
4263 : // Computes VMULT, the inverse of the sum of area*(short-wave absorptance+transmittance) for
4264 : // the surfaces in a zone. VMULT is used to calculate the zone interior diffuse short-wave radiation
4265 : // absorbed by the inside of opaque zone surfaces or by the glass and shade/blind layers of zone windows.
4266 :
4267 : // Sets VCONV to zero (VCONV was formerly used to calculate convective gain due to short-wave
4268 : // radiation absorbed by interior window shades).
4269 :
4270 : // REFERENCES:
4271 : // BLAST Routine - CIVAF - Compute Surface Absorption Factors For Short Wave Radiation
4272 : // From Zone Lights And Diffuse Solar.
4273 :
4274 : // Avoid a division by zero of the user has entered a bunch of surfaces with zero absorptivity on the inside
4275 2828408 : Real64 constexpr SmallestAreaAbsProductAllowed(0.01);
4276 :
4277 2828408 : auto &s_mat = state.dataMaterial;
4278 :
4279 23359775 : for (auto &thisSolEnclosure : state.dataViewFactor->EnclSolInfo) {
4280 20531367 : if (!thisSolEnclosure.radReCalc) {
4281 20352007 : continue;
4282 : }
4283 179360 : Real64 SUM1 = 0.0; // Intermediate calculation value for solar absorbed and transmitted
4284 :
4285 1930872 : for (int const SurfNum : thisSolEnclosure.SurfacePtr) {
4286 1751512 : auto &thisSurf = state.dataSurface->Surface(SurfNum);
4287 1751512 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
4288 1751512 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
4289 1751512 : if (thisConstruct.TransDiff <= 0.0) {
4290 : // Opaque surface
4291 1328762 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum); // Inside surface short-wave absorptance
4292 1328762 : SUM1 += thisSurf.Area * AbsIntSurf;
4293 :
4294 : } else {
4295 : // Window
4296 422750 : if (!state.dataConstruction->Construct(thisSurf.Construction).WindowTypeEQL) {
4297 416756 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4298 :
4299 416756 : Real64 AbsDiffTotWin = 0.0; // Sum of window layer short-wave absorptances
4300 416756 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
4301 416756 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
4302 :
4303 : // Sum of absorptances of glass layers
4304 997672 : for (int Lay = 1; Lay <= thisConstruct.TotGlassLayers; ++Lay) {
4305 580916 : Real64 AbsDiffLayWin = thisConstruct.AbsDiffBack(Lay); // Window layer short-wave absorptance
4306 :
4307 : // Window with shade, screen or blind
4308 580916 : if (ConstrNumSh != 0) {
4309 269568 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4310 269568 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
4311 13665 : AbsDiffLayWin = constrSh.AbsDiffBack(Lay);
4312 255903 : } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
4313 8643 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4314 8643 : auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxLo];
4315 8643 : auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxHi];
4316 8643 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
4317 8643 : AbsDiffLayWin = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
4318 : }
4319 : }
4320 :
4321 : // Switchable glazing
4322 580916 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
4323 0 : assert(ConstrNumSh > 0); // Should this be included in the if above
4324 0 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4325 0 : AbsDiffLayWin = Window::InterpSw(SwitchFac, AbsDiffLayWin, constrSh.AbsDiffBack(Lay));
4326 : }
4327 580916 : AbsDiffTotWin += AbsDiffLayWin;
4328 : }
4329 :
4330 416756 : Real64 TransDiffWin = thisConstruct.TransDiff; // Window diffuse short-wave transmittance
4331 416756 : Real64 DiffAbsShade = 0.0; // Diffuse short-wave shade or blind absorptance
4332 :
4333 : // Window with shade, screen or blind
4334 :
4335 416756 : if (ConstrNumSh != 0) {
4336 143813 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4337 143813 : if (ANY_SHADE_SCREEN(ShadeFlag)) {
4338 7679 : TransDiffWin = constrSh.TransDiff;
4339 7679 : DiffAbsShade = constrSh.AbsDiffBackShade;
4340 136134 : } else if (ANY_BLIND(ShadeFlag)) {
4341 8605 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4342 8605 : auto const &btarSlatLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
4343 8605 : auto const &btarSlatHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
4344 8605 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
4345 8605 : TransDiffWin = Interp(btarSlatLo.Sol.Ft.Df.Tra, btarSlatHi.Sol.Ft.Df.Tra, interpFac);
4346 8605 : DiffAbsShade = Interp(btarSlatLo.Sol.Bk.Df.Abs, btarSlatHi.Sol.Bk.Df.Abs, interpFac);
4347 : }
4348 : }
4349 :
4350 : // Switchable glazing
4351 :
4352 416756 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
4353 0 : assert(ConstrNumSh > 0);
4354 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4355 0 : TransDiffWin = Window::InterpSw(SwitchFac, TransDiffWin, constructionSh.TransDiff);
4356 : }
4357 :
4358 416756 : SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin + DiffAbsShade);
4359 :
4360 : // Window frame and divider effects (shade area is glazed area plus divider area)
4361 :
4362 416756 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
4363 122826 : SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) *
4364 122826 : (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum));
4365 : }
4366 416756 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
4367 121637 : Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
4368 121637 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
4369 : // Suspended (between-glass) divider: account for glass on inside of divider
4370 95 : Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass material number
4371 95 : auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
4372 95 : assert(thisMaterial != nullptr);
4373 95 : Real64 TransGl = thisMaterial->Trans; // Glass layer short-wave transmittance, reflectance, absorptance
4374 95 : Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
4375 95 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
4376 95 : Real64 DividerRefl = 1.0 - DividerAbs; // Window divider short-wave reflectance
4377 95 : DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
4378 : }
4379 121637 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4380 14 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (DividerAbs + DiffAbsShade);
4381 : } else {
4382 121623 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
4383 : DividerAbs;
4384 : }
4385 : }
4386 : } else { // equivalent layer window
4387 : // In equivalent layer window solid layers (Glazing and shades) are treated equally
4388 : // frames and dividers are not supported
4389 5994 : Real64 AbsDiffTotWin = 0.0;
4390 5994 : Real64 AbsDiffLayWin = 0.0;
4391 5994 : Real64 TransDiffWin = thisConstruct.TransDiff;
4392 28000 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL; ++Lay) {
4393 22006 : AbsDiffLayWin = thisConstruct.AbsDiffBackEQL(Lay);
4394 22006 : AbsDiffTotWin += AbsDiffLayWin;
4395 : }
4396 5994 : SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin);
4397 : }
4398 : } // End of check if opaque surface or window
4399 : } // End of loop over surfaces in zone
4400 :
4401 179360 : if (SUM1 > SmallestAreaAbsProductAllowed) { // Everything is okay, proceed with the regular calculation
4402 179355 : thisSolEnclosure.solVMULT = 1.0 / SUM1;
4403 :
4404 : } else { // the sum of area*solar absorptance for all surfaces in the zone is zero--either the user screwed up
4405 : // or they really want to disallow any solar from being absorbed on the inside surfaces. Fire off a
4406 : // nasty warning message and then assume that no solar is ever absorbed (basically everything goes
4407 : // back out whatever window is there. Note that this also assumes that the shade has no effect.
4408 : // That's probably not correct, but how correct is it to assume that no solar is absorbed anywhere
4409 : // in the zone?
4410 5 : if (thisSolEnclosure.solAbsFirstCalc) {
4411 2 : ShowWarningError(
4412 : state,
4413 2 : format("ComputeIntSWAbsorbFactors: Sum of area times inside solar absorption for all surfaces is zero in Enclosure: {}",
4414 1 : thisSolEnclosure.Name));
4415 1 : thisSolEnclosure.solAbsFirstCalc = false;
4416 : }
4417 5 : thisSolEnclosure.solVMULT = 0.0;
4418 : }
4419 2828408 : } // End of enclosure loop
4420 2828408 : }
4421 :
4422 12147 : void ComputeDifSolExcZonesWIZWindows(EnergyPlusData &state)
4423 : {
4424 :
4425 : // SUBROUTINE INFORMATION:
4426 : // MODIFIED Jun 2007 - Lawrie - Speed enhancements.
4427 : // RE-ENGINEERED Winkelmann, Lawrie
4428 :
4429 : // PURPOSE OF THIS SUBROUTINE:
4430 : // This subroutine computes the diffuse solar exchange factors between enclosures with
4431 : // interzone windows.
4432 :
4433 12147 : int const numEnclosures = state.dataViewFactor->NumOfSolarEnclosures;
4434 12147 : if (!allocated(state.dataHeatBalSurf->ZoneFractDifShortZtoZ)) {
4435 6 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ.allocate(numEnclosures, numEnclosures);
4436 6 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ.allocate(numEnclosures);
4437 6 : state.dataHeatBalSurfMgr->DiffuseArray.allocate(numEnclosures, numEnclosures);
4438 : }
4439 :
4440 12147 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ = false;
4441 12147 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ.to_identity();
4442 12147 : state.dataHeatBalSurfMgr->DiffuseArray.to_identity();
4443 :
4444 : // IF (.not. ANY(Zone%HasInterZoneWindow)) RETURN ! this caused massive diffs
4445 12147 : if (state.dataGlobal->KickOffSimulation || state.dataGlobal->KickOffSizing) {
4446 51 : return;
4447 : }
4448 : // Compute fraction transmitted in one pass.
4449 :
4450 101664 : for (int const SurfNum : state.dataSurface->AllHTWindowSurfaceList) {
4451 89568 : auto &surface = state.dataSurface->Surface(SurfNum);
4452 89568 : if (surface.ExtBoundCond <= 0) {
4453 62496 : continue;
4454 : }
4455 27072 : if (surface.ExtBoundCond == SurfNum) {
4456 0 : continue;
4457 : }
4458 27072 : if (state.dataConstruction->Construct(surface.Construction).TransDiff <= 0.0) {
4459 0 : continue;
4460 : }
4461 :
4462 27072 : int surfEnclNum = surface.SolarEnclIndex;
4463 27072 : if (!state.dataViewFactor->EnclSolInfo(surfEnclNum).HasInterZoneWindow) {
4464 0 : continue;
4465 : }
4466 27072 : int MZ = state.dataSurface->Surface(surface.ExtBoundCond).SolarEnclIndex;
4467 54144 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(surfEnclNum, MZ) += state.dataConstruction->Construct(surface.Construction).TransDiff *
4468 27072 : state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT * surface.Area;
4469 27072 : if (state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT != 0.0) {
4470 27072 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ(surfEnclNum) = true;
4471 : }
4472 12096 : }
4473 : // Compute fractions for multiple passes.
4474 :
4475 12096 : Array2D<Real64>::size_type l(0u), m(0u), d(0u);
4476 60480 : for (int NZ = 1; NZ <= numEnclosures; ++NZ, d += numEnclosures + 1) {
4477 48384 : m = NZ - 1;
4478 48384 : Real64 D_d(0.0); // Local accumulator
4479 241920 : for (int MZ = 1; MZ <= numEnclosures; ++MZ, ++l, m += numEnclosures) {
4480 193536 : if (MZ == NZ) {
4481 48384 : continue;
4482 : }
4483 145152 : state.dataHeatBalSurfMgr->DiffuseArray[l] =
4484 145152 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] /
4485 290304 : (1.0 - state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] *
4486 145152 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m]); // [ l ] == ( MZ, NZ ), [ m ] == ( NZ, MZ )
4487 145152 : D_d += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m] * state.dataHeatBalSurfMgr->DiffuseArray[l];
4488 : }
4489 48384 : state.dataHeatBalSurfMgr->DiffuseArray[d] += D_d; // [ d ] == ( NZ, NZ )
4490 : }
4491 :
4492 12096 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ = state.dataHeatBalSurfMgr->DiffuseArray;
4493 : // added for CR 7999 & 7869
4494 12096 : assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize1() == numEnclosures);
4495 12096 : assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize2() == numEnclosures);
4496 60480 : for (int NZ = 1; NZ <= numEnclosures; ++NZ) {
4497 197568 : for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
4498 173376 : if (MZ == NZ) {
4499 36288 : continue;
4500 : }
4501 137088 : if (state.dataHeatBalSurf->ZoneFractDifShortZtoZ(MZ, NZ) > 0.0) {
4502 24192 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ(NZ) = true;
4503 24192 : break;
4504 : }
4505 : }
4506 : }
4507 :
4508 : // Compute fractions for multiple zones.
4509 :
4510 60480 : for (int IZ = 1; IZ <= numEnclosures; ++IZ) {
4511 48384 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(IZ)) {
4512 24192 : continue;
4513 : }
4514 :
4515 120960 : for (int JZ = 1; JZ <= numEnclosures; ++JZ) {
4516 96768 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(JZ)) {
4517 48384 : continue;
4518 : }
4519 48384 : if (IZ == JZ) {
4520 24192 : continue;
4521 : }
4522 24192 : if (state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ) == 0.0) {
4523 0 : continue;
4524 : }
4525 :
4526 120960 : for (int KZ = 1; KZ <= numEnclosures; ++KZ) {
4527 96768 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(KZ)) {
4528 48384 : continue;
4529 : }
4530 48384 : if (IZ == KZ) {
4531 24192 : continue;
4532 : }
4533 24192 : if (JZ == KZ) {
4534 24192 : continue;
4535 : }
4536 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) == 0.0) {
4537 0 : continue;
4538 : }
4539 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, KZ) +=
4540 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4541 :
4542 0 : for (int LZ = 1; LZ <= numEnclosures; ++LZ) {
4543 0 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(LZ)) {
4544 0 : continue;
4545 : }
4546 0 : if (IZ == LZ) {
4547 0 : continue;
4548 : }
4549 0 : if (JZ == LZ) {
4550 0 : continue;
4551 : }
4552 0 : if (KZ == LZ) {
4553 0 : continue;
4554 : }
4555 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) == 0.0) {
4556 0 : continue;
4557 : }
4558 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, LZ) += state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
4559 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) *
4560 0 : state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4561 :
4562 0 : for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
4563 0 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(MZ)) {
4564 0 : continue;
4565 : }
4566 0 : if (IZ == MZ) {
4567 0 : continue;
4568 : }
4569 0 : if (JZ == MZ) {
4570 0 : continue;
4571 : }
4572 0 : if (KZ == MZ) {
4573 0 : continue;
4574 : }
4575 0 : if (LZ == MZ) {
4576 0 : continue;
4577 : }
4578 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) == 0.0) {
4579 0 : continue;
4580 : }
4581 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, MZ) +=
4582 0 : state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) * state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
4583 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4584 : } // MZ Loop
4585 :
4586 : } // LZ Loop
4587 :
4588 : } // KZ Loop
4589 :
4590 : } // JZ Loop
4591 :
4592 : } // IZ Loop
4593 : } // ComputeDifSolExcZoneWIZWindows()
4594 :
4595 421444 : void InitEMSControlledSurfaceProperties(EnergyPlusData &state)
4596 : {
4597 :
4598 : // SUBROUTINE INFORMATION:
4599 : // AUTHOR B. Griffith
4600 : // DATE WRITTEN April 2011
4601 :
4602 : // PURPOSE OF THIS SUBROUTINE:
4603 : // initialize material and construction surface properties if being overridden by EMS
4604 :
4605 : // METHODOLOGY EMPLOYED:
4606 : // update solar, thermal and visible absorptance values when actuated by EMS
4607 :
4608 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4609 : int TotLayers; // count of material layers in a construction
4610 : int InsideMaterNum; // integer pointer for inside face's material layer
4611 : int OutsideMaterNum; // integer pointer for outside face's material layer
4612 :
4613 421444 : auto &s_mat = state.dataMaterial;
4614 :
4615 421444 : state.dataGlobal->AnySurfPropOverridesInModel = false;
4616 : // first determine if anything needs to be done, once yes, then always init
4617 9463148 : for (auto const *mat : s_mat->materials) {
4618 9041704 : if (mat->group != Material::Group::Regular) {
4619 1248395 : continue;
4620 : }
4621 :
4622 7793309 : if ((mat->AbsorpSolarEMSOverrideOn) || (mat->AbsorpThermalEMSOverrideOn) || (mat->AbsorpVisibleEMSOverrideOn)) {
4623 0 : state.dataGlobal->AnySurfPropOverridesInModel = true;
4624 0 : break;
4625 : }
4626 : }
4627 :
4628 421444 : if (!state.dataGlobal->AnySurfPropOverridesInModel) {
4629 421444 : return; // quick return if nothing has ever needed to be done
4630 : }
4631 :
4632 : // first, loop over materials
4633 : // why is this a second loop?
4634 0 : for (auto *mat : s_mat->materials) {
4635 0 : if (mat->group != Material::Group::Regular) {
4636 0 : continue;
4637 : }
4638 :
4639 0 : mat->AbsorpSolar = mat->AbsorpSolarEMSOverrideOn ? max(min(mat->AbsorpSolarEMSOverride, 0.9999), 0.0001) : mat->AbsorpSolarInput;
4640 0 : mat->AbsorpThermal = mat->AbsorpThermalEMSOverrideOn ? max(min(mat->AbsorpThermalEMSOverride, 0.9999), 0.0001) : mat->AbsorpThermalInput;
4641 0 : mat->AbsorpVisible = mat->AbsorpVisibleEMSOverrideOn ? max(min(mat->AbsorpVisibleEMSOverride, 0.9999), 0.0001) : mat->AbsorpVisibleInput;
4642 : } // loop over materials
4643 :
4644 : // second, loop over constructions
4645 0 : for (auto &thisConstruct : state.dataConstruction->Construct) {
4646 0 : if (thisConstruct.TypeIsWindow) {
4647 0 : continue; // only override opaque constructions
4648 : }
4649 0 : TotLayers = thisConstruct.TotLayers;
4650 0 : if (TotLayers == 0) {
4651 0 : continue; // error condition
4652 : }
4653 0 : InsideMaterNum = thisConstruct.LayerPoint(TotLayers);
4654 0 : if (InsideMaterNum != 0) {
4655 0 : auto const *mat = s_mat->materials(InsideMaterNum);
4656 0 : thisConstruct.InsideAbsorpVis = mat->AbsorpVisible;
4657 0 : thisConstruct.InsideAbsorpSolar = mat->AbsorpSolar;
4658 0 : thisConstruct.InsideAbsorpThermal = mat->AbsorpThermal;
4659 : }
4660 :
4661 0 : OutsideMaterNum = thisConstruct.LayerPoint(1);
4662 0 : if (OutsideMaterNum != 0) {
4663 0 : auto const *mat = s_mat->materials(OutsideMaterNum);
4664 0 : thisConstruct.OutsideAbsorpVis = mat->AbsorpVisible;
4665 0 : thisConstruct.OutsideAbsorpSolar = mat->AbsorpSolar;
4666 0 : thisConstruct.OutsideAbsorpThermal = mat->AbsorpThermal;
4667 : }
4668 : } // for (ConstrNum)
4669 : } // InitEMSControlledSurfaceProperties()
4670 :
4671 421444 : void InitEMSControlledConstructions(EnergyPlusData &state)
4672 : {
4673 :
4674 : // SUBROUTINE INFORMATION:
4675 : // AUTHOR B. Griffith
4676 : // DATE WRITTEN Jan 2012
4677 :
4678 : // PURPOSE OF THIS SUBROUTINE:
4679 : // change construction on surface if overridden by EMS
4680 :
4681 421444 : state.dataGlobal->AnyConstrOverridesInModel = false;
4682 46147562 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4683 45732177 : if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum)) {
4684 6059 : state.dataGlobal->AnyConstrOverridesInModel = true;
4685 6059 : break;
4686 : }
4687 : }
4688 421444 : if (!state.dataGlobal->AnyConstrOverridesInModel) {
4689 415385 : return;
4690 : }
4691 :
4692 424130 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4693 418071 : auto &surface = state.dataSurface->Surface(SurfNum);
4694 :
4695 418071 : if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum) && (state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum) > 0)) {
4696 :
4697 6059 : if (state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
4698 6059 : .TypeIsWindow) { // okay, always allow windows
4699 6059 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
4700 6059 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
4701 : }
4702 :
4703 12118 : if ((state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) &&
4704 6059 : (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum))) {
4705 :
4706 6059 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4707 6059 : state.dataConstruction->Construct(surface.Construction).IsUsed = true;
4708 6059 : state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4709 :
4710 : } else { // have not checked yet or is not okay, so see if we need to warn about incompatible
4711 0 : if (!state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) {
4712 : // check if constructions appear compatible
4713 :
4714 0 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
4715 0 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
4716 : // compare old construction to new construction and see if terms match
4717 : // set as okay and turn false if find a big problem
4718 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4719 : true;
4720 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4721 : true;
4722 0 : if (state.dataConstruction->Construct(surface.Construction).NumHistories !=
4723 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories) {
4724 : // throw warning, but allow
4725 0 : ShowWarningError(state,
4726 : "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
4727 : "CTF timescales are being used.");
4728 0 : ShowContinueError(state,
4729 0 : format("Construction named = {} has CTF timesteps = {}",
4730 0 : state.dataConstruction->Construct(surface.Construction).Name,
4731 0 : state.dataConstruction->Construct(surface.Construction).NumHistories));
4732 0 : ShowContinueError(
4733 : state,
4734 0 : format("While construction named = {} has CTF timesteps = {}",
4735 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4736 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories));
4737 0 : ShowContinueError(
4738 : state,
4739 0 : format("Transient heat transfer modeling may not be valid for surface name = {}, and the simulation continues",
4740 0 : surface.Name));
4741 : }
4742 0 : if (state.dataConstruction->Construct(surface.Construction).NumCTFTerms !=
4743 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms) {
4744 : // throw warning, but allow
4745 0 : ShowWarningError(state,
4746 : "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
4747 : "CTF terms are being used.");
4748 0 : ShowContinueError(state,
4749 0 : format("Construction named = {} has number of CTF terms = {}",
4750 0 : state.dataConstruction->Construct(surface.Construction).Name,
4751 0 : state.dataConstruction->Construct(surface.Construction).NumCTFTerms));
4752 0 : ShowContinueError(
4753 : state,
4754 0 : format("While construction named = {} has number of CTF terms = {}",
4755 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4756 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms));
4757 0 : ShowContinueError(state,
4758 0 : format("The actuator is allowed but the transient heat transfer modeling may not be valid for surface "
4759 : "name = {}, and the simulation continues",
4760 0 : surface.Name));
4761 : }
4762 :
4763 0 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
4764 0 : if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
4765 : // throw warning, and do not allow
4766 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4767 0 : ShowContinueError(state,
4768 0 : format("Construction named = {} has internal source/sink",
4769 0 : state.dataConstruction->Construct(surface.Construction).Name));
4770 0 : ShowContinueError(
4771 : state,
4772 0 : format("While construction named = {} is not an internal source/sink construction",
4773 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
4774 0 : ShowContinueError(
4775 : state,
4776 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4777 0 : surface.Name));
4778 :
4779 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4780 0 : SurfNum) = false;
4781 : }
4782 : }
4783 :
4784 0 : if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4785 : SurfNum)) {
4786 0 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4787 : }
4788 :
4789 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
4790 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4791 : true;
4792 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4793 : true;
4794 0 : if (state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes !=
4795 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).TotNodes) {
4796 : // throw warning, and do not allow
4797 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4798 0 : ShowContinueError(state,
4799 0 : format("Construction named = {} has number of finite difference nodes ={}",
4800 0 : state.dataConstruction->Construct(surface.Construction).Name,
4801 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes));
4802 0 : ShowContinueError(
4803 : state,
4804 0 : format("While construction named = {}has number of finite difference nodes ={}",
4805 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4806 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
4807 0 : .TotNodes));
4808 0 : ShowContinueError(
4809 : state,
4810 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4811 0 : surface.Name));
4812 :
4813 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4814 : false;
4815 : }
4816 :
4817 0 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
4818 0 : if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
4819 : // throw warning, and do not allow
4820 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4821 0 : ShowContinueError(state,
4822 0 : format("Construction named = {} has internal source/sink",
4823 0 : state.dataConstruction->Construct(surface.Construction).Name));
4824 0 : ShowContinueError(
4825 : state,
4826 0 : format("While construction named = {} is not an internal source/sink construction",
4827 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
4828 0 : ShowContinueError(
4829 : state,
4830 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4831 0 : surface.Name));
4832 :
4833 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4834 0 : SurfNum) = false;
4835 : }
4836 : }
4837 :
4838 0 : if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4839 : SurfNum)) {
4840 0 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4841 : }
4842 :
4843 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { // don't allow
4844 0 : ShowSevereError(state,
4845 : "InitEMSControlledConstructions: EMS Construction State Actuator not available with Heat transfer "
4846 : "algorithm CombinedHeatAndMoistureFiniteElement.");
4847 0 : ShowContinueError(
4848 : state,
4849 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4850 0 : surface.Name));
4851 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4852 : true;
4853 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4854 : false;
4855 :
4856 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) { // don't allow
4857 0 : ShowSevereError(state,
4858 : "InitEMSControlledConstructions: EMS Construction State Actuator not available for Surfaces with "
4859 : "Foundation Outside Boundary Condition.");
4860 0 : ShowContinueError(
4861 : state,
4862 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4863 0 : surface.Name));
4864 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4865 : true;
4866 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4867 : false;
4868 : }
4869 :
4870 : } else {
4871 : // do nothing, has been checked and is not okay with single warning already issued.
4872 : }
4873 : }
4874 : } else {
4875 412012 : surface.Construction = surface.ConstructionStoredInputValue;
4876 412012 : state.dataSurface->SurfActiveConstruction(SurfNum) = surface.ConstructionStoredInputValue;
4877 : }
4878 : } // for (SurfNum)
4879 : } // InitEMSControlledConstructions()
4880 :
4881 : // End Initialization Section of the Module
4882 : //******************************************************************************
4883 :
4884 : // Begin Algorithm Section of the Module
4885 : //******************************************************************************
4886 :
4887 : // Beginning of Record Keeping subroutines for the HB Module
4888 : // *****************************************************************************
4889 :
4890 3760544 : void UpdateIntermediateSurfaceHeatBalanceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
4891 : {
4892 3760544 : int firstZone = 1;
4893 3760544 : int lastZone = state.dataGlobal->NumOfZones;
4894 :
4895 3760544 : if (present(ZoneToResimulate)) {
4896 796099 : firstZone = ZoneToResimulate;
4897 796099 : lastZone = ZoneToResimulate;
4898 : }
4899 :
4900 25695242 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4901 43917996 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4902 21983298 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4903 21983298 : int const firstSurf = thisSpace.WindowSurfaceFirst;
4904 21983298 : int const lastSurf = thisSpace.WindowSurfaceLast;
4905 46809985 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4906 24826687 : if (state.dataSurface->Surface(surfNum).ExtSolar) { // WindowManager's definition of ZoneWinHeatGain/Loss
4907 24795445 : state.dataHeatBal->ZoneWinHeatGain(zoneNum) += state.dataSurface->SurfWinHeatGain(surfNum);
4908 : }
4909 : }
4910 : // Update zone window heat gain reports (these intermediate values are also used for Sensible Heat Gain Summary in GatherHeatGainReport)
4911 21983298 : if (state.dataHeatBal->ZoneWinHeatGain(zoneNum) >= 0.0) {
4912 13057502 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = state.dataHeatBal->ZoneWinHeatGain(zoneNum);
4913 13057502 : state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) =
4914 13057502 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
4915 : } else {
4916 8925796 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = -state.dataHeatBal->ZoneWinHeatGain(zoneNum);
4917 8925796 : state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) =
4918 8925796 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
4919 : }
4920 21934698 : }
4921 : }
4922 :
4923 3760544 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
4924 687 : UpdateNonRepresentativeSurfaceResults(state, ZoneToResimulate);
4925 : }
4926 :
4927 : // Opaque or window surfaces (Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.)
4928 25695242 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4929 43917996 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4930 21983298 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4931 21983298 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
4932 21983298 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
4933 209696807 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4934 187713509 : state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) =
4935 187713509 : -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
4936 187713509 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
4937 : }
4938 21934698 : }
4939 : }
4940 : // Opaque surfaces
4941 25695242 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4942 43917996 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4943 21983298 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4944 21983298 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
4945 21983298 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
4946 184870120 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4947 162886822 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) =
4948 162886822 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum);
4949 : }
4950 21934698 : }
4951 : }
4952 : // Inside face conduction calculation for Kiva surfaces
4953 3878804 : for (int surfNum : state.dataSurface->AllHTKivaSurfaceList) {
4954 118260 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) =
4955 118260 : -(state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
4956 118260 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
4957 118260 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum));
4958 3760544 : }
4959 3760544 : }
4960 :
4961 687 : void UpdateNonRepresentativeSurfaceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
4962 : {
4963 687 : int firstZone = 1;
4964 687 : int lastZone = state.dataGlobal->NumOfZones;
4965 :
4966 687 : if (present(ZoneToResimulate)) {
4967 0 : firstZone = ZoneToResimulate;
4968 0 : lastZone = ZoneToResimulate;
4969 : }
4970 :
4971 32289 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4972 63204 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4973 31602 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4974 : // Heat transfer surfaces
4975 31602 : int firstSurf = thisSpace.HTSurfaceFirst;
4976 31602 : int lastSurf = thisSpace.HTSurfaceLast;
4977 429375 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4978 397773 : auto const &surface = state.dataSurface->Surface(surfNum);
4979 397773 : int repSurfNum = surface.RepresentativeCalcSurfNum;
4980 :
4981 397773 : if (surfNum != repSurfNum) {
4982 : #if 0
4983 : // Check for divergence
4984 : Real64 surfConv = -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
4985 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
4986 : Real64 repSurfConv = -state.dataHeatBalSurf->SurfHConvInt(repSurfNum) *
4987 : (state.dataHeatBalSurf->SurfTempIn(repSurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum));
4988 : Real64 diff = surfConv - repSurfConv;
4989 : if (std::abs(diff) > 3.0 && state.dataSurface->Surface(repSurfNum).ConstituentSurfaceNums.size() == 2) {
4990 : ShowWarningError(state, format("Difference in representative surface convection {:.3R} W/m2", diff));
4991 : ShowContinueErrorTimeStamp(state, "");
4992 : ShowContinueError(state, format(" Original Surface: {}", surface.Name));
4993 : ShowContinueError(state, format(" Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(surfNum)));
4994 : ShowContinueError(state,
4995 : format(" Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(surfNum)));
4996 : ShowContinueError(state,
4997 : format(" Sunlit fraction: {:.3R}",
4998 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum)));
4999 : ShowContinueError(state, format(" Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum)));
5000 : ShowContinueError(state,
5001 : format(" Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(surfNum)));
5002 : ShowContinueError(state, format(" Representative Surface: {}", state.dataSurface->Surface(repSurfNum).Name));
5003 : ShowContinueError(state, format(" Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(repSurfNum)));
5004 : ShowContinueError(state,
5005 : format(" Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(repSurfNum)));
5006 : ShowContinueError(state,
5007 : format(" Sunlit fraction: {:.3R}",
5008 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, repSurfNum)));
5009 : ShowContinueError(state,
5010 : format(" Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum)));
5011 : ShowContinueError(
5012 : state, format(" Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(repSurfNum)));
5013 : }
5014 : #endif
5015 :
5016 : // Surface Heat Balance Arrays
5017 89997 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempIn(repSurfNum);
5018 89997 : state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(repSurfNum);
5019 89997 : state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBal->SurfTempEffBulkAir(repSurfNum);
5020 89997 : state.dataHeatBalSurf->SurfHConvInt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(repSurfNum);
5021 89997 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(repSurfNum);
5022 89997 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(repSurfNum);
5023 89997 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(repSurfNum);
5024 :
5025 89997 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(repSurfNum);
5026 89997 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvExt(repSurfNum);
5027 89997 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(repSurfNum);
5028 89997 : state.dataHeatBalSurf->SurfHAirExt(surfNum) = state.dataHeatBalSurf->SurfHAirExt(repSurfNum);
5029 89997 : state.dataHeatBalSurf->SurfHSkyExt(surfNum) = state.dataHeatBalSurf->SurfHSkyExt(repSurfNum);
5030 89997 : state.dataHeatBalSurf->SurfHGrdExt(surfNum) = state.dataHeatBalSurf->SurfHGrdExt(repSurfNum);
5031 :
5032 89997 : state.dataSurface->SurfTAirRef(surfNum) = state.dataSurface->SurfTAirRef(repSurfNum);
5033 89997 : if (state.dataSurface->SurfTAirRef(surfNum) != DataSurfaces::RefAirTemp::Invalid) {
5034 0 : state.dataSurface->SurfTAirRefRpt(surfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(surfNum)];
5035 : }
5036 :
5037 89997 : state.dataSurface->surfExtConv(surfNum).hfModelEq = state.dataSurface->surfExtConv(repSurfNum).hfModelEq;
5038 89997 : state.dataSurface->surfExtConv(surfNum).hnModelEq = state.dataSurface->surfExtConv(repSurfNum).hnModelEq;
5039 :
5040 89997 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
5041 89997 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(repSurfNum);
5042 89997 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) =
5043 89997 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(repSurfNum);
5044 :
5045 : // Internal (non reporting variables)
5046 89997 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(repSurfNum);
5047 89997 : state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum);
5048 : }
5049 : }
5050 :
5051 : // Opaque surfaces
5052 31602 : firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
5053 31602 : lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
5054 307089 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
5055 275487 : auto const &surface = state.dataSurface->Surface(surfNum);
5056 275487 : int repSurfNum = surface.RepresentativeCalcSurfNum;
5057 :
5058 275487 : if (surfNum != repSurfNum) {
5059 : // Surface Heat Balance Arrays
5060 11679 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(repSurfNum);
5061 11679 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum);
5062 11679 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(repSurfNum);
5063 : }
5064 : }
5065 :
5066 : // Window surfaces
5067 31602 : firstSurf = thisSpace.WindowSurfaceFirst;
5068 31602 : lastSurf = thisSpace.WindowSurfaceLast;
5069 153888 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
5070 122286 : auto const &surface = state.dataSurface->Surface(surfNum);
5071 122286 : int repSurfNum = surface.RepresentativeCalcSurfNum;
5072 :
5073 122286 : if (surfNum != repSurfNum) {
5074 78318 : Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
5075 :
5076 : // Glazing
5077 78318 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
5078 78318 : state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
5079 78318 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
5080 :
5081 : // Frame
5082 78318 : Real64 frameHeatGain = 0.0;
5083 78318 : if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
5084 0 : Real64 frameAreaRatio = state.dataSurface->SurfWinFrameArea(surfNum) / state.dataSurface->SurfWinFrameArea(repSurfNum);
5085 0 : state.dataSurface->SurfWinFrameHeatGain(surfNum) = state.dataSurface->SurfWinFrameHeatGain(repSurfNum) * frameAreaRatio;
5086 0 : state.dataSurface->SurfWinFrameHeatLoss(surfNum) = state.dataSurface->SurfWinFrameHeatLoss(repSurfNum) * frameAreaRatio;
5087 0 : state.dataSurface->SurfWinFrameTempIn(surfNum) = state.dataSurface->SurfWinFrameTempIn(repSurfNum);
5088 0 : state.dataSurface->SurfWinFrameTempSurfOut(surfNum) = state.dataSurface->SurfWinFrameTempSurfOut(repSurfNum);
5089 0 : frameHeatGain = state.dataSurface->SurfWinFrameHeatGain(surfNum) - state.dataSurface->SurfWinFrameHeatLoss(surfNum);
5090 : }
5091 :
5092 : // Divider
5093 78318 : Real64 dividerHeatGain = 0.0;
5094 78318 : if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
5095 0 : Real64 dividerAreaRatio = state.dataSurface->SurfWinDividerArea(surfNum) / state.dataSurface->SurfWinDividerArea(repSurfNum);
5096 0 : state.dataSurface->SurfWinDividerHeatGain(surfNum) = state.dataSurface->SurfWinDividerHeatGain(repSurfNum) * dividerAreaRatio;
5097 0 : state.dataSurface->SurfWinDividerHeatLoss(surfNum) = state.dataSurface->SurfWinDividerHeatLoss(repSurfNum) * dividerAreaRatio;
5098 0 : state.dataSurface->SurfWinDividerTempIn(surfNum) = state.dataSurface->SurfWinDividerTempIn(repSurfNum);
5099 0 : state.dataSurface->SurfWinDividerTempSurfOut(surfNum) = state.dataSurface->SurfWinDividerTempSurfOut(repSurfNum);
5100 0 : dividerHeatGain = state.dataSurface->SurfWinDividerHeatGain(surfNum) - state.dataSurface->SurfWinDividerHeatLoss(surfNum);
5101 : }
5102 :
5103 78318 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = frameHeatGain + dividerHeatGain;
5104 :
5105 : // Whole window
5106 156636 : state.dataSurface->SurfWinHeatGain(surfNum) = (state.dataSurface->SurfWinHeatGain(repSurfNum) -
5107 78318 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(repSurfNum) * areaRatio) +
5108 78318 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum);
5109 : }
5110 : }
5111 31602 : }
5112 : }
5113 687 : }
5114 :
5115 2828212 : void UpdateFinalSurfaceHeatBalance(EnergyPlusData &state)
5116 : {
5117 :
5118 : // SUBROUTINE INFORMATION:
5119 : // AUTHOR Rick Strand
5120 : // DATE WRITTEN December 2000
5121 :
5122 : // PURPOSE OF THIS SUBROUTINE:
5123 : // If a radiant system is present and was on for part of the time step,
5124 : // then we probably need to make yet another pass through the heat balance.
5125 : // This is necessary because the heat source/sink to the surface that is
5126 : // the radiant system may have varied during the system time steps.
5127 :
5128 : // METHODOLOGY EMPLOYED:
5129 : // First, determine whether or not the radiant system was running. If
5130 : // any of the Qsource terms are non-zero, then it was running. Then,
5131 : // update the current source terms with the "average" value calculated
5132 : // by the radiant system algorithm. This requires the "USE" of the
5133 : // radiant algorithm module. Finally, using this source value, redo
5134 : // the inside and outside heat balances.
5135 :
5136 : bool LowTempRadSysOn; // .TRUE. if a low temperature radiant system is running
5137 : bool HighTempRadSysOn; // .TRUE. if a high temperature radiant system is running
5138 : bool HWBaseboardSysOn; // .TRUE. if a water baseboard heater is running
5139 : bool SteamBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
5140 : bool ElecBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
5141 : bool CoolingPanelSysOn; // true if a simple cooling panel is running
5142 : bool SwimmingPoolOn; // true if a pool is present (running)
5143 :
5144 2828212 : LowTempRadiantSystem::UpdateRadSysSourceValAvg(state, LowTempRadSysOn);
5145 2828212 : HighTempRadiantSystem::UpdateHTRadSourceValAvg(state, HighTempRadSysOn);
5146 2828212 : HWBaseboardRadiator::UpdateBBRadSourceValAvg(state, HWBaseboardSysOn);
5147 2828212 : SteamBaseboardRadiator::UpdateBBSteamRadSourceValAvg(state, SteamBaseboardSysOn);
5148 2828212 : ElectricBaseboardRadiator::UpdateBBElecRadSourceValAvg(state, ElecBaseboardSysOn);
5149 2828212 : CoolingPanelSimple::UpdateCoolingPanelSourceValAvg(state, CoolingPanelSysOn);
5150 2828212 : SwimmingPool::UpdatePoolSourceValAvg(state, SwimmingPoolOn);
5151 :
5152 2828212 : if (LowTempRadSysOn || HighTempRadSysOn || HWBaseboardSysOn || SteamBaseboardSysOn || ElecBaseboardSysOn || CoolingPanelSysOn || SwimmingPoolOn) {
5153 : // Solve the zone heat balance 'Detailed' solution
5154 : // Call the outside and inside surface heat balances
5155 82564 : CalcHeatBalanceOutsideSurf(state);
5156 82564 : CalcHeatBalanceInsideSurf(state);
5157 : }
5158 2828212 : }
5159 :
5160 2652853 : void UpdateThermalHistories(EnergyPlusData &state)
5161 : {
5162 :
5163 : // SUBROUTINE INFORMATION:
5164 : // AUTHOR Russ Taylor
5165 : // DATE WRITTEN June 1990
5166 : // RE-ENGINEERED Mar98 (RKS)
5167 :
5168 : // PURPOSE OF THIS SUBROUTINE:
5169 : // This subroutine updates and shifts the thermal and flux histories.
5170 :
5171 : // METHODOLOGY EMPLOYED:
5172 : // If a surface runs on the user selected subhourly time step, then the
5173 : // history terms for the temperatures and fluxes must simply be updated
5174 : // and shifted. However, if the surface runs at a different (longer) time
5175 : // step, then the "master" history series is used for the interpolated
5176 : // update scheme.
5177 :
5178 : // REFERENCES:
5179 : // (I)BLAST legacy routine UTHRMH
5180 : // Taylor et.al., Impact of Simultaneous Simulation of Buildings and
5181 : // Mechanical Systems in Heat Balance Based Energy Analysis Programs
5182 : // on System Response and Control, Building Simulation '91, IBPSA, Nice, France.
5183 :
5184 2652853 : if (state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag) {
5185 788 : state.dataHeatBalSurfMgr->QExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5186 788 : state.dataHeatBalSurfMgr->QInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5187 788 : state.dataHeatBalSurfMgr->TempInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5188 788 : state.dataHeatBalSurfMgr->TempExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5189 788 : state.dataHeatBalSurfMgr->SumTime.dimension(state.dataSurface->TotSurfaces, 0.0);
5190 788 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5191 31 : state.dataHeatBalSurfMgr->Qsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
5192 31 : state.dataHeatBalSurfMgr->Tsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
5193 31 : state.dataHeatBalSurfMgr->Tuser1.dimension(state.dataSurface->TotSurfaces, 0.0);
5194 : }
5195 788 : state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag = false;
5196 : }
5197 :
5198 22904077 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5199 40551048 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5200 20299824 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5201 20299824 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5202 20299824 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5203 171976554 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5204 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5205 151676730 : auto const &surface = state.dataSurface->Surface(SurfNum);
5206 :
5207 151676730 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5208 288450 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5209 138432 : continue;
5210 : }
5211 :
5212 151538298 : int const ConstrNum = surface.Construction;
5213 151538298 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5214 :
5215 151538298 : if (construct.NumCTFTerms == 0) {
5216 0 : continue; // Skip surfaces with no history terms
5217 : }
5218 :
5219 : // Sign convention for the various terms in the following two equations
5220 : // is based on the form of the Conduction Transfer Function equation
5221 : // given by:
5222 : // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + (Sum of)(V Qsrc)
5223 : // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + (Sum of)(W Qsrc)
5224 : // In both equations, flux is positive from outside to inside. The V and W terms are for radiant systems only.
5225 :
5226 : // Set current inside flux:
5227 151538298 : Real64 const SurfOutsideTempCurr = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
5228 151538298 : Real64 SurfInsideFluxHistCurr = SurfOutsideTempCurr * construct.CTFCross[0] -
5229 151538298 : state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFInside[0] +
5230 151538298 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum); // Heat source/sink term for radiant systems
5231 : // Only HT opaq surfaces are evaluated, previous if (surface.Class == SurfaceClass::Floor || surface.Class == SurfaceClass::Wall ||
5232 : // surface.Class == SurfaceClass::IntMass || surface.Class == SurfaceClass::Roof || surface.Class == SurfaceClass::Door) checks are
5233 : // redundant.
5234 151538298 : if (construct.SourceSinkPresent) {
5235 397692 : SurfInsideFluxHistCurr += state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceIn[0];
5236 : }
5237 151538298 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr;
5238 151538298 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting
5239 151538298 : state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr;
5240 :
5241 : // Update the temperature at the source/sink location (if one is present)
5242 151538298 : if (construct.SourceSinkPresent) {
5243 397692 : state.dataHeatBalSurf->SurfTempSource(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1) =
5244 397692 : SurfOutsideTempCurr * construct.CTFTSourceOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTSourceIn[0] +
5245 397692 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTSourceQ[0] +
5246 397692 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
5247 397692 : state.dataHeatBalSurf->SurfTempUserLoc(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1) =
5248 397692 : SurfOutsideTempCurr * construct.CTFTUserOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTUserIn[0] +
5249 397692 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTUserSource[0] +
5250 397692 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum);
5251 : }
5252 :
5253 : // Set current outside flux:
5254 151538298 : if (construct.SourceSinkPresent) {
5255 397692 : state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) =
5256 397692 : SurfOutsideTempCurr * construct.CTFOutside[0] - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
5257 397692 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceOut[0] +
5258 397692 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); // Heat source/sink term for radiant systems
5259 : } else {
5260 302281212 : state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = SurfOutsideTempCurr * construct.CTFOutside[0] -
5261 151140606 : state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
5262 151140606 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum);
5263 : }
5264 : // switch sign for balance at outside face
5265 151538298 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = -state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
5266 151538298 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(SurfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum);
5267 : }
5268 20251224 : }
5269 : } // ...end of loop over all (heat transfer) surfaces...
5270 :
5271 2652853 : if (state.dataHeatBal->SimpleCTFOnly && !state.dataGlobal->AnyConstrOverridesInModel) {
5272 : // Temporarily save the rvalue references of the last term arrays
5273 2190081 : Array1D<Real64> insideTemp(std::move(state.dataHeatBalSurf->SurfInsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
5274 2190081 : Array1D<Real64> outsideTemp(std::move(state.dataHeatBalSurf->SurfOutsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
5275 2190081 : Array1D<Real64> insideFlux(std::move(state.dataHeatBalSurf->SurfInsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
5276 2190081 : Array1D<Real64> outsideFlux(std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
5277 : // Shifting its internal pointer to data to the new object; Using the (Array1D && a) overload of the "=" operator
5278 19581927 : for (int HistTermNum = state.dataHeatBal->MaxCTFTerms + 1; HistTermNum >= 3; --HistTermNum) {
5279 17391846 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum - 1));
5280 17391846 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum - 1));
5281 17391846 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum - 1));
5282 17391846 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum - 1));
5283 : }
5284 : // Reuse the pointers of the last term arrays for the second term arrays
5285 2190081 : state.dataHeatBalSurf->SurfInsideTempHist(2) = std::move(insideTemp);
5286 2190081 : state.dataHeatBalSurf->SurfOutsideTempHist(2) = std::move(outsideTemp);
5287 2190081 : state.dataHeatBalSurf->SurfInsideFluxHist(2) = std::move(insideFlux);
5288 2190081 : state.dataHeatBalSurf->SurfOutsideFluxHist(2) = std::move(outsideFlux);
5289 : // Hard copy the values of the the 1st term to the 2nd (copying data instead of pointers to protect the 1st term arrays used in run time)
5290 2190081 : state.dataHeatBalSurf->SurfInsideTempHist(2) = state.dataHeatBalSurf->SurfInsideTempHist(1);
5291 2190081 : state.dataHeatBalSurf->SurfOutsideTempHist(2) = state.dataHeatBalSurf->SurfOutsideTempHist(1);
5292 2190081 : state.dataHeatBalSurf->SurfInsideFluxHist(2) = state.dataHeatBalSurf->SurfInsideFluxHist(1);
5293 2190081 : state.dataHeatBalSurf->SurfOutsideFluxHist(2) = state.dataHeatBalSurf->SurfOutsideFluxHist(1);
5294 2190081 : return;
5295 2190081 : }
5296 :
5297 3581182 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5298 6253020 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5299 3134610 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5300 3134610 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5301 3134610 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5302 26009661 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5303 22875051 : auto const &surface = state.dataSurface->Surface(SurfNum);
5304 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5305 22875051 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5306 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5307 0 : continue;
5308 : }
5309 22875051 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5310 19144611 : state.dataHeatBalSurfMgr->TempExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
5311 19144611 : state.dataHeatBalSurfMgr->TempInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
5312 19144611 : state.dataHeatBalSurfMgr->QExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
5313 19144611 : state.dataHeatBalSurfMgr->QInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum);
5314 : }
5315 : }
5316 3118410 : }
5317 :
5318 : } // ...end of loop over all (heat transfer) surfaces...
5319 462772 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5320 431634 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5321 653526 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5322 326763 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5323 326763 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5324 326763 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5325 2540337 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5326 2213574 : auto const &surface = state.dataSurface->Surface(SurfNum);
5327 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5328 2213574 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5329 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5330 0 : continue;
5331 : }
5332 2213574 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5333 2201448 : state.dataHeatBalSurfMgr->Tsrc1(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1);
5334 2201448 : state.dataHeatBalSurfMgr->Tuser1(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1);
5335 2201448 : state.dataHeatBalSurfMgr->Qsrc1(SurfNum) = state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1);
5336 : }
5337 : }
5338 326763 : }
5339 : } // ...end of loop over all (heat transfer) surfaces...
5340 : }
5341 :
5342 : // SHIFT TEMPERATURE AND FLUX HISTORIES:
5343 : // SHIFT AIR TEMP AND FLUX SHIFT VALUES WHEN AT BOTTOM OF ARRAY SPACE.
5344 3581182 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5345 6253020 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5346 3134610 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5347 3134610 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5348 3134610 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5349 26009661 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5350 22875051 : auto const &surface = state.dataSurface->Surface(SurfNum);
5351 :
5352 22875051 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5353 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5354 0 : continue;
5355 : }
5356 :
5357 22875051 : int const ConstrNum = surface.Construction;
5358 22875051 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5359 :
5360 22875051 : ++state.dataHeatBalSurf->SurfCurrNumHist(SurfNum);
5361 22875051 : state.dataHeatBalSurfMgr->SumTime(SurfNum) = double(state.dataHeatBalSurf->SurfCurrNumHist(SurfNum)) * state.dataGlobal->TimeStepZone;
5362 :
5363 22875051 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == construct.NumHistories) {
5364 19142399 : state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
5365 :
5366 19142399 : if (construct.NumCTFTerms > 1) {
5367 18915644 : int const numCTFTerms(construct.NumCTFTerms);
5368 150295692 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
5369 131380048 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum) =
5370 131380048 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
5371 131380048 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum) =
5372 131380048 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
5373 131380048 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum) =
5374 131380048 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5375 131380048 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum) =
5376 131380048 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5377 131380048 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) =
5378 131380048 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
5379 131380048 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) =
5380 131380048 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
5381 131380048 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) =
5382 131380048 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5383 131380048 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) =
5384 131380048 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5385 : }
5386 : }
5387 :
5388 19142399 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempExt1(SurfNum);
5389 19142399 : state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempInt1(SurfNum);
5390 19142399 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QExt1(SurfNum);
5391 19142399 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QInt1(SurfNum);
5392 :
5393 19142399 : state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum);
5394 19142399 : state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum);
5395 19142399 : state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum);
5396 19142399 : state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum);
5397 : } else {
5398 3732652 : Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
5399 3732652 : if (construct.NumCTFTerms > 1) {
5400 3732652 : int const numCTFTerms(construct.NumCTFTerms);
5401 53391610 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
5402 : // TH(SideNum, TermNum, SurfNum) = (THM(SideNum, TermNum, SurfNum) -
5403 : // (THM(SideNum, TermNum, SurfNum) - THM(SideNum, TermNum - 1, SurfNum)) * sum_steps;
5404 49658958 : Real64 const THM_Out_1(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum));
5405 49658958 : Real64 const THM_In_1(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum));
5406 49658958 : Real64 const THM_Out_2(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum));
5407 49658958 : Real64 const THM_In_2(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum));
5408 49658958 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = THM_Out_1 - (THM_Out_1 - THM_Out_2) * sum_steps;
5409 49658958 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = THM_In_1 - (THM_In_1 - THM_In_2) * sum_steps;
5410 :
5411 49658958 : Real64 const QHM_Out_1(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum));
5412 49658958 : Real64 const QHM_In_1(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum));
5413 49658958 : Real64 const QHM_Out_2(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum));
5414 49658958 : Real64 const QHM_In_2(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum));
5415 49658958 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = QHM_Out_1 - (QHM_Out_1 - QHM_Out_2) * sum_steps;
5416 49658958 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = QHM_In_1 - (QHM_In_1 - QHM_In_2) * sum_steps;
5417 : }
5418 : }
5419 : // TH( 1, 2, SurfNum ) = THM( 1, 2, SurfNum ) - ( THM( 1, 2, SurfNum ) - TempExt1( SurfNum ) ) * sum_steps;
5420 3732652 : state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) =
5421 3732652 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) -
5422 3732652 : (state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempExt1(SurfNum)) * sum_steps;
5423 3732652 : state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) =
5424 3732652 : state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) -
5425 3732652 : (state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempInt1(SurfNum)) * sum_steps;
5426 3732652 : state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) =
5427 3732652 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) -
5428 3732652 : (state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QExt1(SurfNum)) * sum_steps;
5429 3732652 : state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) =
5430 3732652 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) -
5431 3732652 : (state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QInt1(SurfNum)) * sum_steps;
5432 : }
5433 : }
5434 3118410 : }
5435 : } // ...end of loop over all (heat transfer) surfaces
5436 :
5437 462772 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5438 431634 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5439 653526 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5440 326763 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5441 326763 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5442 326763 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5443 2540337 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5444 2213574 : auto const &surface = state.dataSurface->Surface(SurfNum);
5445 2213574 : int const ConstrNum = surface.Construction;
5446 2213574 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5447 2213574 : if (!construct.SourceSinkPresent) {
5448 1815882 : continue;
5449 : }
5450 397692 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5451 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5452 0 : continue;
5453 : }
5454 :
5455 397692 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5456 385536 : if (construct.NumCTFTerms > 1) {
5457 385536 : int const numCTFTerms = construct.NumCTFTerms;
5458 385536 : int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
5459 385536 : int m1 = m + 1;
5460 3820314 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing
5461 : // SurfTsrcHist( SurfNum, HistTerm ) = SurfTsrcHistM( SurfNum, HHistTerm ) = SurfTsrcHistM( SurfNum, HistTermNum - 1
5462 : // ); SurfQsrcHist( SurfNum, HistTerm ) = SurfQsrcHistM( SurfNum, HHistTerm ) = SurfQsrcHistM( SurfNum, HistTermNum -
5463 : // 1 );
5464 3434778 : state.dataHeatBalSurf->SurfTsrcHist[m1] = state.dataHeatBalSurf->SurfTsrcHistM[m1] =
5465 3434778 : state.dataHeatBalSurf->SurfTsrcHistM[m];
5466 3434778 : state.dataHeatBalSurf->SurfQsrcHist[m1] = state.dataHeatBalSurf->SurfQsrcHistM[m1] =
5467 3434778 : state.dataHeatBalSurf->SurfQsrcHistM[m];
5468 3434778 : state.dataHeatBalSurf->SurfTuserHist[m1] = state.dataHeatBalSurf->SurfTuserHistM[m1] =
5469 3434778 : state.dataHeatBalSurf->SurfTuserHistM[m];
5470 : }
5471 : }
5472 385536 : state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tsrc1(SurfNum);
5473 385536 : state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tuser1(SurfNum);
5474 385536 : state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Qsrc1(SurfNum);
5475 385536 : state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2);
5476 385536 : state.dataHeatBalSurf->SurfTuserHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2);
5477 385536 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2);
5478 : } else {
5479 12156 : Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
5480 :
5481 12156 : if (construct.NumCTFTerms > 1) {
5482 12156 : int const numCTFTerms = construct.NumCTFTerms;
5483 12156 : int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
5484 12156 : int m1 = m + 1;
5485 158028 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing [ l ] == ()
5486 : // Real64 const SurfTsrcHistM_elem( SurfTsrcHistM( SurfNum, HistTermNum ) );
5487 : // SurfTsrcHist( SurfNum, HistTermNum ) = SurfTsrcHistM_elem - ( SurfTsrcHistM_elem - SurfTsrcHistM( SurfNum,
5488 : // HistTermNum
5489 : // - 1 ) ) * sum_steps; Real64 const QsrcHistM_elem( SurfQsrcHistM( SurfNum, HistTermNum ) ); SurfQsrcHist( SurfNum,
5490 : // HistTermNum ) = QsrcHistM_elem - ( QsrcHistM_elem - SurfQsrcHistM( SurfNum, HistTermNum - 1 ) ) * sum_steps;
5491 145872 : Real64 const TsrcHistM_m1(state.dataHeatBalSurf->SurfTsrcHistM[m1]);
5492 145872 : state.dataHeatBalSurf->SurfTsrcHist[m1] =
5493 145872 : TsrcHistM_m1 - (TsrcHistM_m1 - state.dataHeatBalSurf->SurfTsrcHistM[m]) * sum_steps;
5494 145872 : Real64 const QsrcHistM_m1(state.dataHeatBalSurf->SurfQsrcHistM[m1]);
5495 145872 : state.dataHeatBalSurf->SurfQsrcHist[m1] =
5496 145872 : QsrcHistM_m1 - (QsrcHistM_m1 - state.dataHeatBalSurf->SurfQsrcHistM[m]) * sum_steps;
5497 145872 : Real64 const TuserHistM_m1(state.dataHeatBalSurf->SurfTuserHistM[m1]);
5498 145872 : state.dataHeatBalSurf->SurfTuserHist[m1] =
5499 145872 : TuserHistM_m1 - (TuserHistM_m1 - state.dataHeatBalSurf->SurfTuserHistM[m]) * sum_steps;
5500 : }
5501 : }
5502 : // Tuned Linear indexing
5503 : // SurfTsrcHist( SurfNum, 2 ) = SurfTsrcHistM( SurfNum, 2 ) - ( SurfTsrcHistM( SurfNum, 2 ) - Tsrc1( SurfNum ) ) * sum_steps;
5504 : // SurfQsrcHist( SurfNum, 2 ) = SurfQsrcHistM( SurfNum, 2 ) - ( SurfQsrcHistM( SurfNum, 2 ) - Qsrc1( SurfNum ) ) * sum_steps;
5505 12156 : int const l2 = state.dataHeatBalSurf->SurfTsrcHist.index(SurfNum, 2);
5506 12156 : state.dataHeatBalSurf->SurfTsrcHist[l2] =
5507 12156 : state.dataHeatBalSurf->SurfTsrcHistM[l2] -
5508 12156 : (state.dataHeatBalSurf->SurfTsrcHistM[l2] - state.dataHeatBalSurfMgr->Tsrc1(SurfNum)) * sum_steps;
5509 12156 : state.dataHeatBalSurf->SurfQsrcHist[l2] =
5510 12156 : state.dataHeatBalSurf->SurfQsrcHistM[l2] -
5511 12156 : (state.dataHeatBalSurf->SurfQsrcHistM[l2] - state.dataHeatBalSurfMgr->Qsrc1(SurfNum)) * sum_steps;
5512 12156 : state.dataHeatBalSurf->SurfTuserHist[l2] =
5513 12156 : state.dataHeatBalSurf->SurfTuserHistM[l2] -
5514 12156 : (state.dataHeatBalSurf->SurfTuserHistM[l2] - state.dataHeatBalSurfMgr->Tuser1(SurfNum)) * sum_steps;
5515 : }
5516 : }
5517 326763 : }
5518 : } // ...end of loop over all (heat transfer) surfaces...
5519 : } // ...end of AnyInternalHeatSourceInInput
5520 : }
5521 :
5522 3760544 : void CalculateZoneMRT(EnergyPlusData &state,
5523 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
5524 : {
5525 :
5526 : // SUBROUTINE INFORMATION:
5527 : // AUTHOR Rick Strand
5528 : // DATE WRITTEN November 2000
5529 :
5530 : // PURPOSE OF THIS SUBROUTINE:
5531 : // Calculates the current zone and enclosure MRT for thermal comfort and radiation
5532 : // calculation purposes.
5533 :
5534 3760544 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5535 801 : state.dataHeatBalSurfMgr->SurfaceAE.allocate(state.dataSurface->TotSurfaces);
5536 801 : state.dataHeatBalSurfMgr->ZoneAESum.allocate(state.dataGlobal->NumOfZones);
5537 801 : state.dataHeatBalSurfMgr->SurfaceAE = 0.0;
5538 801 : state.dataHeatBalSurfMgr->ZoneAESum = 0.0;
5539 6001 : for (auto &encl : state.dataViewFactor->EnclRadInfo) {
5540 5200 : encl.sumAE = 0.0;
5541 801 : }
5542 48091 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
5543 47290 : auto const &surface = state.dataSurface->Surface(SurfNum);
5544 47290 : if (surface.HeatTransSurf) {
5545 45583 : auto &thisSurfAE = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum);
5546 45583 : thisSurfAE = surface.Area * state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal;
5547 45583 : int ZoneNum = surface.Zone;
5548 45583 : if (ZoneNum > 0) {
5549 45582 : state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) += thisSurfAE;
5550 : }
5551 45583 : if (surface.RadEnclIndex > 0) {
5552 45582 : state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).sumAE += thisSurfAE;
5553 : }
5554 : }
5555 : }
5556 : }
5557 :
5558 : // Zero sumAET for applicable enclosures
5559 3760544 : if (present(ZoneToResimulate)) {
5560 1592198 : for (int spaceNum : state.dataHeatBal->Zone(ZoneToResimulate).spaceIndexes) {
5561 796099 : int enclNum = state.dataHeatBal->space(spaceNum).radiantEnclosureNum;
5562 796099 : state.dataViewFactor->EnclRadInfo(enclNum).sumAET = 0.0;
5563 796099 : state.dataViewFactor->EnclRadInfo(enclNum).reCalcMRT = true;
5564 796099 : }
5565 : } else {
5566 24099000 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
5567 21134555 : thisEnclosure.reCalcMRT = true;
5568 2964445 : }
5569 : }
5570 27671484 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5571 23910940 : if (present(ZoneToResimulate) && (ZoneNum != ZoneToResimulate)) {
5572 1976242 : continue;
5573 : }
5574 21934698 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
5575 21934698 : if (state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) > 0.01) {
5576 21932673 : Real64 zoneSumAET = 0.0;
5577 43913946 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
5578 21981273 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5579 209686682 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
5580 187705409 : Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) * state.dataHeatBalSurf->SurfTempIn(SurfNum);
5581 187705409 : zoneSumAET += surfAET;
5582 187705409 : state.dataViewFactor->EnclRadInfo(state.dataSurface->Surface(SurfNum).RadEnclIndex).sumAET += surfAET;
5583 : }
5584 21932673 : }
5585 21932673 : thisZoneHB.MRT = zoneSumAET / state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum);
5586 : } else {
5587 2025 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5588 2 : ShowWarningError(
5589 : state,
5590 2 : format("Zone areas*inside surface emissivities are summing to zero, for Zone=\"{}\"", state.dataHeatBal->Zone(ZoneNum).Name));
5591 3 : ShowContinueError(state, "As a result, MRT will be set to MAT for that zone");
5592 : }
5593 2025 : thisZoneHB.MRT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
5594 : }
5595 : }
5596 : // Calculate MRT for applicable enclosures
5597 27667440 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
5598 23906896 : if (!thisEnclosure.reCalcMRT) {
5599 0 : continue;
5600 : }
5601 23906896 : if (thisEnclosure.sumAE > 0.01) {
5602 23904871 : thisEnclosure.sumAET = 0.0;
5603 225977262 : for (int surfNum : thisEnclosure.SurfacePtr) {
5604 202072391 : Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum);
5605 202072391 : thisEnclosure.sumAET += surfAET;
5606 : }
5607 23904871 : thisEnclosure.MRT = thisEnclosure.sumAET / thisEnclosure.sumAE;
5608 : } else {
5609 2025 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5610 2 : ShowWarningError(state,
5611 2 : format("Enclosure areas*inside surface emissivities are summing to zero, for Enclosure=\"{}\"", thisEnclosure.Name));
5612 3 : ShowContinueError(state, "As a result, MRT will be set to the volume weighted average MAT for that enclosure");
5613 : }
5614 2025 : Real64 sumMATVol = 0.0;
5615 2025 : Real64 sumVol = 0.0;
5616 2025 : Real64 sumMAT = 0.0;
5617 4050 : for (auto &spaceNum : thisEnclosure.spaceNums) {
5618 2025 : Real64 spaceVolume = state.dataHeatBal->space(spaceNum).Volume;
5619 2025 : Real64 spaceMAT = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT;
5620 2025 : sumVol += spaceVolume;
5621 2025 : sumMATVol += spaceMAT * spaceVolume;
5622 2025 : sumMAT += spaceMAT;
5623 2025 : }
5624 2025 : if (sumVol > 0.01) {
5625 2025 : thisEnclosure.MRT = sumMATVol / sumVol;
5626 : } else {
5627 0 : thisEnclosure.MRT = sumMAT / (int)thisEnclosure.spaceNums.size();
5628 : }
5629 : }
5630 : // Set space MRTs
5631 47866436 : for (int spaceNum : thisEnclosure.spaceNums) {
5632 23959540 : state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MRT = thisEnclosure.MRT;
5633 23906896 : }
5634 3760544 : }
5635 :
5636 3760544 : state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime = false;
5637 3760544 : }
5638 :
5639 : // End of Record Keeping subroutines for the HB Module
5640 : // *****************************************************************************
5641 :
5642 : // Beginning of Reporting subroutines for the HB Module
5643 : // *****************************************************************************
5644 :
5645 2828212 : void CalcThermalResilience(EnergyPlusData &state)
5646 : {
5647 : // This function calculate timestep-wise heat index and humidex.
5648 :
5649 : // The computation of the heat index is a refinement of a result obtained by multiple regression analysis
5650 : // carried out by Lans P. Rothfusz and described in a 1990 National Weather Service (NWS)
5651 : // Technical Attachment (SR 90-23).
5652 : // Reference: https://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
5653 :
5654 : // The current formula for determining the humidex was developed by J. M. Masterton and F. A. Richardson of
5655 : // Canada's Atmospheric Environment Service in 1979.
5656 : // Reference: Masterson, J., and F. Richardson, 1979: Humidex, a method of quantifying human
5657 : // discomfort due to excessive heat and humidity CLI 1-79, Environment Canada, Atmospheric Environment Service
5658 : // using OutputProcessor::ReqRepVars;
5659 2828212 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
5660 6002 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5661 10402 : SetupOutputVariable(state,
5662 : "Zone Heat Index",
5663 : Constant::Units::C,
5664 5201 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex,
5665 : OutputProcessor::TimeStepType::Zone,
5666 : OutputProcessor::StoreType::Average,
5667 5201 : state.dataHeatBal->Zone(ZoneNum).Name);
5668 10402 : SetupOutputVariable(state,
5669 : "Zone Humidity Index",
5670 : Constant::Units::None,
5671 5201 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex,
5672 : OutputProcessor::TimeStepType::Zone,
5673 : OutputProcessor::StoreType::Average,
5674 5201 : state.dataHeatBal->Zone(ZoneNum).Name);
5675 : }
5676 22594 : for (auto const *reqVar : state.dataOutputProcessor->reqVars) {
5677 21793 : if (reqVar->name == "Zone Heat Index") {
5678 0 : state.dataHeatBalSurfMgr->reportVarHeatIndex = true;
5679 21793 : } else if (reqVar->name == "Zone Humidity Index") {
5680 0 : state.dataHeatBalSurfMgr->reportVarHumidex = true;
5681 : }
5682 801 : }
5683 : }
5684 :
5685 : // Calculate Heat Index and Humidex.
5686 : // The heat index equation set is fit to Fahrenheit units, so the zone air temperature values are first convert to F,
5687 : // then heat index is calculated and converted back to C.
5688 2828212 : if (state.dataHeatBalSurfMgr->reportVarHeatIndex || state.dataOutRptTab->displayThermalResilienceSummary) {
5689 6578118 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5690 5484603 : Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5691 5484603 : Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
5692 5484603 : Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress) * 100.0;
5693 5484603 : Real64 const ZoneTF = ZoneT * (9.0 / 5.0) + 32.0;
5694 5484603 : if (state.dataHeatBal->heatIndexMethod == DataHeatBalance::HeatIndexMethod::Simplified) {
5695 5484603 : Real64 constexpr c1 = -42.379;
5696 5484603 : Real64 constexpr c2 = 2.04901523;
5697 5484603 : Real64 constexpr c3 = 10.14333127;
5698 5484603 : Real64 constexpr c4 = -.22475541;
5699 5484603 : Real64 constexpr c5 = -.00683783;
5700 5484603 : Real64 constexpr c6 = -.05481717;
5701 5484603 : Real64 constexpr c7 = .00122874;
5702 5484603 : Real64 constexpr c8 = .00085282;
5703 5484603 : Real64 constexpr c9 = -.00000199;
5704 : Real64 HI;
5705 :
5706 5484603 : if (ZoneTF < 80) {
5707 4748952 : HI = 0.5 * (ZoneTF + 61.0 + (ZoneTF - 68.0) * 1.2 + (ZoneRH * 0.094));
5708 : } else {
5709 735651 : HI = c1 + c2 * ZoneTF + c3 * ZoneRH + c4 * ZoneTF * ZoneRH + c5 * ZoneTF * ZoneTF + c6 * ZoneRH * ZoneRH +
5710 735651 : c7 * ZoneTF * ZoneTF * ZoneRH + c8 * ZoneTF * ZoneRH * ZoneRH + c9 * ZoneTF * ZoneTF * ZoneRH * ZoneRH;
5711 735651 : if (ZoneRH < 13 && ZoneTF < 112) {
5712 34760 : HI -= (13 - ZoneRH) / 4 * std::sqrt((17 - abs(ZoneTF - 95)) / 17);
5713 700891 : } else if (ZoneRH > 85 && ZoneTF < 87) {
5714 15017 : HI += (ZoneRH - 85) / 10 * (87 - ZoneTF) / 5;
5715 : }
5716 : }
5717 5484603 : HI = (HI - 32.0) * (5.0 / 9.0);
5718 5484603 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex = HI;
5719 : } else {
5720 : // calculate extended heat index
5721 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex =
5722 0 : ExtendedHI::heatindex(state, ZoneT + Constant::Kelvin, ZoneRH / 100.0) - Constant::Kelvin;
5723 : }
5724 : }
5725 : }
5726 2828212 : if (state.dataHeatBalSurfMgr->reportVarHumidex || state.dataOutRptTab->displayThermalResilienceSummary) {
5727 6578118 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5728 5484603 : Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
5729 5484603 : Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5730 5484603 : Real64 const TDewPointK = Psychrometrics::PsyTdpFnWPb(state, ZoneW, state.dataEnvrn->OutBaroPress) + Constant::Kelvin;
5731 5484603 : Real64 const e = 6.11 * std::exp(5417.7530 * ((1 / 273.16) - (1 / TDewPointK)));
5732 5484603 : Real64 const h = 5.0 / 9.0 * (e - 10.0);
5733 5484603 : Real64 const Humidex = ZoneT + h;
5734 5484603 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex = Humidex;
5735 : }
5736 : }
5737 2828212 : }
5738 :
5739 1093515 : void ReportThermalResilience(EnergyPlusData &state)
5740 : {
5741 :
5742 1093515 : Array1D_bool reportPeriodFlags;
5743 1093515 : if (state.dataWeather->TotReportPers > 0) {
5744 5376 : reportPeriodFlags.dimension(state.dataWeather->TotThermalReportPers, false);
5745 5376 : General::findReportPeriodIdx(state, state.dataWeather->ThermalReportPeriodInput, state.dataWeather->TotThermalReportPers, reportPeriodFlags);
5746 : }
5747 :
5748 1093515 : auto &ort = state.dataOutRptTab;
5749 1100427 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5750 6912 : if (reportPeriodFlags(i)) {
5751 0 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
5752 0 : state.dataWeather->ThermalReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
5753 : }
5754 : }
5755 :
5756 1093515 : if (state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime) {
5757 680 : int constexpr HINoBins = 5; // Heat Index range - number of bins
5758 680 : int constexpr HumidexNoBins = 5; // Humidex range - number of bins
5759 680 : int constexpr SETNoBins = 5; // SET report column numbers
5760 680 : int constexpr ColdHourOfSafetyNoBins = 5; // Cold Stress Hour of Safety number of columns
5761 680 : int constexpr HeatHourOfSafetyNoBins = 5; // Heat Stress Hour of Safety number of columns
5762 680 : int constexpr UnmetDegreeHourNoBins = 6; // Unmet Degree Hour number of columns
5763 680 : int constexpr DiscomfortWtExceedHourNoBins = 4; // Unmet Degree Hour number of columns
5764 :
5765 680 : if (state.dataHeatBal->TotPeople == 0) {
5766 103 : state.dataHeatBalSurfMgr->hasPierceSET = false;
5767 : }
5768 3700 : for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
5769 3020 : if (!state.dataHeatBal->People(iPeople).Pierce) {
5770 3009 : state.dataHeatBalSurfMgr->hasPierceSET = false;
5771 : }
5772 : }
5773 4365 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5774 : // the whole period
5775 : // user specified reporting period
5776 3690 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5777 5 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5778 5 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5779 5 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5780 5 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5781 5 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5782 5 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5783 5 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
5784 5 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
5785 5 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
5786 : }
5787 5 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(ColdHourOfSafetyNoBins, 0.0);
5788 5 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(HeatHourOfSafetyNoBins, 0.0);
5789 5 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, i).assign(UnmetDegreeHourNoBins, 0.0);
5790 5 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
5791 5 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
5792 : }
5793 3685 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod = 0.0;
5794 3685 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod = 0.0;
5795 3685 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod = 0.0;
5796 3685 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod = 0.0;
5797 : }
5798 680 : state.dataHeatBalSurfMgr->lowSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
5799 680 : state.dataHeatBalSurfMgr->highSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
5800 680 : state.dataHeatBalSurfMgr->lowSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
5801 680 : state.dataHeatBalSurfMgr->highSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
5802 680 : state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime = false;
5803 : }
5804 :
5805 : // Count hours only during weather simulation periods
5806 1093515 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
5807 : // use default value if there are no user inputs
5808 219096 : Real64 ColdTempThresh = 15.56;
5809 219096 : Real64 HeatTempThresh = 30.0;
5810 : // Trace current time step Zone Pierce SET; NaN if no occupant or SET not calculated
5811 : // Record last time step SET to trace SET unmet duration;
5812 :
5813 219096 : Real64 valueNotInit = -999.0;
5814 219096 : Real64 nearThreshold = 1.0;
5815 1192032 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5816 972936 : state.dataHeatBal->Resilience(ZoneNum).PierceSET = valueNotInit;
5817 972936 : state.dataHeatBal->Resilience(ZoneNum).PMV = valueNotInit;
5818 : }
5819 1069296 : for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
5820 850200 : int ZoneNum = state.dataHeatBal->People(iPeople).ZonePtr;
5821 850200 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc =
5822 850200 : state.dataHeatBal->People(iPeople).NumberOfPeople * state.dataHeatBal->People(iPeople).sched->getCurrentVal();
5823 850200 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
5824 850200 : if (state.dataHeatBal->People(iPeople).Pierce) {
5825 0 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = state.dataThermalComforts->ThermalComfortData(iPeople).PierceSET;
5826 : } else {
5827 850200 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = -1;
5828 : }
5829 :
5830 850200 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
5831 850200 : Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5832 850200 : ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
5833 850200 : bool &CrossedColdThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedColdThresh;
5834 850200 : if (Temperature > ColdTempThresh) { // safe
5835 781208 : if (!CrossedColdThresh) {
5836 : // compute the number of hours before threshold is reached
5837 396296 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
5838 : }
5839 : } else { // danger
5840 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5841 68992 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
5842 68992 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
5843 68992 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5844 : // first time crossing threshold
5845 68992 : if (!CrossedColdThresh) {
5846 : // compute the time when the zone crosses the threshold temperature
5847 : int encodedMonDayHrMin;
5848 10 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5849 10 : state.dataEnvrn->Month,
5850 10 : state.dataEnvrn->DayOfMonth,
5851 10 : state.dataGlobal->HourOfDay,
5852 10 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5853 : // fixme: not sure how to aggregate by zone
5854 10 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[1] = encodedMonDayHrMin;
5855 10 : CrossedColdThresh = true;
5856 : }
5857 : }
5858 850200 : HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
5859 850200 : bool &CrossedHeatThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedHeatThresh;
5860 850200 : if (Temperature < HeatTempThresh) { // safe
5861 845039 : if (!CrossedHeatThresh) {
5862 : // compute the number of hours before threshold is reached
5863 460217 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
5864 : }
5865 : } else { // danger
5866 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5867 5161 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
5868 5161 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
5869 5161 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5870 : // first time crossing threshold
5871 5161 : if (!CrossedHeatThresh) {
5872 : // compute the time when the zone crosses the threshold temperature
5873 : int encodedMonDayHrMin;
5874 13 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5875 13 : state.dataEnvrn->Month,
5876 13 : state.dataEnvrn->DayOfMonth,
5877 13 : state.dataGlobal->HourOfDay,
5878 13 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5879 13 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[1] = encodedMonDayHrMin;
5880 13 : CrossedHeatThresh = true;
5881 : }
5882 : }
5883 :
5884 850200 : Real64 VeryHotPMVThresh = 3.0;
5885 850200 : Real64 WarmPMVThresh = 0.7;
5886 850200 : Real64 CoolPMVThresh = -0.7;
5887 850200 : Real64 VeryColdPMVThresh = -3.0;
5888 850200 : Real64 PMV = state.dataThermalComforts->ThermalComfortData(iPeople).FangerPMV;
5889 850200 : if (PMV < VeryColdPMVThresh) {
5890 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[0] +=
5891 0 : (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5892 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[0] +=
5893 0 : (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5894 : }
5895 850200 : if (PMV < CoolPMVThresh) {
5896 91082 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[1] +=
5897 91082 : (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5898 91082 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[1] +=
5899 91082 : (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5900 : }
5901 850200 : if (PMV > WarmPMVThresh) {
5902 94796 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[2] +=
5903 94796 : (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
5904 94796 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[2] +=
5905 94796 : (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5906 : }
5907 850200 : if (PMV > VeryHotPMVThresh) {
5908 402 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[3] +=
5909 402 : (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
5910 402 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[3] +=
5911 402 : (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5912 : }
5913 :
5914 : // check whether PierceSET changed for people in a zone
5915 850200 : if (state.dataHeatBal->Resilience(ZoneNum).PierceSET < valueNotInit + nearThreshold) {
5916 850200 : state.dataHeatBal->Resilience(ZoneNum).PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
5917 : } else {
5918 0 : if (state.dataHeatBal->Resilience(ZoneNum).PierceSET != state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET) {
5919 0 : ShowRecurringWarningErrorAtEnd(state,
5920 0 : fmt::format("Zone {} has multiple people objects with different PierceSet.", ZoneNum),
5921 0 : state.dataHeatBalFanSys->PierceSETerrorIndex);
5922 : }
5923 : }
5924 :
5925 : // check whether PierceSET, PMV, etc. changed for different people in a zone
5926 850200 : if (state.dataHeatBal->Resilience(ZoneNum).PMV < valueNotInit + nearThreshold) {
5927 850200 : state.dataHeatBal->Resilience(ZoneNum).PMV = PMV;
5928 : } else {
5929 0 : if (state.dataHeatBal->Resilience(ZoneNum).PMV != PMV) {
5930 0 : ShowRecurringWarningErrorAtEnd(state,
5931 0 : fmt::format("Zone {} has multiple people objects with different PMV.", ZoneNum),
5932 0 : state.dataHeatBalFanSys->PMVerrorIndex);
5933 : }
5934 : }
5935 :
5936 850200 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5937 0 : if (reportPeriodFlags(i)) {
5938 0 : int ReportPeriodIdx = i;
5939 0 : ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
5940 0 : bool &CrossedColdThreshRepPeriod = state.dataHeatBalFanSys->CrossedColdThreshRepPeriod(ZoneNum, ReportPeriodIdx);
5941 0 : if (Temperature > ColdTempThresh) { // safe
5942 0 : if (!CrossedColdThreshRepPeriod) {
5943 : // compute the number of hours before threshold is reached
5944 0 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
5945 : }
5946 : } else { // danger
5947 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5948 0 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
5949 0 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
5950 0 : NumOcc * state.dataGlobal->TimeStepZone;
5951 0 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
5952 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5953 : // first time crossing threshold
5954 0 : if (!CrossedColdThreshRepPeriod) {
5955 : // compute the time when the zone crosses the threshold temperature
5956 : int encodedMonDayHrMin;
5957 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5958 0 : state.dataEnvrn->Month,
5959 0 : state.dataEnvrn->DayOfMonth,
5960 0 : state.dataGlobal->HourOfDay,
5961 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5962 : // fixme: not sure how to aggregate by zone
5963 0 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
5964 0 : CrossedColdThreshRepPeriod = true;
5965 : }
5966 : }
5967 0 : HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
5968 0 : bool &CrossedHeatThreshRepPeriod = state.dataHeatBalFanSys->CrossedHeatThreshRepPeriod(ZoneNum, ReportPeriodIdx);
5969 0 : if (Temperature < HeatTempThresh) { // safe
5970 0 : if (!CrossedHeatThreshRepPeriod) {
5971 : // compute the number of hours before threshold is reached
5972 0 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
5973 : }
5974 : } else { // danger
5975 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5976 0 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
5977 0 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
5978 0 : NumOcc * state.dataGlobal->TimeStepZone;
5979 0 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
5980 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5981 : // first time crossing threshold
5982 0 : if (!CrossedHeatThreshRepPeriod) {
5983 : // compute the time when the zone crosses the threshold temperature
5984 : int encodedMonDayHrMin;
5985 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5986 0 : state.dataEnvrn->Month,
5987 0 : state.dataEnvrn->DayOfMonth,
5988 0 : state.dataGlobal->HourOfDay,
5989 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5990 0 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
5991 0 : CrossedHeatThreshRepPeriod = true;
5992 : }
5993 : }
5994 :
5995 0 : if (PMV < VeryColdPMVThresh) {
5996 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
5997 0 : (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5998 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
5999 0 : (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6000 : }
6001 0 : if (PMV < CoolPMVThresh) {
6002 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6003 0 : (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
6004 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6005 0 : (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6006 : }
6007 0 : if (PMV > WarmPMVThresh) {
6008 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6009 0 : (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
6010 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6011 0 : (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6012 : }
6013 0 : if (PMV > VeryHotPMVThresh) {
6014 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6015 0 : (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
6016 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6017 0 : (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6018 : }
6019 : }
6020 : }
6021 : }
6022 1192032 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6023 972936 : Real64 HI = state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex;
6024 972936 : Real64 Humidex = state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex;
6025 :
6026 972936 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6027 972936 : if (HI <= 26.7) {
6028 921157 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[0] += state.dataGlobal->TimeStepZone;
6029 921157 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6030 921157 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6031 51779 : } else if (HI > 26.7 && HI <= 32.2) {
6032 41483 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[1] += state.dataGlobal->TimeStepZone;
6033 41483 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6034 41483 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6035 10296 : } else if (HI > 32.2 && HI <= 39.4) {
6036 4776 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[2] += state.dataGlobal->TimeStepZone;
6037 4776 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6038 4776 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6039 5520 : } else if (HI > 39.4 && HI <= 51.7) {
6040 3610 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[3] += state.dataGlobal->TimeStepZone;
6041 3610 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
6042 3610 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6043 : } else {
6044 1910 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[4] += state.dataGlobal->TimeStepZone;
6045 1910 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
6046 1910 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6047 : }
6048 :
6049 972936 : if (Humidex <= 29) {
6050 884184 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[0] += state.dataGlobal->TimeStepZone;
6051 884184 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6052 884184 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6053 88752 : } else if (Humidex > 29 && Humidex <= 40) {
6054 78160 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[1] += state.dataGlobal->TimeStepZone;
6055 78160 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6056 78160 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6057 10592 : } else if (Humidex > 40 && Humidex <= 45) {
6058 4801 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[2] += state.dataGlobal->TimeStepZone;
6059 4801 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6060 4801 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6061 5791 : } else if (Humidex > 45 && Humidex <= 50) {
6062 3093 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[3] += state.dataGlobal->TimeStepZone;
6063 3093 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
6064 3093 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6065 : } else {
6066 2698 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[4] += state.dataGlobal->TimeStepZone;
6067 2698 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
6068 2698 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6069 : }
6070 :
6071 972936 : Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
6072 972936 : auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
6073 972936 : Real64 CoolingSetpoint = zoneTstatSetpt.setptHi;
6074 972936 : Real64 HeatingSetpoint = zoneTstatSetpt.setptLo;
6075 :
6076 972936 : if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
6077 42672 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[0] += (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6078 42672 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[1] +=
6079 42672 : NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6080 42672 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[2] +=
6081 42672 : (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6082 : }
6083 972936 : if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
6084 65815 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[3] += (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6085 65815 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[4] +=
6086 65815 : NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6087 65815 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[5] +=
6088 65815 : (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6089 : }
6090 :
6091 972936 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
6092 : int encodedMonDayHrMin;
6093 0 : Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
6094 0 : Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
6095 :
6096 0 : if (PierceSET <= 12.2) {
6097 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[0] += (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
6098 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[1] += (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
6099 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[2] += (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6100 : // Reset duration when last step is out of range.
6101 0 : if (PierceSETLast == -1 || PierceSETLast > 12.2) {
6102 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6103 0 : state.dataEnvrn->Month,
6104 0 : state.dataEnvrn->DayOfMonth,
6105 0 : state.dataGlobal->HourOfDay,
6106 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6107 0 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
6108 0 : state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
6109 : }
6110 : // Keep the longest duration record.
6111 0 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
6112 0 : if (state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] &&
6113 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6114 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] = state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1];
6115 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[4] = state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1];
6116 : }
6117 0 : } else if (PierceSET > 30) {
6118 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[0] += (PierceSET - 30) * state.dataGlobal->TimeStepZone;
6119 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[1] += (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
6120 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[2] += (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6121 0 : if (PierceSETLast == -1 || PierceSETLast <= 30) {
6122 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6123 0 : state.dataEnvrn->Month,
6124 0 : state.dataEnvrn->DayOfMonth,
6125 0 : state.dataGlobal->HourOfDay,
6126 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6127 0 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
6128 0 : state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
6129 : }
6130 0 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
6131 0 : if (state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] &&
6132 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6133 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] = state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1];
6134 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[4] = state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1];
6135 : }
6136 : }
6137 :
6138 0 : if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
6139 0 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
6140 0 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
6141 : }
6142 : }
6143 :
6144 972936 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
6145 0 : if (reportPeriodFlags(i)) {
6146 0 : int ReportPeriodIdx = i;
6147 :
6148 0 : if (HI <= 26.7) {
6149 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6150 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6151 0 : NumOcc * state.dataGlobal->TimeStepZone;
6152 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6153 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6154 0 : } else if (HI > 26.7 && HI <= 32.2) {
6155 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6156 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6157 0 : NumOcc * state.dataGlobal->TimeStepZone;
6158 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6159 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6160 0 : } else if (HI > 32.2 && HI <= 39.4) {
6161 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6162 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6163 0 : NumOcc * state.dataGlobal->TimeStepZone;
6164 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6165 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6166 0 : } else if (HI > 39.4 && HI <= 51.7) {
6167 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6168 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6169 0 : NumOcc * state.dataGlobal->TimeStepZone;
6170 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6171 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6172 : } else {
6173 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
6174 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6175 0 : NumOcc * state.dataGlobal->TimeStepZone;
6176 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6177 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6178 : }
6179 :
6180 0 : if (Humidex <= 29) {
6181 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6182 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6183 0 : NumOcc * state.dataGlobal->TimeStepZone;
6184 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6185 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6186 0 : } else if (Humidex > 29 && Humidex <= 40) {
6187 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6188 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6189 0 : NumOcc * state.dataGlobal->TimeStepZone;
6190 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6191 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6192 0 : } else if (Humidex > 40 && Humidex <= 45) {
6193 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6194 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6195 0 : NumOcc * state.dataGlobal->TimeStepZone;
6196 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6197 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6198 0 : } else if (Humidex > 45 && Humidex <= 50) {
6199 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6200 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6201 0 : NumOcc * state.dataGlobal->TimeStepZone;
6202 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6203 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6204 : } else {
6205 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
6206 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6207 0 : NumOcc * state.dataGlobal->TimeStepZone;
6208 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6209 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6210 : }
6211 :
6212 0 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
6213 : int encodedMonDayHrMin;
6214 0 : Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
6215 0 : Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
6216 0 : if (PierceSET <= 12.2) {
6217 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6218 0 : (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
6219 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6220 0 : (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
6221 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6222 0 : (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6223 : // Reset duration when last step is out of range
6224 0 : if (PierceSETLast == -1 || PierceSETLast > 12.2) {
6225 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6226 0 : state.dataEnvrn->Month,
6227 0 : state.dataEnvrn->DayOfMonth,
6228 0 : state.dataGlobal->HourOfDay,
6229 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6230 0 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6231 0 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6232 0 : } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
6233 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6234 0 : state.dataEnvrn->Month,
6235 0 : state.dataEnvrn->DayOfMonth,
6236 0 : state.dataGlobal->HourOfDay,
6237 0 : state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
6238 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6239 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6240 : }
6241 : // Keep the longest duration record.
6242 0 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
6243 0 : if (state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
6244 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
6245 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6246 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
6247 0 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
6248 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
6249 0 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
6250 : }
6251 0 : } else if (PierceSET > 30) {
6252 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6253 0 : (PierceSET - 30) * state.dataGlobal->TimeStepZone;
6254 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6255 0 : (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
6256 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6257 0 : (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6258 : // Reset duration when last step is out of range.
6259 0 : if (PierceSETLast == -1 || PierceSETLast <= 30) {
6260 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6261 0 : state.dataEnvrn->Month,
6262 0 : state.dataEnvrn->DayOfMonth,
6263 0 : state.dataGlobal->HourOfDay,
6264 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6265 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6266 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6267 0 : } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
6268 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6269 0 : state.dataEnvrn->Month,
6270 0 : state.dataEnvrn->DayOfMonth,
6271 0 : state.dataGlobal->HourOfDay,
6272 0 : state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
6273 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6274 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6275 : }
6276 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
6277 0 : if (state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
6278 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
6279 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6280 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
6281 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
6282 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
6283 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
6284 : }
6285 : }
6286 0 : if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
6287 0 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6288 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6289 : }
6290 : }
6291 :
6292 0 : if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
6293 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6294 0 : (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6295 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6296 0 : NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6297 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6298 0 : (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6299 : }
6300 0 : if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
6301 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6302 0 : (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6303 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6304 0 : NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6305 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[5] +=
6306 0 : (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6307 : }
6308 : }
6309 : }
6310 : } // loop over zones
6311 : }
6312 1093515 : }
6313 :
6314 19097 : void ReportCO2Resilience(EnergyPlusData &state)
6315 : {
6316 19097 : if (state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime) {
6317 680 : int NoBins = 3;
6318 4365 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6319 3688 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6320 3 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6321 3 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6322 3 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6323 : }
6324 : }
6325 680 : state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime = false;
6326 680 : if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
6327 665 : if (state.dataOutRptTab->displayCO2ResilienceSummaryExplicitly) {
6328 0 : ShowWarningError(state,
6329 : "Writing Annual CO2 Resilience Summary - CO2 Level Hours reports: "
6330 : "Zone Air CO2 Concentration output is required, "
6331 : "but no ZoneAirContaminantBalance object is defined.");
6332 : }
6333 665 : state.dataOutRptTab->displayCO2ResilienceSummary = false;
6334 665 : return;
6335 : }
6336 : }
6337 :
6338 18432 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
6339 0 : for (auto const &people : state.dataHeatBal->People) {
6340 0 : state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
6341 0 : }
6342 :
6343 0 : Array1D_bool reportPeriodFlags;
6344 0 : if (state.dataWeather->TotReportPers > 0) {
6345 0 : reportPeriodFlags.dimension(state.dataWeather->TotCO2ReportPers, false);
6346 0 : General::findReportPeriodIdx(state, state.dataWeather->CO2ReportPeriodInput, state.dataWeather->TotCO2ReportPers, reportPeriodFlags);
6347 : }
6348 :
6349 0 : auto &ort = state.dataOutRptTab;
6350 0 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6351 0 : if (reportPeriodFlags(i)) {
6352 0 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
6353 0 : state.dataWeather->CO2ReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
6354 : }
6355 : }
6356 :
6357 0 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6358 0 : Real64 ZoneAirCO2 = state.dataContaminantBalance->ZoneAirCO2Avg(ZoneNum);
6359 :
6360 0 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6361 0 : if (ZoneAirCO2 <= 1000) {
6362 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[0] += state.dataGlobal->TimeStepZone;
6363 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6364 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6365 0 : } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
6366 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[1] += state.dataGlobal->TimeStepZone;
6367 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6368 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6369 : } else {
6370 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[2] += state.dataGlobal->TimeStepZone;
6371 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6372 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6373 : }
6374 0 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6375 0 : if (reportPeriodFlags(i)) {
6376 0 : int ReportPeriodIdx = i;
6377 0 : if (ZoneAirCO2 <= 1000) {
6378 0 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6379 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6380 0 : NumOcc * state.dataGlobal->TimeStepZone;
6381 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6382 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6383 0 : } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
6384 0 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6385 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6386 0 : NumOcc * state.dataGlobal->TimeStepZone;
6387 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6388 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6389 : } else {
6390 0 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6391 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6392 0 : NumOcc * state.dataGlobal->TimeStepZone;
6393 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6394 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6395 : }
6396 : }
6397 : }
6398 : }
6399 0 : } // loop over zones
6400 : }
6401 :
6402 93264 : void ReportVisualResilience(EnergyPlusData &state)
6403 : {
6404 93264 : if (state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime) {
6405 680 : int NoBins = 4;
6406 4365 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6407 3688 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6408 3 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6409 3 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6410 3 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6411 : }
6412 : }
6413 680 : state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime = false;
6414 680 : if ((int)state.dataDayltg->daylightControl.size() == 0) {
6415 624 : if (state.dataOutRptTab->displayVisualResilienceSummaryExplicitly) {
6416 0 : ShowWarningError(state,
6417 : "Writing Annual Visual Resilience Summary - Lighting Level Hours reports: "
6418 : "Zone Average Daylighting Reference Point Illuminance output is required, "
6419 : "but no Daylighting Control Object is defined.");
6420 : }
6421 624 : state.dataOutRptTab->displayVisualResilienceSummary = false;
6422 624 : return;
6423 : }
6424 : }
6425 :
6426 92640 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
6427 0 : for (auto const &people : state.dataHeatBal->People) {
6428 0 : state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
6429 0 : }
6430 : // Accumulate across daylighting controls first
6431 0 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6432 0 : state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum = 0.0;
6433 : }
6434 0 : for (int daylightCtrlNum = 1; daylightCtrlNum <= (int)state.dataDayltg->daylightControl.size(); ++daylightCtrlNum) {
6435 0 : auto &thisDaylightControl = state.dataDayltg->daylightControl(daylightCtrlNum);
6436 0 : if (thisDaylightControl.PowerReductionFactor > 0) {
6437 0 : for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
6438 0 : state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum += thisDaylightControl.refPts(refPt).illumSetPoint;
6439 : }
6440 : } else {
6441 0 : for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
6442 0 : state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum +=
6443 0 : thisDaylightControl.refPts(refPt).lums[(int)DataSurfaces::Lum::Illum];
6444 : }
6445 : }
6446 : }
6447 :
6448 0 : Array1D_bool reportPeriodFlags;
6449 0 : if (state.dataWeather->TotReportPers > 0) {
6450 0 : reportPeriodFlags.dimension(state.dataWeather->TotVisualReportPers, false);
6451 0 : General::findReportPeriodIdx(
6452 0 : state, state.dataWeather->VisualReportPeriodInput, state.dataWeather->TotVisualReportPers, reportPeriodFlags);
6453 : }
6454 :
6455 0 : auto &ort = state.dataOutRptTab;
6456 0 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6457 0 : if (reportPeriodFlags(i)) {
6458 0 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
6459 0 : state.dataWeather->VisualReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
6460 : }
6461 : }
6462 :
6463 0 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6464 0 : if (state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts == 0) {
6465 0 : continue;
6466 : }
6467 : // Now divide by total reference points to get average
6468 0 : Real64 avgZoneIllum = state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum / state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts;
6469 :
6470 0 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6471 0 : if (avgZoneIllum <= 100) {
6472 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[0] += state.dataGlobal->TimeStepZone;
6473 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6474 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6475 0 : } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
6476 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[1] += state.dataGlobal->TimeStepZone;
6477 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6478 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6479 0 : } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
6480 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[2] += state.dataGlobal->TimeStepZone;
6481 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6482 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6483 : } else {
6484 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[3] += state.dataGlobal->TimeStepZone;
6485 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
6486 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6487 : }
6488 0 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6489 0 : if (reportPeriodFlags(i)) {
6490 0 : int ReportPeriodIdx = i;
6491 0 : if (avgZoneIllum <= 100) {
6492 0 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6493 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6494 0 : NumOcc * state.dataGlobal->TimeStepZone;
6495 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6496 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6497 0 : } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
6498 0 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6499 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6500 0 : NumOcc * state.dataGlobal->TimeStepZone;
6501 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6502 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6503 0 : } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
6504 0 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6505 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6506 0 : NumOcc * state.dataGlobal->TimeStepZone;
6507 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6508 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6509 : } else {
6510 0 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6511 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6512 0 : NumOcc * state.dataGlobal->TimeStepZone;
6513 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6514 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6515 : }
6516 : }
6517 : }
6518 : }
6519 0 : } // loop over zones
6520 : }
6521 :
6522 2828212 : void ReportSurfaceHeatBalance(EnergyPlusData &state)
6523 : {
6524 :
6525 : // SUBROUTINE INFORMATION:
6526 : // AUTHOR Linda Lawrie
6527 : // DATE WRITTEN Oct 2000
6528 :
6529 : // PURPOSE OF THIS SUBROUTINE:
6530 : // This subroutine puts the reporting part of the HBSurface Module in one area.
6531 :
6532 2828212 : SolarShading::ReportSurfaceShading(state);
6533 :
6534 2828212 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
6535 687 : ReportNonRepresentativeSurfaceResults(state);
6536 : }
6537 :
6538 : // Set derived surface output variables and other record keeping - after iterations are complete - all HT surfaces
6539 :
6540 : // Opaque or window surfaces
6541 23362447 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6542 41117070 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6543 20582835 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6544 20582835 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
6545 20582835 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
6546 197906631 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6547 177323796 : auto const &surface = state.dataSurface->Surface(surfNum);
6548 : // Inside Face Convection - sign convention is positive means energy going into inside face from the air.
6549 177323796 : state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) = surface.Area * state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum);
6550 177323796 : state.dataHeatBalSurf->SurfQConvInRep(surfNum) =
6551 177323796 : state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6552 :
6553 177323796 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
6554 177323796 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(surfNum) =
6555 177323796 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6556 :
6557 177323796 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) * surface.Area;
6558 177323796 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(surfNum) =
6559 177323796 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6560 :
6561 177323796 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) * surface.Area;
6562 177323796 : state.dataHeatBalSurf->SurfQRadHVACInRep(surfNum) =
6563 177323796 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6564 :
6565 177323796 : state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) * surface.Area;
6566 :
6567 177323796 : state.dataHeatBalSurf->SurfQConvOutReport(surfNum) =
6568 177323796 : state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6569 :
6570 177323796 : state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) * surface.Area;
6571 177323796 : state.dataHeatBalSurf->SurfQRadOutReport(surfNum) =
6572 177323796 : state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6573 :
6574 : // Calculate surface heat emission to the air, positive values indicates heat transfer from surface to the outside
6575 177323796 : state.dataHeatBalSurf->SurfQAirExtReport(surfNum) =
6576 177323796 : surface.Area * state.dataHeatBalSurf->SurfHAirExt(surfNum) *
6577 177323796 : (state.dataHeatBalSurf->SurfTempOut(surfNum) - state.dataSurface->SurfOutDryBulbTemp(surfNum));
6578 :
6579 : // Subtract since SurfQdotConvOutRep's convention is opposite (positive values indicate heat transfer from the outside to the surface)
6580 177323796 : state.dataHeatBalSurf->SurfQHeatEmiReport(surfNum) =
6581 177323796 : state.dataHeatBalSurf->SurfQAirExtReport(surfNum) - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum);
6582 : }
6583 20534235 : }
6584 : }
6585 :
6586 2828212 : if (state.dataOutRptTab->displayHeatEmissionsSummary) {
6587 1089579 : state.dataHeatBalSurf->SumSurfaceHeatEmission = 0.0;
6588 48412815 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
6589 47323236 : if (state.dataSurface->Surface(SurfNum).ExtBoundCond == DataSurfaces::ExternalEnvironment) {
6590 21848829 : state.dataHeatBalSurf->SumSurfaceHeatEmission +=
6591 21848829 : state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
6592 : }
6593 : }
6594 : }
6595 :
6596 : // Window surfaces
6597 23362447 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6598 41117070 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6599 20582835 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6600 20582835 : int const firstSurf = thisSpace.WindowSurfaceFirst;
6601 20582835 : int const lastSurf = thisSpace.WindowSurfaceLast;
6602 44424183 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6603 23841348 : auto const &surface = state.dataSurface->Surface(surfNum);
6604 23841348 : state.dataHeatBal->SurfWinInitialDifSolInTransReport(surfNum) =
6605 23841348 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum) * surface.Area;
6606 :
6607 : // Absorbed short wave radiation
6608 : int TotGlassLayers;
6609 23841348 : int const constrNum = state.dataSurface->SurfActiveConstruction(surfNum);
6610 23841348 : auto const &thisConstruct = state.dataConstruction->Construct(constrNum);
6611 23841348 : int const constrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(surfNum);
6612 23841348 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(surfNum);
6613 23841348 : if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::EQL) {
6614 8109 : TotGlassLayers = state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL;
6615 23833239 : } else if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::BSDF) {
6616 39540 : TotGlassLayers = thisConstruct.TotSolidLayers;
6617 23793699 : } else if (DataSurfaces::NOT_SHADED(ShadeFlag) || ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
6618 23604721 : TotGlassLayers = thisConstruct.TotGlassLayers;
6619 : } else {
6620 : // Interior, exterior or between-glass shade, screen or blind in place
6621 188978 : TotGlassLayers = state.dataConstruction->Construct(constrNumSh).TotGlassLayers;
6622 : }
6623 23841348 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) = 0.0;
6624 23841348 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = 0.0;
6625 23841348 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = 0.0;
6626 54490572 : for (int lay = 1; lay <= TotGlassLayers; ++lay) {
6627 : // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
6628 30649224 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) +=
6629 30649224 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(surfNum, lay) * surface.Area;
6630 : // Total Shortwave Radiation Absorbed on Inside of Surface[W]
6631 30649224 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
6632 : // Total Shortwave Absorbed:All solid Layers[W]
6633 30649224 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
6634 : }
6635 :
6636 : // Window heat gain/loss
6637 23841348 : if (state.dataSurface->SurfWinHeatGain(surfNum) >= 0.0) {
6638 8172380 : state.dataSurface->SurfWinHeatGainRep(surfNum) = state.dataSurface->SurfWinHeatGain(surfNum);
6639 8172380 : state.dataSurface->SurfWinHeatGainRepEnergy(surfNum) =
6640 8172380 : state.dataSurface->SurfWinHeatGainRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6641 : } else {
6642 15668968 : state.dataSurface->SurfWinHeatLossRep(surfNum) = -state.dataSurface->SurfWinHeatGain(surfNum);
6643 15668968 : state.dataSurface->SurfWinHeatLossRepEnergy(surfNum) =
6644 15668968 : state.dataSurface->SurfWinHeatLossRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6645 : }
6646 23841348 : state.dataSurface->SurfWinHeatTransferRepEnergy(surfNum) =
6647 23841348 : state.dataSurface->SurfWinHeatGain(surfNum) * state.dataGlobal->TimeStepZoneSec;
6648 23841348 : if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
6649 4050 : int pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
6650 4050 : state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatGain = state.dataSurface->SurfWinHeatGainRep(surfNum);
6651 4050 : state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatLoss = state.dataSurface->SurfWinHeatLossRep(surfNum);
6652 : }
6653 : }
6654 20534235 : }
6655 : }
6656 :
6657 2828212 : if (state.dataSurface->AnyMovableInsulation) {
6658 10122 : ReportIntMovInsInsideSurfTemp(state);
6659 : }
6660 :
6661 : // Opaque heat transfer surfaces
6662 23362447 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6663 41117070 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6664 20582835 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6665 20582835 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6666 20582835 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6667 174065283 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6668 153482448 : auto const &surface = state.dataSurface->Surface(surfNum);
6669 :
6670 153482448 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) * surface.Area;
6671 153482448 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(surfNum) =
6672 153482448 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) * state.dataGlobal->TimeStepZoneSec;
6673 :
6674 153482448 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) * surface.Area;
6675 153482448 : state.dataHeatBalSurf->SurfQRadSolarInRep(surfNum) =
6676 153482448 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6677 :
6678 153482448 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) * surface.Area;
6679 153482448 : state.dataHeatBalSurf->SurfQRadLightsInRep(surfNum) =
6680 153482448 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6681 :
6682 : // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
6683 153482448 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(surfNum) * surface.Area;
6684 : // Total Shortwave Radiation Absorbed on Inside of Surface[W]
6685 153482448 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) * surface.Area;
6686 :
6687 : // inside face conduction updates
6688 153482448 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) * surface.Area;
6689 153482448 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(surfNum) =
6690 153482448 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6691 153482448 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = 0.0;
6692 153482448 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = 0.0;
6693 153482448 : if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) >= 0.0) {
6694 74628578 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6695 : } else {
6696 78853870 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6697 : }
6698 :
6699 : // outside face conduction updates
6700 153482448 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum);
6701 153482448 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(surfNum) =
6702 153482448 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6703 153482448 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = 0.0;
6704 153482448 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = 0.0;
6705 153482448 : if (state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) >= 0.0) {
6706 94490197 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6707 : } else {
6708 58992251 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6709 : }
6710 : }
6711 174065283 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6712 : // do average surface conduction updates
6713 :
6714 153482448 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) =
6715 153482448 : (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)) / 2.0;
6716 153482448 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(surfNum) =
6717 153482448 : (state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)) / 2.0;
6718 153482448 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(surfNum) =
6719 153482448 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6720 153482448 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = 0.0;
6721 153482448 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = 0.0;
6722 153482448 : if (state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) >= 0.0) {
6723 67224917 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
6724 : } else {
6725 86257531 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
6726 : }
6727 :
6728 : // do surface storage rate updates
6729 153482448 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux(surfNum) =
6730 153482448 : -(state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum));
6731 153482448 : state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) =
6732 153482448 : -(state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum));
6733 153482448 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(surfNum) =
6734 153482448 : state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6735 153482448 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = 0.0;
6736 153482448 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = 0.0;
6737 153482448 : if (state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) >= 0.0) {
6738 66423820 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
6739 : } else {
6740 87058628 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
6741 : }
6742 : }
6743 20534235 : }
6744 : }
6745 :
6746 2828212 : if (state.dataGlobal->ZoneSizingCalc && state.dataGlobal->CompLoadReportIsReq) {
6747 : // This is by surface, so it works for both space and zone component loads
6748 73122 : int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
6749 73122 : auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
6750 674988 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6751 1236060 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6752 634194 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6753 634194 : int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6754 634194 : int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6755 5032314 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6756 4398120 : surfCLDayTS.surf[surfNum - 1].lightSWRadSeq = state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum);
6757 4398120 : surfCLDayTS.surf[surfNum - 1].feneSolarRadSeq = state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum);
6758 : }
6759 634194 : firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
6760 634194 : lastSurf = thisSpace.OpaqOrWinSurfaceLast;
6761 5588010 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6762 4953816 : auto const &surface = state.dataSurface->Surface(surfNum);
6763 4953816 : if (!state.dataGlobal->WarmupFlag) {
6764 677376 : if (state.dataGlobal->isPulseZoneSizing) {
6765 338688 : surfCLDayTS.surf[surfNum - 1].loadConvectedWithPulse = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
6766 : } else {
6767 338688 : surfCLDayTS.surf[surfNum - 1].loadConvectedNormal = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
6768 338688 : surfCLDayTS.surf[surfNum - 1].netSurfRadSeq = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
6769 : }
6770 : }
6771 : }
6772 601866 : }
6773 : }
6774 : }
6775 :
6776 2828212 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
6777 514302 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6778 777210 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6779 388605 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6780 388605 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6781 388605 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6782 3186792 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6783 2798187 : state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6784 2798187 : state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6785 : }
6786 388605 : if (state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) >= 0.0) {
6787 177218 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
6788 177218 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) =
6789 177218 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6790 : } else {
6791 211387 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
6792 211387 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) =
6793 211387 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6794 : }
6795 :
6796 388605 : if (state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) >= 0.0) {
6797 256629 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
6798 256629 : state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) =
6799 256629 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6800 : } else {
6801 131976 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
6802 131976 : state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) =
6803 131976 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6804 : }
6805 388605 : }
6806 : }
6807 : }
6808 2828212 : }
6809 :
6810 687 : void ReportNonRepresentativeSurfaceResults(EnergyPlusData &state)
6811 : {
6812 32289 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6813 63204 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6814 31602 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6815 : // Heat transfer surfaces
6816 31602 : int firstSurf = thisSpace.HTSurfaceFirst;
6817 31602 : int lastSurf = thisSpace.HTSurfaceLast;
6818 429375 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6819 397773 : auto const &surface = state.dataSurface->Surface(surfNum);
6820 397773 : int repSurfNum = surface.RepresentativeCalcSurfNum;
6821 397773 : if (surfNum != repSurfNum) {
6822 89997 : state.dataSurface->surfIntConv(surfNum).convClassRpt = state.dataSurface->surfIntConv(repSurfNum).convClassRpt;
6823 89997 : state.dataSurface->surfExtConv(surfNum).convClassRpt = state.dataSurface->surfExtConv(repSurfNum).convClassRpt;
6824 : }
6825 : }
6826 :
6827 : // Windows
6828 31602 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
6829 0 : firstSurf = thisSpace.WindowSurfaceFirst;
6830 0 : lastSurf = thisSpace.WindowSurfaceLast;
6831 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6832 0 : auto const &surface = state.dataSurface->Surface(surfNum);
6833 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
6834 0 : if (surfNum != repSurfNum) {
6835 0 : Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
6836 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
6837 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
6838 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
6839 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
6840 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
6841 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(repSurfNum) * areaRatio;
6842 : }
6843 : }
6844 : }
6845 31602 : }
6846 : }
6847 687 : }
6848 :
6849 10122 : void ReportIntMovInsInsideSurfTemp(EnergyPlusData &state)
6850 : {
6851 10122 : state.dataHeatBalSurf->SurfTempInMovInsRep = state.dataHeatBalSurf->SurfTempIn;
6852 16197 : for (int SurfNum : state.dataSurface->intMovInsulSurfNums) {
6853 6075 : if (state.dataSurface->intMovInsuls(SurfNum).present) {
6854 6075 : state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
6855 : }
6856 10122 : }
6857 10122 : }
6858 : // End of Reporting subroutines for the HB Module
6859 : // *****************************************************************************
6860 :
6861 : // *****************************************************************************
6862 : // *****************************************************************************
6863 : // *****************************************************************************
6864 : // *****************************************************************************
6865 :
6866 : // Formerly EXTERNAL SUBROUTINES (heavily related to HeatBalanceSurfaceManager) now moved into namespace
6867 :
6868 3727810 : void CalcHeatBalanceOutsideSurf(EnergyPlusData &state,
6869 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
6870 : {
6871 :
6872 : // SUBROUTINE INFORMATION:
6873 : // AUTHOR George Walton
6874 : // DATE WRITTEN December 1979
6875 : // MODIFIED Jun 1990 (RDT for new CTF arrays);
6876 : // Aug 2000 (RJL for MTF moisture calculations)
6877 : // Sep 2000 (RKS for new radiant exchange algorithm)
6878 : // Dec 2000 (RKS for radiant system model addition)
6879 : // Apr 2002 (COP removed denominator from OSC calculation
6880 : // Jul 2008 (P.Biddulph include calls to HAMT)
6881 : // Jul 2011, M.J. Witte and C.O. Pedersen, add new fields to OSC for last T, max and min
6882 : // Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
6883 : // RE-ENGINEERED Mar 1998 (RKS)
6884 :
6885 : // PURPOSE OF THIS SUBROUTINE:
6886 : // This subroutine performs a heat balance on the outside face of each
6887 : // surface in the building.
6888 :
6889 : // METHODOLOGY EMPLOYED:
6890 : // Various boundary conditions are set and additional parameters are set-
6891 : // up. Then, the proper heat balance equation is selected based on the
6892 : // presence of movable insulation, thermal mass of the surface construction,
6893 : // and convection model being used.
6894 :
6895 : // REFERENCES:
6896 : // (I)BLAST legacy routine HBOUT
6897 : // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
6898 :
6899 : // // Using/Aliasing
6900 : // using namespace DataEnvironment;
6901 : // using namespace DataHeatBalance;
6902 : // using namespace DataHeatBalSurface;
6903 : // using namespace DataSurfaces;
6904 : // using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
6905 : // using namespace Psychrometrics;
6906 : // using EcoRoofManager::CalcEcoRoof;
6907 : //
6908 : // // Locals
6909 : // // SUBROUTINE ARGUMENT DEFINITIONS:
6910 : //
6911 : //>>>>>>> origin/develop
6912 : // SUBROUTINE PARAMETER DEFINITIONS:
6913 3727810 : constexpr std::string_view RoutineNameGroundTemp("CalcHeatBalanceOutsideSurf:GroundTemp");
6914 3727810 : constexpr std::string_view RoutineNameGroundTempFC("CalcHeatBalanceOutsideSurf:GroundTempFC");
6915 3727810 : constexpr std::string_view RoutineNameOtherSideCoefNoCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefNoCalcExt");
6916 3727810 : constexpr std::string_view RoutineNameOtherSideCoefCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefCalcExt");
6917 3727810 : constexpr std::string_view RoutineNameOSCM("CalcHeatBalanceOutsideSurf:OSCM");
6918 3727810 : constexpr std::string_view RoutineNameExtEnvWetSurf("CalcHeatBalanceOutsideSurf:extEnvWetSurf");
6919 3727810 : constexpr std::string_view RoutineNameExtEnvDrySurf("CalcHeatBalanceOutsideSurf:extEnvDrySurf");
6920 3727810 : constexpr std::string_view RoutineNameNoWind("CalcHeatBalanceOutsideSurf:nowind");
6921 3727810 : constexpr std::string_view RoutineNameOther("CalcHeatBalanceOutsideSurf:interior/other");
6922 3727810 : constexpr std::string_view RoutineNameIZPart("CalcHeatBalanceOutsideSurf:IZPart");
6923 3727810 : constexpr std::string_view HBSurfManGroundHAMT("HBSurfMan:Ground:HAMT");
6924 3727810 : constexpr std::string_view HBSurfManRainHAMT("HBSurfMan:Rain:HAMT");
6925 3727810 : constexpr std::string_view HBSurfManDrySurfCondFD("HBSurfMan:DrySurf:CondFD");
6926 3727810 : constexpr std::string_view Outside("Outside");
6927 :
6928 3727810 : auto &s_mat = state.dataMaterial;
6929 :
6930 3727810 : bool MovInsulErrorFlag = false; // Movable Insulation error flag
6931 :
6932 : // set ground surfaces average temperature
6933 3727810 : GetGroundSurfacesTemperatureAverage(state);
6934 :
6935 : // set surrounding surfaces average temperature
6936 3727810 : GetSurroundingSurfacesTemperatureAverage(state);
6937 :
6938 3727810 : auto &Surface = state.dataSurface->Surface;
6939 :
6940 3727810 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
6941 23750256 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
6942 : // Need to transfer any source/sink for a surface to the local array. Note that
6943 : // the local array is flux (W/m2) while the QRadSysSource is heat transfer (W).
6944 : // This must be done at this location so that this is always updated correctly.
6945 22781150 : if (Surface(SurfNum).Area > 0.0) {
6946 22781150 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) =
6947 22781150 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
6948 : }
6949 :
6950 : // next we add source (actually a sink) from any integrated PV
6951 22781150 : if (Surface(SurfNum).Area > 0.0) {
6952 22781150 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +=
6953 22781150 : state.dataHeatBalFanSys->QPVSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
6954 : }
6955 : }
6956 : }
6957 :
6958 3727810 : if (present(ZoneToResimulate)) {
6959 1592198 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
6960 796099 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, ZoneToResimulate, Outside);
6961 : } else {
6962 5863422 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
6963 2931711 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, Outside);
6964 : }
6965 :
6966 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
6967 3740383 : for (int surfNum : state.dataSurface->allOutsideSourceSurfaceList) {
6968 12573 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) = Surface(surfNum).outsideHeatSourceTermSched->getCurrentVal();
6969 3727810 : }
6970 27442346 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
6971 47477672 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6972 23763136 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
6973 224431910 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
6974 200668774 : if (Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) {
6975 25732712 : continue;
6976 : }
6977 174936062 : if (present(ZoneToResimulate)) {
6978 18716444 : if ((zoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) {
6979 11506789 : continue; // skip surfaces that are not associated with this zone
6980 : }
6981 : }
6982 : // Interior windows in partitions use "normal" heat balance calculations
6983 : // For rest, Outside surface temp of windows not needed in Window5 calculation approach.
6984 : // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
6985 :
6986 : // Initializations for this surface
6987 163429273 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
6988 163429273 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
6989 163429273 : Real64 HMovInsul = 0.0; // "Convection" coefficient of movable insulation
6990 163429273 : Real64 HSky = 0.0; // "Convection" coefficient from sky to surface
6991 163429273 : Real64 HGround = 0.0; // "Convection" coefficient from ground to surface
6992 163429273 : Real64 HAir = 0.0; // "Convection" coefficient from air to surface (radiation)
6993 163429273 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
6994 163429273 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
6995 163429273 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
6996 163429273 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
6997 163429273 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = 0.0;
6998 :
6999 : // Calculate the current outside surface temperature TH(SurfNum,1,1) for the
7000 : // various different boundary conditions
7001 163429273 : switch (Surface(SurfNum).ExtBoundCond) {
7002 9951112 : case DataSurfaces::Ground: { // Surface in contact with ground
7003 9951112 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
7004 9951112 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
7005 :
7006 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7007 9951112 : if (thisConstruct.SourceSinkPresent) {
7008 1374580 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7009 : }
7010 :
7011 : // start HAMT
7012 9951112 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7013 : // Set variables used in the HAMT moisture balance
7014 26913 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7015 26913 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
7016 26913 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
7017 26913 : state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0, HBSurfManGroundHAMT);
7018 26913 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7019 :
7020 26913 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7021 26913 : state.dataMstBal->HConvExtFD(SurfNum) /
7022 80739 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7023 : state,
7024 26913 : state.dataEnvrn->OutBaroPress,
7025 26913 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7026 : Psychrometrics::PsyWFnTdbRhPb(state,
7027 26913 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7028 : 1.0,
7029 26913 : state.dataEnvrn->OutBaroPress,
7030 26913 : RoutineNameGroundTemp)) +
7031 53826 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7032 26913 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7033 :
7034 26913 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7035 26913 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7036 26913 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7037 : }
7038 : // end HAMT
7039 :
7040 9951112 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7041 : // Set variables used in the FD moisture balance
7042 415748 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7043 415748 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
7044 415748 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
7045 415748 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0);
7046 415748 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7047 415748 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7048 415748 : state.dataMstBal->HConvExtFD(SurfNum) /
7049 1247244 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7050 : state,
7051 415748 : state.dataEnvrn->OutBaroPress,
7052 415748 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7053 : Psychrometrics::PsyWFnTdbRhPb(state,
7054 415748 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7055 : 1.0,
7056 415748 : state.dataEnvrn->OutBaroPress,
7057 415748 : RoutineNameGroundTemp)) +
7058 831496 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7059 415748 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7060 415748 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7061 415748 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7062 415748 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7063 : }
7064 : // Added for FCfactor grounds
7065 9951112 : } break;
7066 588276 : case DataSurfaces::GroundFCfactorMethod: { // Surface in contact with ground
7067 588276 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
7068 588276 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
7069 :
7070 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7071 588276 : if (thisConstruct.SourceSinkPresent) {
7072 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7073 : }
7074 :
7075 588276 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7076 : // Set variables used in the HAMT moisture balance
7077 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7078 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
7079 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
7080 0 : state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0, HBSurfManGroundHAMT);
7081 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7082 :
7083 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7084 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7085 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7086 : state,
7087 0 : state.dataEnvrn->OutBaroPress,
7088 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7089 : Psychrometrics::PsyWFnTdbRhPb(state,
7090 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7091 : 1.0,
7092 0 : state.dataEnvrn->OutBaroPress,
7093 0 : RoutineNameGroundTempFC)) +
7094 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7095 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7096 :
7097 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7098 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7099 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7100 : }
7101 :
7102 588276 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7103 : // Set variables used in the FD moisture balance
7104 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7105 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
7106 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
7107 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0);
7108 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7109 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7110 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7111 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7112 : state,
7113 0 : state.dataEnvrn->OutBaroPress,
7114 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7115 : Psychrometrics::PsyWFnTdbRhPb(state,
7116 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7117 : 1.0,
7118 0 : state.dataEnvrn->OutBaroPress,
7119 0 : RoutineNameGroundTempFC)) +
7120 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7121 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7122 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7123 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7124 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7125 : }
7126 588276 : } break;
7127 79287 : case DataSurfaces::OtherSideCoefNoCalcExt: {
7128 : // Use Other Side Coefficients to determine the surface film coefficient and
7129 : // the exterior boundary condition temperature
7130 :
7131 79287 : int OPtr = Surface(SurfNum).OSCPtr;
7132 : // Set surface temp from previous timestep
7133 79287 : if (state.dataGlobal->BeginTimeStepFlag) {
7134 79037 : state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7135 : }
7136 :
7137 79287 : if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
7138 71763 : state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
7139 : }
7140 :
7141 : // Allow for modification of TemperatureCoefficient with unitary sine wave.
7142 : Real64 ConstantTempCoef; // Temperature Coefficient as input or modified using sine wave COP mod
7143 79287 : if (state.dataSurface->OSC(OPtr).SinusoidalConstTempCoef) { // Sine wave C4
7144 3465 : ConstantTempCoef = std::sin(2 * Constant::Pi * state.dataGlobal->CurrentTime / state.dataSurface->OSC(OPtr).SinusoidPeriod);
7145 : } else {
7146 75822 : ConstantTempCoef = state.dataSurface->OSC(OPtr).ConstTempCoef;
7147 : }
7148 :
7149 79287 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7150 79287 : (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
7151 79287 : state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7152 79287 : ConstantTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
7153 79287 : state.dataSurface->OSC(OPtr).GroundTempCoef *
7154 79287 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
7155 79287 : state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
7156 79287 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7157 79287 : state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
7158 :
7159 : // Enforce max/min limits if applicable
7160 79287 : if (state.dataSurface->OSC(OPtr).MinLimitPresent) {
7161 33255 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7162 33255 : max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7163 : }
7164 79287 : if (state.dataSurface->OSC(OPtr).MaxLimitPresent) {
7165 33255 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7166 33255 : min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7167 : }
7168 :
7169 79287 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataSurface->OSC(OPtr).OSCTempCalc;
7170 :
7171 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7172 79287 : if (thisConstruct.SourceSinkPresent) {
7173 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7174 : }
7175 :
7176 158574 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7177 79287 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7178 : // Set variables used in the FD moisture balance and HAMT
7179 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7180 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7181 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7182 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7183 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7184 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7185 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7186 0 : state.dataEnvrn->OutBaroPress,
7187 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7188 : Psychrometrics::PsyWFnTdbRhPb(state,
7189 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7190 : 1.0,
7191 0 : state.dataEnvrn->OutBaroPress,
7192 0 : RoutineNameOtherSideCoefNoCalcExt)) +
7193 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7194 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7195 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7196 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7197 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7198 : }
7199 : // This ends the calculations for this surface and goes on to the next SurfNum
7200 79287 : } break;
7201 1353 : case DataSurfaces::OtherSideCoefCalcExt: { // A surface with other side coefficients that define the outside environment
7202 : // First, set up the outside convection coefficient and the exterior temperature
7203 : // boundary condition for the surface
7204 1353 : int OPtr = Surface(SurfNum).OSCPtr;
7205 : // Set surface temp from previous timestep
7206 1353 : if (state.dataGlobal->BeginTimeStepFlag) {
7207 1347 : state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7208 : }
7209 :
7210 1353 : if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
7211 0 : state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
7212 : }
7213 :
7214 1353 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSC(OPtr).SurfFilmCoef;
7215 :
7216 1353 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7217 1353 : (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
7218 1353 : state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7219 1353 : state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
7220 1353 : state.dataSurface->OSC(OPtr).GroundTempCoef *
7221 1353 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
7222 1353 : state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
7223 1353 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7224 1353 : state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
7225 :
7226 : // Enforce max/min limits if applicable
7227 1353 : if (state.dataSurface->OSC(OPtr).MinLimitPresent) {
7228 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7229 0 : max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7230 : }
7231 1353 : if (state.dataSurface->OSC(OPtr).MaxLimitPresent) {
7232 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7233 0 : min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7234 : }
7235 :
7236 1353 : Real64 TempExt = state.dataSurface->OSC(OPtr).OSCTempCalc;
7237 :
7238 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7239 1353 : if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) {
7240 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7241 : }
7242 :
7243 2706 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7244 1353 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7245 : // Set variables used in the FD moisture balance and HAMT
7246 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7247 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7248 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7249 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7250 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7251 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7252 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7253 0 : state.dataEnvrn->OutBaroPress,
7254 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7255 : Psychrometrics::PsyWFnTdbRhPb(state,
7256 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7257 : 1.0,
7258 0 : state.dataEnvrn->OutBaroPress,
7259 0 : RoutineNameOtherSideCoefCalcExt)) +
7260 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7261 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7262 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7263 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7264 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7265 : }
7266 :
7267 : // Call the outside surface temp calculation and pass the necessary terms
7268 1353 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7269 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7270 1353 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7271 1353 : if (MovInsulErrorFlag) {
7272 0 : ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7273 : }
7274 : }
7275 : // This ends the calculations for this surface and goes on to the next SurfNum
7276 1353 : } break;
7277 211815 : case DataSurfaces::OtherSideCondModeledExt: { // A surface with other side conditions determined from separate, dynamic component
7278 : // modeling that defines the "outside environment"
7279 : // First, set up the outside convection coefficient and the exterior temperature
7280 : // boundary condition for the surface
7281 211815 : int OPtr = Surface(SurfNum).OSCMPtr;
7282 : // EMS overrides
7283 211815 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTConv) {
7284 0 : state.dataSurface->OSCM(OPtr).TConv = state.dataSurface->OSCM(OPtr).EMSOverrideTConvValue;
7285 : }
7286 211815 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHConv) {
7287 0 : state.dataSurface->OSCM(OPtr).HConv = state.dataSurface->OSCM(OPtr).EMSOverrideHConvValue;
7288 : }
7289 211815 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTRad) {
7290 0 : state.dataSurface->OSCM(OPtr).TRad = state.dataSurface->OSCM(OPtr).EMSOverrideTRadValue;
7291 : }
7292 211815 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHrad) {
7293 0 : state.dataSurface->OSCM(OPtr).HRad = state.dataSurface->OSCM(OPtr).EMSOverrideHradValue;
7294 : }
7295 211815 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSCM(OPtr).HConv;
7296 :
7297 211815 : Real64 TempExt = state.dataSurface->OSCM(OPtr).TConv;
7298 :
7299 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7300 211815 : if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) {
7301 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7302 : }
7303 :
7304 423630 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7305 211815 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7306 : // Set variables used in the FD moisture balance and HAMT
7307 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7308 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7309 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7310 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7311 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7312 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7313 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7314 : state,
7315 0 : state.dataEnvrn->OutBaroPress,
7316 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7317 : Psychrometrics::PsyWFnTdbRhPb(
7318 0 : state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOSCM)) +
7319 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7320 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7321 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataSurface->OSCM(OPtr).HRad; // CR 8046, use sky term for surface to baffle IR
7322 0 : state.dataMstBal->HGrndFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
7323 0 : state.dataMstBal->HAirFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
7324 : }
7325 :
7326 : // Call the outside surface temp calculation and pass the necessary terms
7327 211815 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7328 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7329 :
7330 211815 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
7331 8124 : CalcExteriorVentedCavity(state, SurfNum);
7332 : }
7333 :
7334 211815 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7335 211815 : if (MovInsulErrorFlag) {
7336 0 : ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7337 : }
7338 :
7339 0 : } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7340 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7341 0 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
7342 0 : CalcExteriorVentedCavity(state, SurfNum);
7343 : }
7344 : }
7345 : // This ends the calculations for this surface and goes on to the next SurfNum
7346 211815 : } break;
7347 46731605 : case DataSurfaces::ExternalEnvironment: {
7348 : // checking the EcoRoof presented in the external environment
7349 : // recompute each load by calling ecoroof
7350 :
7351 : Real64 TempExt;
7352 :
7353 46731605 : if (state.dataSurface->SurfExtEcoRoof(SurfNum)) {
7354 443820 : EcoRoofManager::CalcEcoRoof(state, SurfNum, ConstrNum, TempExt);
7355 443820 : continue;
7356 : }
7357 : // Roughness index of the exterior surface
7358 46287785 : Material::SurfaceRoughness RoughSurf = state.dataHeatBalSurf->SurfRoughnessExt(SurfNum);
7359 : // Thermal absorptance of the exterior surface
7360 46287785 : Real64 AbsThermSurf = state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum);
7361 46287785 : HMovInsul = 0;
7362 : // Check for outside movable insulation
7363 46287785 : if (state.dataSurface->AnyMovableInsulation && state.dataSurface->extMovInsuls(SurfNum).present) {
7364 4047 : HMovInsul = state.dataSurface->extMovInsuls(SurfNum).H;
7365 : }
7366 :
7367 : // Check for exposure to wind (exterior environment)
7368 46287785 : if (Surface(SurfNum).ExtWind) {
7369 :
7370 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine)
7371 46110968 : Convect::InitExtConvCoeff(state,
7372 : SurfNum,
7373 : HMovInsul,
7374 : RoughSurf,
7375 : AbsThermSurf,
7376 46110968 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7377 46110968 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7378 46110968 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7379 46110968 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7380 46110968 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7381 46110968 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7382 :
7383 46110968 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside surface gets wet
7384 :
7385 11907 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum == 0) { // Reset SurfHcExt because of wetness
7386 11907 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0;
7387 : } else { // User set
7388 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
7389 : }
7390 :
7391 11907 : TempExt = state.dataSurface->SurfOutWetBulbTemp(SurfNum);
7392 :
7393 : // start HAMT
7394 11907 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7395 : // Set variables used in the HAMT moisture balance
7396 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7397 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) =
7398 0 : Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManRainHAMT);
7399 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7400 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7401 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7402 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7403 0 : state.dataEnvrn->OutBaroPress,
7404 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7405 : Psychrometrics::PsyWFnTdbRhPb(state,
7406 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7407 : 1.0,
7408 0 : state.dataEnvrn->OutBaroPress,
7409 0 : RoutineNameExtEnvWetSurf)) +
7410 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7411 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7412 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7413 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7414 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7415 : }
7416 : // end HAMT
7417 11907 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7418 : // Set variables used in the FD moisture balance
7419 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7420 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) =
7421 0 : Psychrometrics::PsyRhovFnTdbRhLBnd0C(state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0);
7422 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7423 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7424 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7425 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7426 0 : state.dataEnvrn->OutBaroPress,
7427 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7428 : Psychrometrics::PsyWFnTdbRhPb(state,
7429 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7430 : 1.0,
7431 0 : state.dataEnvrn->OutBaroPress,
7432 0 : RoutineNameExtEnvWetSurf)) +
7433 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7434 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7435 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7436 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7437 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7438 : }
7439 :
7440 : } else { // Surface is dry, use the normal correlation
7441 :
7442 46099061 : TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
7443 :
7444 90310240 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7445 44211179 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7446 : // Set variables used in the FD moisture balance and HAMT
7447 2032533 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7448 2032533 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7449 2032533 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7450 2032533 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7451 2032533 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7452 2032533 : state.dataMstBal->HConvExtFD(SurfNum) /
7453 4065066 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7454 2032533 : state.dataEnvrn->OutBaroPress,
7455 2032533 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7456 : Psychrometrics::PsyWFnTdbRhPb(state,
7457 2032533 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7458 : 1.0,
7459 2032533 : state.dataEnvrn->OutBaroPress,
7460 2032533 : RoutineNameExtEnvDrySurf)) +
7461 4065066 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7462 2032533 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7463 : // check for saturation conditions of air
7464 : // Local temporary saturated vapor density for checking
7465 : Real64 RhoVaporSat =
7466 2032533 : Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManDrySurfCondFD);
7467 2032533 : if (state.dataMstBal->RhoVaporAirOut(SurfNum) > RhoVaporSat) {
7468 1103097 : state.dataMstBal->RhoVaporAirOut(SurfNum) = RhoVaporSat;
7469 : }
7470 2032533 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7471 2032533 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7472 2032533 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7473 : }
7474 : }
7475 :
7476 : } else { // No wind
7477 :
7478 : // Calculate exterior heat transfer coefficients for windspeed = 0
7479 176817 : Convect::InitExtConvCoeff(state,
7480 : SurfNum,
7481 : HMovInsul,
7482 : RoughSurf,
7483 : AbsThermSurf,
7484 176817 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7485 176817 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7486 176817 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7487 176817 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7488 176817 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7489 176817 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7490 :
7491 176817 : TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
7492 :
7493 346908 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7494 170091 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7495 : // Set variables used in the FD moisture balance and HAMT
7496 6726 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7497 6726 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7498 6726 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7499 6726 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7500 6726 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7501 6726 : state.dataMstBal->HConvExtFD(SurfNum) /
7502 13452 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7503 6726 : state.dataEnvrn->OutBaroPress,
7504 6726 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7505 : Psychrometrics::PsyWFnTdbRhPb(state,
7506 6726 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7507 : 1.0,
7508 6726 : state.dataEnvrn->OutBaroPress,
7509 6726 : RoutineNameNoWind)) +
7510 13452 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7511 6726 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7512 6726 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7513 6726 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7514 6726 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7515 : }
7516 : }
7517 : // Calculate LWR from surrounding surfaces if defined for an exterior surface
7518 46287785 : if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
7519 5412 : int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
7520 : // Absolute temperature of the outside surface of an exterior surface
7521 5412 : Real64 TSurf = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) + Constant::Kelvin;
7522 13530 : for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface;
7523 : SrdSurfNum++) {
7524 : // View factor of a surrounding surface
7525 8118 : Real64 SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor;
7526 : // Absolute temperature of a surrounding surface
7527 : Real64 SrdSurfTempAbs =
7528 8118 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() +
7529 8118 : Constant::Kelvin;
7530 8118 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) +=
7531 8118 : Constant::StefanBoltzmann * AbsThermSurf * SrdSurfViewFac * (pow_4(SrdSurfTempAbs) - pow_4(TSurf));
7532 : }
7533 : }
7534 :
7535 46287785 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7536 48331094 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD ||
7537 2043309 : Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
7538 44248526 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7539 44248526 : if (MovInsulErrorFlag) {
7540 0 : ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7541 : }
7542 : }
7543 46287785 : } break;
7544 :
7545 118260 : case DataSurfaces::KivaFoundation: {
7546 118260 : auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
7547 118260 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness;
7548 118260 : Real64 AbsThermSurf = thisMaterial->AbsorpThermal;
7549 :
7550 : // Set Kiva exterior convection algorithms
7551 118260 : Convect::InitExtConvCoeff(state,
7552 : SurfNum,
7553 : HMovInsul,
7554 : RoughSurf,
7555 : AbsThermSurf,
7556 118260 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7557 118260 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7558 118260 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7559 118260 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7560 118260 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7561 118260 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7562 118260 : } break;
7563 :
7564 105747565 : default: { // for interior or other zone surfaces
7565 :
7566 105747565 : if (Surface(SurfNum).ExtBoundCond == SurfNum) { // Regular partition/internal mass
7567 :
7568 33568713 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
7569 :
7570 : // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
7571 :
7572 66992358 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7573 33423645 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7574 : // Set variables used in the FD moisture balance HAMT
7575 145068 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
7576 145068 : state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(SurfNum);
7577 145068 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
7578 145068 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7579 145068 : state.dataMstBal->HConvExtFD(SurfNum) /
7580 290136 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7581 : state,
7582 145068 : state.dataEnvrn->OutBaroPress,
7583 145068 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7584 : Psychrometrics::PsyWFnTdbRhPb(
7585 145068 : state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOther)) +
7586 290136 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7587 145068 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7588 145068 : state.dataMstBal->HSkyFD(SurfNum) = 0.0;
7589 145068 : state.dataMstBal->HGrndFD(SurfNum) = 0.0;
7590 145068 : state.dataMstBal->HAirFD(SurfNum) = 0.0;
7591 : }
7592 :
7593 : } else { // Interzone partition
7594 :
7595 72178852 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
7596 72178852 : state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
7597 :
7598 : // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
7599 :
7600 143214432 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7601 71035580 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7602 : // Set variables used in the FD moisture balance and HAMT
7603 1143272 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
7604 1143272 : state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(Surface(SurfNum).ExtBoundCond);
7605 1143272 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(Surface(SurfNum).ExtBoundCond);
7606 1143272 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7607 1143272 : state.dataMstBal->HConvExtFD(SurfNum) /
7608 2286544 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7609 1143272 : state.dataEnvrn->OutBaroPress,
7610 1143272 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7611 : Psychrometrics::PsyWFnTdbRhPb(state,
7612 1143272 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7613 : 1.0,
7614 1143272 : state.dataEnvrn->OutBaroPress,
7615 1143272 : RoutineNameIZPart)) +
7616 2286544 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7617 1143272 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7618 1143272 : state.dataMstBal->HSkyFD(SurfNum) = 0.0;
7619 1143272 : state.dataMstBal->HGrndFD(SurfNum) = 0.0;
7620 1143272 : state.dataMstBal->HAirFD(SurfNum) = 0.0;
7621 : }
7622 : }
7623 : // This ends the calculations for this surface and goes on to the next SurfNum
7624 105747565 : } break;
7625 : }
7626 :
7627 162985453 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = GetQdotConvOutPerArea(state, SurfNum);
7628 : }
7629 23714536 : }
7630 : } // ...end of DO loop over all surface (actually heat transfer surfaces)
7631 3727810 : }
7632 :
7633 162985453 : Real64 GetQdotConvOutPerArea(EnergyPlusData &state, int const SurfNum)
7634 : {
7635 162985453 : auto const &surface = state.dataSurface->Surface(SurfNum);
7636 162985453 : int OPtr = surface.OSCMPtr;
7637 162985453 : if (surface.OSCMPtr > 0) { // Optr is set above in this case, use OSCM boundary data
7638 211815 : return -state.dataSurface->OSCM(OPtr).HConv * (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->OSCM(OPtr).TConv);
7639 : } else {
7640 162773638 : if (state.dataEnvrn->IsRain) {
7641 43093 : return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
7642 43093 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutWetBulbTemp(SurfNum));
7643 : } else {
7644 162730545 : return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
7645 162730545 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutDryBulbTemp(SurfNum));
7646 : }
7647 : }
7648 : }
7649 :
7650 3760544 : void CalcHeatBalanceInsideSurf(EnergyPlusData &state,
7651 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
7652 : {
7653 3760544 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime) {
7654 801 : if (state.dataHeatBal->AnyEMPD) {
7655 2 : state.dataHeatBalSurf->MinIterations = DataHeatBalSurface::MinEMPDIterations;
7656 : }
7657 801 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
7658 66 : SetupOutputVariable(state,
7659 : "Surface Inside Face Heat Balance Calculation Iteration Count",
7660 : Constant::Units::None,
7661 22 : state.dataHeatBal->InsideSurfIterations,
7662 : OutputProcessor::TimeStepType::Zone,
7663 : OutputProcessor::StoreType::Sum,
7664 : "Simulation");
7665 : }
7666 : // Precompute whether CTF temperature limits will be needed
7667 801 : state.dataHeatBalSurf->Zone_has_mixed_HT_models.resize(state.dataGlobal->NumOfZones + 1, false);
7668 6002 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
7669 10414 : for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
7670 5213 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
7671 50485 : for (int iSurf = thisSpace.HTSurfaceFirst, eSurf = thisSpace.HTSurfaceLast; iSurf <= eSurf; ++iSurf) {
7672 45320 : DataSurfaces::HeatTransferModel const alg = state.dataSurface->Surface(iSurf).HeatTransferAlgorithm;
7673 45320 : if ((alg == DataSurfaces::HeatTransferModel::CondFD) || (alg == DataSurfaces::HeatTransferModel::HAMT) ||
7674 : (alg == DataSurfaces::HeatTransferModel::Kiva)) {
7675 48 : state.dataHeatBalSurf->Zone_has_mixed_HT_models[iZone] = true;
7676 48 : break;
7677 : }
7678 : }
7679 5201 : }
7680 : }
7681 801 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime = false;
7682 : }
7683 :
7684 3760544 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag) {
7685 6496 : state.dataHeatBalSurf->SurfTempInsOld = 23.0;
7686 6496 : state.dataHeatBalSurfMgr->RefAirTemp = 23.0;
7687 6496 : state.dataHeatBal->SurfTempEffBulkAir = 23.0;
7688 6496 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount = 0;
7689 6496 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = false;
7690 :
7691 : // Initialize Kiva instances ground temperatures
7692 6496 : if (state.dataHeatBal->AnyKiva) {
7693 63 : state.dataSurfaceGeometry->kivaManager.initKivaInstances(state);
7694 : }
7695 : }
7696 3760544 : if (!state.dataGlobal->BeginEnvrnFlag) {
7697 3751549 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = true;
7698 : }
7699 :
7700 3760544 : sumSurfQdotRadHVAC(state);
7701 :
7702 : // Pass correct list of surfaces to CalcHeatBalanceInsideSurf2
7703 3760544 : bool const PartialResimulate(present(ZoneToResimulate));
7704 :
7705 3760544 : if (!PartialResimulate) {
7706 2964445 : if (state.dataHeatBal->AllCTF) {
7707 2721446 : CalcHeatBalanceInsideSurf2CTFOnly(state, 1, state.dataGlobal->NumOfZones, state.dataSurface->AllIZSurfaceList);
7708 : } else {
7709 485998 : CalcHeatBalanceInsideSurf2(state,
7710 242999 : state.dataSurface->AllHTSurfaceList,
7711 242999 : state.dataSurface->AllIZSurfaceList,
7712 242999 : state.dataSurface->AllHTNonWindowSurfaceList,
7713 242999 : state.dataSurface->AllHTWindowSurfaceList);
7714 : }
7715 : } else {
7716 796099 : auto const &zoneHTSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTSurfaceList;
7717 796099 : auto const &zoneIZSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneIZSurfaceList;
7718 796099 : auto const &zoneHTNonWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTNonWindowSurfaceList;
7719 796099 : auto const &zoneHTWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTWindowSurfaceList;
7720 : // Cannot use CalcHeatBalanceInsideSurf2CTFOnly because resimulated zone includes adjacent interzone surfaces
7721 796099 : CalcHeatBalanceInsideSurf2(state, zoneHTSurfList, zoneIZSurfList, zoneHTNonWindowSurfList, zoneHTWindowSurfList, ZoneToResimulate);
7722 : }
7723 3760544 : CalculateZoneMRT(state, ZoneToResimulate); // Update here so that the proper value of MRT is available to radiant systems
7724 3760544 : UpdateIntermediateSurfaceHeatBalanceResults(state, ZoneToResimulate);
7725 3760544 : }
7726 :
7727 1039098 : void CalcHeatBalanceInsideSurf2(EnergyPlusData &state,
7728 : const std::vector<int> &HTSurfs, // Heat transfer surfaces to simulate (opaque and windows)
7729 : const std::vector<int> &IZSurfs, // Interzone heat transfer surfaces to simulate
7730 : const std::vector<int> &HTNonWindowSurfs, // Non-window heat transfer surfaces to simulate
7731 : const std::vector<int> &HTWindowSurfs, // Window heat transfer surfaces to simulate
7732 : ObjexxFCL::Optional_int_const ZoneToResimulate)
7733 : {
7734 : // SUBROUTINE INFORMATION:
7735 : // AUTHOR George Walton
7736 : // DATE WRITTEN December 1979
7737 : // MODIFIED Jun 1990 (RDT for new CTF arrays)
7738 : // Dec 1999 (FCW for window calculation)
7739 : // May 2000 (FCW for window frame and dividers)
7740 : // Aug 2000 (RJL for MTF moisture calculations)
7741 : // Sep 2000 (RKS for new radiant exchange algorithm)
7742 : // Dec 2000 (RKS for radiant system model addition)
7743 : // Jul 2003 (CC) set the reference temperatures for inside surface heat balance
7744 : // depending on convection algorithms and/or air models used
7745 : // May 2006 (RR account for exterior window screen)
7746 : // Jul 2008 (P. Biddulph include calls to HAMT)
7747 : // Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
7748 : // RE-ENGINEERED Mar 1998 (RKS)
7749 :
7750 : // PURPOSE OF THIS SUBROUTINE:
7751 : // This subroutine performs a heat balance on the inside face of each
7752 : // surface in the building.
7753 :
7754 : // METHODOLOGY EMPLOYED:
7755 : // Various boundary conditions are set and additional parameters are set-
7756 : // up. Then, the proper heat balance equation is selected based on whether
7757 : // the surface is a partition or not and on whether or not movable
7758 : // insulation is present on the inside face.
7759 :
7760 : // REFERENCES:
7761 : // (I)BLAST legacy routine HBSRF
7762 :
7763 1039098 : constexpr std::string_view rhoAirZone("RhoAirZone");
7764 1039098 : constexpr std::string_view wsurf("Wsurf");
7765 1039098 : constexpr std::string_view HBSurfManInsideSurf("HB,SurfMan:InsideSurf");
7766 1039098 : constexpr std::string_view Inside("Inside");
7767 :
7768 : Real64 TempSurfOutTmp; // Local Temporary Surface temperature for the outside surface face
7769 : Real64 SurfTempInSat; // Local temporary surface dew point temperature
7770 :
7771 : Real64 Wsurf; // Moisture ratio for HAMT
7772 : Real64 RhoAirZone; // Zone moisture density for HAMT
7773 : int OtherSideZoneNum; // Zone Number index for other side of an interzone partition HAMT
7774 :
7775 1039098 : auto &s_mat = state.dataMaterial;
7776 : // determine reference air temperatures
7777 13649562 : for (int SurfNum : HTSurfs) {
7778 :
7779 : // These conditions are not used in every SurfNum loop here so we don't use them to skip surfaces
7780 12610464 : if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
7781 0 : continue; // Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.
7782 : }
7783 12610464 : Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum);
7784 12610464 : state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) = RefAirTemp;
7785 12610464 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataHeatBalSurfMgr->RefAirTemp(SurfNum);
7786 1039098 : }
7787 :
7788 : // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
7789 : // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
7790 : // CalcWindowHeatBalance.
7791 : // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
7792 1963423 : for (int surfNum : HTWindowSurfs) {
7793 924325 : state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
7794 924325 : state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
7795 924325 : state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
7796 924325 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
7797 924325 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
7798 924325 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
7799 924325 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
7800 924325 : state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
7801 924325 : state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
7802 924325 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
7803 924325 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
7804 924325 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
7805 924325 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
7806 1039098 : }
7807 :
7808 1039098 : state.dataHeatBal->InsideSurfIterations = 0;
7809 :
7810 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
7811 1039098 : for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
7812 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
7813 0 : state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
7814 1039098 : }
7815 :
7816 : // Calculate Kiva instances
7817 1039098 : if (state.dataHeatBal->AnyKiva) {
7818 30738 : if (((state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::HOURLY &&
7819 21897 : state.dataGlobal->TimeStep == 1) ||
7820 61476 : state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::TIMESTEP) &&
7821 13063 : !state.dataGlobal->WarmupFlag) {
7822 9336 : state.dataSurfaceGeometry->kivaManager.calcKivaInstances(state);
7823 : }
7824 : }
7825 :
7826 1039098 : bool Converged = false; // .TRUE. if inside heat balance has converged
7827 4133103 : while (!Converged) { // Start of main inside heat balance DO loop...
7828 :
7829 3094005 : state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
7830 :
7831 3094005 : if (state.dataHeatBal->AnyKiva) {
7832 865799 : for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
7833 663220 : state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = kivaSurf.second.results.Trad - Constant::Kelvin;
7834 202579 : }
7835 : }
7836 :
7837 6188010 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
7838 3094005 : state.dataHeatBalSurf->SurfTempIn,
7839 3094005 : state.dataHeatBal->InsideSurfIterations,
7840 3094005 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
7841 : ZoneToResimulate,
7842 : Inside); // Update the radiation balance
7843 :
7844 3094005 : if (state.dataHeatBal->AnyKiva) {
7845 865799 : for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
7846 663220 : state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = state.dataHeatBalSurf->SurfTempInsOld(kivaSurf.first);
7847 202579 : }
7848 : }
7849 :
7850 : // Every 30 iterations, recalculate the inside convection coefficients in case
7851 : // there has been a significant drift in the surface temperatures predicted.
7852 : // This is not fool-proof and it basically means that the outside surface
7853 : // heat balance is in error (potentially) once HConvIn is re-evaluated.
7854 : // The choice of 30 is not significant--just want to do this a couple of
7855 : // times before the iteration limit is hit.
7856 5148912 : if ((state.dataHeatBal->InsideSurfIterations > 0) &&
7857 2054907 : (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
7858 67 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
7859 : }
7860 :
7861 3094005 : if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
7862 1437866 : for (int SurfNum : HTSurfs) {
7863 1330236 : auto const &surface = state.dataSurface->Surface(SurfNum);
7864 1330236 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
7865 0 : continue; // Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.
7866 : }
7867 :
7868 : // Calculate the inside surface moisture quantities
7869 : // calculate the inside surface moisture transfer conditions
7870 : // check for saturation conditions of air
7871 1330236 : if ((surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) ||
7872 626657 : (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)) {
7873 1056940 : int ZoneNum = surface.Zone;
7874 1056940 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
7875 1056940 : Real64 const ZoneAirHumRat_zone(max(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRat, 1.0e-5));
7876 1056940 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
7877 :
7878 1056940 : state.dataMstBal->RhoVaporAirIn(SurfNum) =
7879 1056940 : min(Psychrometrics::PsyRhovFnTdbWPb_fast(MAT_zone, ZoneAirHumRat_zone, state.dataEnvrn->OutBaroPress),
7880 : Psychrometrics::PsyRhovFnTdbRh(state, MAT_zone, 1.0, HBSurfManInsideSurf));
7881 1056940 : state.dataMstBal->HMassConvInFD(SurfNum) =
7882 2113880 : HConvIn_surf / (Psychrometrics::PsyRhoAirFnPbTdbW_fast(state, state.dataEnvrn->OutBaroPress, MAT_zone, ZoneAirHumRat_zone) *
7883 1056940 : Psychrometrics::PsyCpAirFnW_fast(ZoneAirHumRat_zone));
7884 : }
7885 107630 : }
7886 : }
7887 :
7888 43739600 : for (int SurfNum : HTNonWindowSurfs) {
7889 : // Perform heat balance on the inside face of the surface ...
7890 : // The following are possibilities here:
7891 : // (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
7892 : // (b) the surface is a partition, in which case the temperature of both sides are the same
7893 : // (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
7894 : // (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
7895 : // (e) standard opaque surface with movable insulation, special two-part equation
7896 : // In the surface calculation there are the following Algorithm types for opaque surfaces that
7897 : // do not have movable insulation:
7898 : // (a) the regular CTF calc (SolutionAlgo = UseCTF)
7899 : // (b) the EMPD calc (Solutionalgo = UseEMPD)
7900 : // (c) the CondFD calc (SolutionAlgo = UseCondFD)
7901 : // (d) the HAMT calc (solutionalgo = UseHAMT).
7902 :
7903 40645595 : auto const &surface = state.dataSurface->Surface(SurfNum);
7904 40645595 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
7905 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
7906 0 : if (SurfNum != repSurfNum) {
7907 0 : continue;
7908 : }
7909 : }
7910 40645595 : int const ZoneNum = surface.Zone;
7911 40645595 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7912 40645595 : int const ConstrNum = surface.Construction;
7913 40645595 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
7914 40645595 : Real64 const MAT_zone = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
7915 40645595 : Real64 const HConvIn_surf = state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
7916 :
7917 40645595 : if (surface.ExtBoundCond == SurfNum) {
7918 : // CR6869 -- let Window HB take care of it IF (Surface(SurfNum)%ExtBoundCond == SurfNum) THEN
7919 : // Surface is adiabatic
7920 2270634 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7921 295824 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
7922 :
7923 1974810 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7924 0 : MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
7925 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
7926 : }
7927 : // Pre-calculate a few terms
7928 : Real64 const TempTerm(
7929 1974810 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
7930 1974810 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
7931 1974810 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
7932 1974810 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
7933 1974810 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
7934 1974810 : Real64 const TempDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
7935 : // Calculate the current inside surface temperature
7936 1974810 : if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
7937 0 : ((state.dataSurface->SurfIsPool(SurfNum)) &&
7938 0 : (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
7939 0 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
7940 1974810 : if (construct.SourceSinkPresent) {
7941 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7942 0 : (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
7943 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
7944 : TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
7945 : // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
7946 : // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
7947 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
7948 : // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
7949 : // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
7950 : // same temp) | Convection and damping term | Radiation from AFN ducts
7951 : } else {
7952 1974810 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7953 1974810 : (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
7954 : TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
7955 : // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
7956 : // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
7957 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
7958 : // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
7959 : // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
7960 : // same temp) | Convection and damping term | Radiation from AFN ducts
7961 : }
7962 : } else { // this is a pool and it has been simulated this time step
7963 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7964 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
7965 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) /
7966 0 : (construct.CTFInside[0] - construct.CTFCross[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
7967 : DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms (see
7968 : // non-pool equation for details) | Iterative damping term (for stability) |
7969 : // Conduction term (both partition sides same temp) | Pool and damping term
7970 : }
7971 1974810 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7972 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
7973 0 : state.dataMstBalEMPD->HeatFluxLatent(SurfNum) * TempDiv; // Conduction term (both partition sides same temp) |
7974 : // Conduction term (both partition sides same temp) |
7975 : // Convection and damping term
7976 0 : if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
7977 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
7978 : }
7979 : }
7980 : // if any mixed heat transfer models in zone, apply limits to CTF result
7981 1974810 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
7982 766517 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7983 766517 : max(DataHeatBalSurface::MinSurfaceTempLimit,
7984 766517 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
7985 766517 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
7986 : }
7987 :
7988 1974810 : if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
7989 :
7990 : // Radiant system does not need the damping coefficient terms (hopefully) // Partitions are assumed to be symmetric
7991 0 : Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf));
7992 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
7993 0 : TempTerm * RadSysDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW
7994 : // radiation from internal sources | Convection from surface to zone air | Radiant flux from
7995 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant
7996 : // flux from a steam baseboard heater | Radiant flux from an electric baseboard heater | Net
7997 : // radiant exchange with other zone surfaces | Cond term (both partition sides same temp) | Cond
7998 : // term (both partition sides same temp) | Convection and damping term
7999 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
8000 : 0.0; // The outside temp is assumed to be equal to the inside temp for a partition
8001 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
8002 0 : construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both partition sides same temp) | Cond
8003 : // term (both partition sides same temp) | Convection and damping term
8004 : }
8005 :
8006 2270634 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
8007 0 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8008 :
8009 295824 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8010 0 : HeatBalanceHAMTManager::ManageHeatBalHAMT(state,
8011 : SurfNum,
8012 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
8013 : TempSurfOutTmp); // HAMT
8014 : }
8015 :
8016 295824 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
8017 591648 : HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
8018 295824 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
8019 : }
8020 :
8021 295824 : TH11 = TempSurfOutTmp;
8022 : }
8023 :
8024 2270634 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8025 :
8026 : } else { // Standard surface or interzone surface
8027 38374961 : bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataSurface->intMovInsuls(SurfNum).present;
8028 38374961 : if (!movableInsulPresent) { // No movable insulation present, normal heat balance equation
8029 :
8030 38374961 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
8031 11664367 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
8032 :
8033 27414173 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
8034 703579 : MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
8035 703579 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
8036 : }
8037 : // Pre-calculate a few terms
8038 : Real64 const TempTerm(
8039 27414173 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
8040 27414173 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
8041 27414173 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
8042 27414173 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
8043 27414173 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
8044 27414173 : Real64 const TempDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
8045 : // Calculate the current inside surface temperature
8046 27414173 : if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
8047 0 : ((state.dataSurface->SurfIsPool(SurfNum)) &&
8048 0 : (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
8049 0 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
8050 27414173 : if (construct.SourceSinkPresent) {
8051 1678300 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8052 1678300 : (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
8053 1678300 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
8054 1678300 : construct.CTFCross[0] * TH11) *
8055 : TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
8056 : // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
8057 : // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
8058 : // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
8059 : // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
8060 : // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
8061 : // outside surface | Coefficient for conduction (current time) | Convection and damping term |
8062 : // Radiation from AFN ducts
8063 : } else {
8064 25735873 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8065 25735873 : (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
8066 25735873 : construct.CTFCross[0] * TH11) *
8067 : TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
8068 : // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
8069 : // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
8070 : // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
8071 : // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
8072 : // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
8073 : // outside surface | Coefficient for conduction (current time) | Convection and damping term |
8074 : // Radiation from AFN ducts
8075 : }
8076 : } else { // surface is a pool and the pool has been simulated this time step
8077 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8078 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
8079 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) /
8080 0 : (construct.CTFInside[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
8081 : DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms
8082 : // (see non-pool equation for details) | Iterative damping term (for
8083 : // stability) | Current conduction from | the outside surface |
8084 : // Coefficient for conduction (current time) | Pool and damping term
8085 : }
8086 27414173 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
8087 703579 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
8088 703579 : state.dataMstBalEMPD->HeatFluxLatent(SurfNum) *
8089 : TempDiv; // Coefficient for conduction (current time) | Convection and damping term
8090 703579 : if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
8091 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
8092 : }
8093 : }
8094 : // if any mixed heat transfer models in zone, apply limits to CTF result
8095 27414173 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
8096 3648198 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = max(
8097 : DataHeatBalSurface::MinSurfaceTempLimit,
8098 3648198 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
8099 3648198 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
8100 : }
8101 :
8102 27414173 : if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
8103 :
8104 : // Radiant system does not need the damping coefficient terms (hopefully)
8105 1678300 : Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf));
8106 1678300 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
8107 1678300 : TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
8108 : // radiation from internal sources | Convection from surface to zone air | Radiant flux
8109 : // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
8110 : // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
8111 : // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
8112 : // sides same temp) | Convection and damping term
8113 1678300 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
8114 1678300 : construct.CTFCross[0] * RadSysDiv; // Outside temp=inside temp for a partition |
8115 : // Cond term (both partition sides same temp) |
8116 : // Convection and damping term
8117 1678300 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
8118 1678300 : construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both
8119 : // partition sides same temp) | Convection and
8120 : // damping term
8121 :
8122 1678300 : if (surface.ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
8123 : // The inside coefficients of one side are equal to the outside coefficients of the other side. But,
8124 : // the inside coefficients are set up once the heat balance equation for that side has been calculated.
8125 : // For both sides to actually have been set, we have to wait until we get to the second side in the surface
8126 : // derived type. At that point, both inside coefficient sets have been evaluated.
8127 270256 : if (surface.ExtBoundCond < SurfNum) { // Both of the inside coefficients have now been set
8128 135128 : int OtherSideSurfNum = surface.ExtBoundCond;
8129 135128 : state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
8130 135128 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
8131 135128 : state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
8132 135128 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
8133 135128 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
8134 135128 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
8135 135128 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
8136 135128 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
8137 135128 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) =
8138 135128 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
8139 135128 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) =
8140 135128 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
8141 : }
8142 : }
8143 : }
8144 :
8145 38374961 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
8146 1016581 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8147 :
8148 10297568 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8149 353361 : if (surface.ExtBoundCond > 0) {
8150 : // HAMT get the correct other side zone zone air temperature --
8151 0 : int OtherSideSurfNum = surface.ExtBoundCond;
8152 : // ZoneNum = surface.Zone;
8153 0 : OtherSideZoneNum = state.dataSurface->Surface(OtherSideSurfNum).Zone;
8154 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
8155 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(OtherSideZoneNum).MAT;
8156 : }
8157 353361 : HeatBalanceHAMTManager::ManageHeatBalHAMT(state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
8158 : }
8159 :
8160 10297568 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
8161 19888414 : HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
8162 9944207 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
8163 : }
8164 :
8165 10297568 : TH11 = TempSurfOutTmp;
8166 :
8167 10960788 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) {
8168 : // Read Kiva results for each surface
8169 663220 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8170 663220 : state.dataSurfaceGeometry->kivaManager.surfaceMap[SurfNum].results.Tconv - Constant::Kelvin;
8171 :
8172 663220 : TH11 = 0.0;
8173 : }
8174 :
8175 38374961 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8176 :
8177 : } else { // Movable insulation present
8178 0 : Real64 HMovInsul = state.dataSurface->intMovInsuls(SurfNum).H;
8179 0 : if (construct.SourceSinkPresent) {
8180 :
8181 0 : ShowSevereError(state, "Interior movable insulation is not valid with embedded sources/sinks");
8182 0 : ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
8183 0 : ShowContinueError(state,
8184 0 : format("interior movable insulation {} for a surface with that construction.",
8185 0 : s_mat->materials(state.dataSurface->intMovInsuls(SurfNum).matNum)->Name));
8186 0 : ShowContinueError(state,
8187 : "This is not currently allowed because the heat balance equations do not currently accommodate "
8188 : "this combination.");
8189 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
8190 : }
8191 :
8192 0 : Real64 F1 = HMovInsul / (HMovInsul + HConvIn_surf + DataHeatBalSurface::IterDampConst);
8193 :
8194 0 : state.dataHeatBalSurf->SurfTempIn(SurfNum) =
8195 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
8196 0 : construct.CTFCross[0] * TH11 +
8197 0 : F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
8198 0 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
8199 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
8200 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
8201 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum))) /
8202 0 : (construct.CTFInside[0] + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
8203 :
8204 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8205 0 : (construct.CTFInside[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
8206 0 : HMovInsul * state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) -
8207 0 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) - construct.CTFCross[0] * TH11) /
8208 : (HMovInsul);
8209 : // if any mixed heat transfer models in zone, apply limits to CTF result
8210 0 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
8211 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8212 0 : max(DataHeatBalSurface::MinSurfaceTempLimit,
8213 0 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
8214 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
8215 : }
8216 : }
8217 : }
8218 3094005 : }
8219 6456894 : for (int SurfNum : HTWindowSurfs) {
8220 3362889 : auto &surface = state.dataSurface->Surface(SurfNum);
8221 3362889 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8222 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8223 0 : if (SurfNum != repSurfNum) {
8224 0 : continue;
8225 : }
8226 : }
8227 3362889 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
8228 3362889 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // Not const, because storm window may change this
8229 3362889 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8230 3362889 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8231 : // Lookup up the TDD:DOME object
8232 0 : int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
8233 0 : int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
8234 : // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
8235 0 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
8236 :
8237 : // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
8238 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
8239 : // = SurfWinQRadSWwinAbs(SurfNum,1)/2.0
8240 0 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
8241 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8242 0 : (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
8243 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) + HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
8244 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
8245 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
8246 0 : Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
8247 0 : (Ueff + HConvIn_surf +
8248 : DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
8249 : // solar | Convection from surface to zone air | Net radiant exchange with
8250 : // other zone surfaces | Iterative damping term (for stability) | Current
8251 : // conduction from the outside surface | Coefficient for conduction (current
8252 : // time) | Convection and damping term
8253 0 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8254 :
8255 0 : Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(SurfNum) + Constant::Kelvin));
8256 :
8257 : // fill out report vars for components of Window Heat Gain
8258 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) =
8259 0 : HConvIn_surf * surface.Area * (state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(SurfNum));
8260 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
8261 0 : state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
8262 0 : (Sigma_Temp_4 - (state.dataSurface->SurfWinIRfromParentZone(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)));
8263 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) =
8264 0 : state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
8265 0 : (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
8266 0 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum);
8267 :
8268 : // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
8269 0 : state.dataSurface->SurfWinHeatGain(SurfNum) =
8270 0 : state.dataSurface->SurfWinTransSolar(SurfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) +
8271 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) -
8272 0 : surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum);
8273 : // Net transmitted solar | Convection | IR exchange | IR
8274 : // Zone diffuse interior shortwave reflected back into the TDD
8275 :
8276 : } else { // Regular window
8277 3362889 : if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
8278 : // Get outside convection coeff for exterior window here to avoid calling
8279 : // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
8280 : // (HeatBalanceSurfaceManager USEing and WindowManager and
8281 : // WindowManager USEing HeatBalanceSurfaceManager)
8282 924325 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
8283 924325 : auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
8284 924325 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
8285 924325 : Real64 EmisOut = thisMaterial->AbsorpThermalFront; // Glass outside surface emissivity
8286 924325 : DataSurfaces::WinShadingType const shading_flag(state.dataSurface->SurfWinShadingFlag(SurfNum));
8287 924325 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
8288 : // Exterior shade in place
8289 0 : int const ConstrNumSh = surface.activeShadedConstruction;
8290 0 : if (ConstrNumSh != 0) {
8291 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
8292 0 : auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
8293 0 : assert(thisMaterial2 != nullptr);
8294 0 : RoughSurf = thisMaterial2->Roughness;
8295 0 : EmisOut = thisMaterial2->AbsorpThermal;
8296 : }
8297 : }
8298 :
8299 : // Get the outside effective emissivity for Equivalent layer model
8300 924325 : if (construct.WindowTypeEQL) {
8301 0 : EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
8302 : }
8303 : // Set Exterior Convection Coefficient...
8304 924325 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
8305 :
8306 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
8307 :
8308 924325 : } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
8309 :
8310 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
8311 : // subroutine)
8312 924325 : Convect::InitExtConvCoeff(state,
8313 : SurfNum,
8314 : 0.0,
8315 : RoughSurf,
8316 : EmisOut,
8317 : TH11,
8318 924325 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
8319 924325 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
8320 924325 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
8321 924325 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
8322 924325 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
8323 :
8324 924325 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
8325 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0; // Reset SurfHcExt because of wetness
8326 : }
8327 :
8328 : } else { // Not Wind exposed
8329 :
8330 : // Calculate exterior heat transfer coefficients for windspeed = 0
8331 0 : Convect::InitExtConvCoeff(state,
8332 : SurfNum,
8333 : 0.0,
8334 : RoughSurf,
8335 : EmisOut,
8336 : TH11,
8337 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
8338 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
8339 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
8340 0 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
8341 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
8342 : }
8343 : } else { // Interior Surface
8344 :
8345 0 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
8346 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
8347 : } else {
8348 : // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
8349 : // same
8350 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
8351 : }
8352 : }
8353 :
8354 : // Following call determines inside surface temperature of glazing, and of
8355 : // frame and/or divider, if present
8356 924325 : Window::CalcWindowHeatBalance(
8357 924325 : state, SurfNum, state.dataHeatBalSurf->SurfHConvExt(SurfNum), state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TH11);
8358 924325 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8359 : }
8360 : }
8361 3094005 : } // ...end of inside surface heat balance equation selection
8362 :
8363 47102489 : for (int SurfNum : HTSurfs) {
8364 44008484 : int const ZoneNum = state.dataSurface->Surface(SurfNum).Zone;
8365 44008484 : auto &zone = state.dataHeatBal->Zone(ZoneNum);
8366 44008484 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
8367 44008484 : Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
8368 44008484 : TH12 = state.dataHeatBalSurf->SurfTempIn(SurfNum);
8369 44008484 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = TH11; // For reporting
8370 44008484 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Dome) {
8371 0 : continue;
8372 : }
8373 44008484 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8374 : // Tubular daylighting devices are treated as one big object with an effective R value.
8375 : // The outside face temperature of the TDD:DOME and the inside face temperature of the
8376 : // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
8377 : // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
8378 : // and the outside face of the TDD:DIFFUSER for reporting.
8379 :
8380 : // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
8381 0 : int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
8382 0 : state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
8383 0 : state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
8384 :
8385 : // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
8386 : // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
8387 0 : TH11 = state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
8388 0 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
8389 : }
8390 :
8391 44008484 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
8392 0 : TestSurfTempCalcHeatBalanceInsideSurf(state, TH12, SurfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
8393 : }
8394 :
8395 3094005 : } // ...end of main loops over all surfaces for inside heat balances
8396 :
8397 : // Interzone surface updating: interzone surfaces have other side temperatures
8398 : // which can vary as the simulation iterates through the inside heat
8399 : // balance. This block is intended to "lock" the opposite side (outside)
8400 : // temperatures to the correct value, namely the value calculated by the
8401 : // inside surface heat balance for the other side.
8402 : // assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
8403 : // int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
8404 22234717 : for (int SurfNum : IZSurfs) {
8405 19140712 : int const surfExtBoundCond = state.dataSurface->Surface(SurfNum).ExtBoundCond;
8406 : // Set the outside surface temperature to the inside surface temperature of the interzone pair.
8407 : // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
8408 : // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
8409 : // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
8410 19140712 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
8411 19140712 : state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
8412 3094005 : }
8413 :
8414 3094005 : ++state.dataHeatBal->InsideSurfIterations;
8415 :
8416 : // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
8417 3094005 : Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
8418 43739600 : for (int SurfNum : HTNonWindowSurfs) {
8419 40645595 : MaxDelTemp = max(std::abs(state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfTempInsOld(SurfNum)), MaxDelTemp);
8420 40645595 : if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
8421 : // also check all internal nodes as well as surface faces
8422 10240031 : MaxDelTemp = max(MaxDelTemp, state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).MaxNodeDelTemp);
8423 : }
8424 3094005 : } // ...end of loop to check for convergence
8425 :
8426 3094005 : if (!state.dataHeatBal->AnyCondFD) {
8427 2082927 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) {
8428 688318 : Converged = true;
8429 : }
8430 : } else {
8431 1011078 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTempCondFD) {
8432 369583 : Converged = true;
8433 : }
8434 :
8435 : // resets relaxation factor to speed up iterations when under-relaxation is not needed.
8436 1011078 : if (state.dataHeatBal->InsideSurfIterations <= 1) {
8437 351700 : state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
8438 : }
8439 1011078 : if ((state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::IterationsForCondFDRelaxChange) && !Converged) {
8440 : // adjust relaxation factor down, assume large number of iterations is result of instability
8441 1739 : state.dataHeatBal->CondFDRelaxFactor *= 0.9;
8442 1739 : if (state.dataHeatBal->CondFDRelaxFactor < 0.1) {
8443 1277 : state.dataHeatBal->CondFDRelaxFactor = 0.1;
8444 : }
8445 : }
8446 : }
8447 :
8448 : #ifdef EP_Count_Calls
8449 : state.dataTimingsData->NumMaxInsideSurfIterations =
8450 : max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
8451 : #endif
8452 :
8453 3094005 : if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) {
8454 39240 : Converged = false;
8455 : }
8456 :
8457 3094005 : if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
8458 0 : if (!state.dataGlobal->WarmupFlag) {
8459 0 : ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
8460 0 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
8461 0 : if (!state.dataHeatBal->AnyCondFD) {
8462 0 : ShowWarningError(state,
8463 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
8464 : "Allowed Temp Diff [C] ={:.3R}",
8465 : MaxDelTemp,
8466 0 : state.dataHeatBal->MaxAllowedDelTemp));
8467 0 : ShowContinueErrorTimeStamp(state, "");
8468 : } else {
8469 0 : ShowWarningError(state,
8470 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
8471 : "Allowed Temp Diff [C] ={:.6R}",
8472 : MaxDelTemp,
8473 0 : state.dataHeatBal->MaxAllowedDelTempCondFD));
8474 0 : ShowContinueErrorTimeStamp(state, "");
8475 : }
8476 : } else {
8477 0 : ShowRecurringWarningErrorAtEnd(state,
8478 : "Inside surface heat balance convergence problem continues",
8479 0 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
8480 : MaxDelTemp,
8481 : MaxDelTemp,
8482 : _,
8483 : "[C]",
8484 : "[C]");
8485 : }
8486 : }
8487 0 : break; // iteration loop
8488 : }
8489 :
8490 : } // ...end of main inside heat balance DO loop (ends when Converged)
8491 :
8492 : // Update SumHmXXXX for non-window EMPD or HAMT surfaces
8493 1039098 : if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
8494 :
8495 : // these SumHmA* variables are only used for EMPD and HAMT and should be reset each time step (and every iteration)
8496 94956 : for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
8497 54963 : thisZoneHB.SumHmAW = 0.0;
8498 54963 : thisZoneHB.SumHmARa = 0.0;
8499 54963 : thisZoneHB.SumHmARaW = 0.0;
8500 39993 : }
8501 :
8502 381747 : for (int SurfNum : HTNonWindowSurfs) {
8503 341754 : auto const &surface = state.dataSurface->Surface(SurfNum);
8504 341754 : int ZoneNum = surface.Zone;
8505 341754 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
8506 :
8507 341754 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8508 171564 : HeatBalanceHAMTManager::UpdateHeatBalHAMT(state, SurfNum);
8509 :
8510 171564 : Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
8511 :
8512 171564 : thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
8513 :
8514 171564 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).MAT);
8515 514692 : RhoAirZone = Psychrometrics::PsyRhoAirFnPbTdbW(
8516 : state,
8517 171564 : state.dataEnvrn->OutBaroPress,
8518 : MAT_zone,
8519 171564 : Psychrometrics::PsyWFnTdbRhPb(
8520 : state,
8521 : MAT_zone,
8522 171564 : Psychrometrics::PsyRhFnTdbRhov(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum), rhoAirZone),
8523 171564 : state.dataEnvrn->OutBaroPress));
8524 :
8525 171564 : Real64 const surfInTemp(state.dataHeatBalSurf->SurfTempInTmp(SurfNum));
8526 : Wsurf =
8527 343128 : Psychrometrics::PsyWFnTdbRhPb(state,
8528 : surfInTemp,
8529 171564 : Psychrometrics::PsyRhFnTdbRhov(state, surfInTemp, state.dataMstBal->RhoVaporSurfIn(SurfNum), wsurf),
8530 171564 : state.dataEnvrn->OutBaroPress);
8531 :
8532 171564 : thisZoneHB.SumHmARa += FD_Area_fac * RhoAirZone;
8533 :
8534 171564 : thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); // old eq'n: FD_Area_fac * RhoAirZone * Wsurf;
8535 :
8536 170190 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
8537 : // need to calculate the amount of moisture that is entering or
8538 : // leaving the zone Qm [kg/sec] = hmi * Area * (Del Rhov)
8539 : // {Hmi [m/sec]; Area [m2]; Rhov [kg moist/m3] }
8540 : // Positive values are into the zone and negative values are
8541 : // leaving the zone. SumHmAw is the sum of the moisture entering or
8542 : // leaving the zone from all of the surfaces and is a rate. Multiply
8543 : // by time to get the actual amount affecting the zone volume of air.
8544 :
8545 150018 : MoistureBalanceEMPDManager::UpdateMoistureBalanceEMPD(state, SurfNum);
8546 150018 : state.dataMstBal->RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum);
8547 150018 : Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
8548 150018 : thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
8549 150018 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
8550 150018 : thisZoneHB.SumHmARa +=
8551 150018 : FD_Area_fac *
8552 450054 : Psychrometrics::PsyRhoAirFnPbTdbW(
8553 : state,
8554 150018 : state.dataEnvrn->OutBaroPress,
8555 : MAT_zone,
8556 150018 : Psychrometrics::PsyWFnTdbRhPb(state,
8557 : MAT_zone,
8558 150018 : Psychrometrics::PsyRhFnTdbRhovLBnd0C(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum)),
8559 150018 : state.dataEnvrn->OutBaroPress)); // surfInTemp, PsyWFnTdbRhPb( surfInTemp, PsyRhFnTdbRhovLBnd0C(
8560 : // surfInTemp, RhoVaporAirIn( SurfNum ) ), OutBaroPress ) );
8561 150018 : thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum);
8562 : }
8563 39993 : }
8564 : }
8565 1039098 : }
8566 :
8567 2721446 : void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state,
8568 : const int FirstZone, // First zone to simulate
8569 : const int LastZone, // Last zone to simulate
8570 : const std::vector<int> &IZSurfs, // Last zone to simulate
8571 : ObjexxFCL::Optional_int_const ZoneToResimulate)
8572 : {
8573 :
8574 : // This function performs a heat balance on the inside face of each
8575 : // surface in the building. It is a copy of CalcHeatBalanceInsideSurf,
8576 : // simplified for CTF surfaces only.
8577 :
8578 : // REFERENCES:
8579 : // (I)BLAST legacy routine HBSRF
8580 :
8581 2721446 : auto &s_mat = state.dataMaterial;
8582 2721446 : auto &Surface = state.dataSurface->Surface;
8583 :
8584 2721446 : constexpr std::string_view Inside("Inside");
8585 :
8586 2721446 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime) {
8587 : // Set up coefficient arrays that never change - loop over non-window HT surfaces
8588 5889 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8589 10238 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8590 5125 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8591 5125 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8592 5125 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8593 43679 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8594 38554 : int const ConstrNum = Surface(surfNum).Construction;
8595 38554 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8596 38554 : if (Surface(surfNum).ExtBoundCond == surfNum) {
8597 6938 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 1;
8598 : } else {
8599 31616 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 0;
8600 : }
8601 38554 : if (construct.SourceSinkPresent) {
8602 127 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 1;
8603 : } else {
8604 38427 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 0;
8605 : }
8606 : }
8607 5113 : }
8608 : }
8609 :
8610 776 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime = false;
8611 : }
8612 :
8613 23236909 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8614 41079526 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8615 20564063 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8616 : // loop over all heat transfer surface except TDD Dome.
8617 20564063 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
8618 20564063 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
8619 : // determine reference air temperatures and other variable terms - loop over all surfaces
8620 197514869 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8621 176950806 : auto const &surface = Surface(surfNum);
8622 176950806 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8623 397773 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8624 397773 : if (surfNum != repSurfNum) {
8625 89997 : continue;
8626 : }
8627 : }
8628 :
8629 176860809 : int const ConstrNum = Surface(surfNum).Construction;
8630 176860809 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8631 176860809 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) = construct.CTFCross[0];
8632 176860809 : state.dataHeatBalSurf->SurfCTFInside0(surfNum) = construct.CTFInside[0];
8633 176860809 : state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) = construct.CTFSourceIn[0];
8634 176860809 : state.dataHeatBalSurf->SurfTempOutHist(surfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
8635 176860809 : if (construct.SourceSinkPresent) {
8636 791424 : state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) = state.dataHeatBalSurf->SurfQsrcHist(surfNum, 1);
8637 : }
8638 :
8639 : // The special heat balance terms for pools are used only when the pool is operating, so IsPool can change
8640 176860809 : if (state.dataSurface->SurfIsPool(surfNum)) {
8641 51624 : if ((std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit) ||
8642 8092 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit)) {
8643 35440 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 1;
8644 : } else {
8645 8092 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 0;
8646 : }
8647 : }
8648 176860809 : Real64 RefAirTemp = state.dataSurface->Surface(surfNum).getInsideAirTemperature(state, surfNum);
8649 176860809 : state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = RefAirTemp;
8650 176860809 : state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(surfNum);
8651 : }
8652 :
8653 : // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
8654 : // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
8655 : // CalcWindowHeatBalance.
8656 : // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
8657 20564063 : int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
8658 20564063 : int const lastWindowSurf = thisSpace.WindowSurfaceLast;
8659 44466425 : for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
8660 23902362 : state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
8661 23902362 : state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
8662 23902362 : state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
8663 23902362 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
8664 23902362 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
8665 23902362 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
8666 23902362 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
8667 23902362 : state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
8668 23902362 : state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
8669 23902362 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
8670 23902362 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
8671 23902362 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
8672 23902362 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
8673 : }
8674 :
8675 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
8676 20589209 : for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
8677 25146 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
8678 25146 : state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
8679 20564063 : }
8680 :
8681 : // Set up coefficient arrays prior to calculations and precalc terms that do no change during iteration - non-window surfaces
8682 20564063 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8683 20564063 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8684 20564063 : Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
8685 20564063 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8686 : // this loop auto-vectorizes
8687 173612507 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8688 153048444 : auto const &surface = Surface(surfNum);
8689 153048444 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8690 275487 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8691 275487 : if (surfNum != repSurfNum) {
8692 11679 : continue;
8693 : }
8694 : }
8695 :
8696 : // Pre-calculate a few terms before the iteration loop
8697 153036765 : state.dataHeatBalSurf->SurfTempTerm(surfNum) =
8698 153036765 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8699 153036765 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8700 153036765 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8701 153036765 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8702 153036765 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
8703 153036765 : state.dataHeatBalSurf->SurfTempDiv(surfNum) =
8704 153036765 : 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
8705 153036765 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
8706 153036765 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
8707 153036765 : (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant);
8708 : }
8709 20515463 : }
8710 : }
8711 :
8712 2721446 : state.dataHeatBal->InsideSurfIterations = 0;
8713 2721446 : bool Converged = false; // .TRUE. if inside heat balance has converged
8714 13800220 : while (!Converged) { // Start of main inside heat balance iteration loop...
8715 :
8716 11078774 : state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
8717 :
8718 22157548 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
8719 11078774 : state.dataHeatBalSurf->SurfTempIn,
8720 11078774 : state.dataHeatBal->InsideSurfIterations,
8721 11078774 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
8722 : ZoneToResimulate,
8723 : Inside); // Update the radiation balance
8724 :
8725 : // Every 30 iterations, recalculate the inside convection coefficients in case
8726 : // there has been a significant drift in the surface temperatures predicted.
8727 : // This is not fool-proof and it basically means that the outside surface
8728 : // heat balance is in error (potentially) once HConvIn is re-evaluated.
8729 : // The choice of 30 is not significant--just want to do this a couple of
8730 : // times before the iteration limit is hit.
8731 19436102 : if ((state.dataHeatBal->InsideSurfIterations > 0) &&
8732 8357328 : (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
8733 1787 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
8734 : // Since HConvIn has changed re-calculate a few terms - non-window surfaces
8735 13687 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8736 23800 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8737 11900 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8738 11900 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8739 11900 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8740 :
8741 11900 : Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
8742 11900 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8743 : // this loop auto-vectorizes
8744 103816 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8745 91916 : auto const &surface = Surface(surfNum);
8746 91916 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8747 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8748 0 : if (surfNum != repSurfNum) {
8749 0 : continue;
8750 : }
8751 : }
8752 :
8753 91916 : state.dataHeatBalSurf->SurfTempTerm(surfNum) =
8754 91916 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8755 91916 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8756 91916 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8757 91916 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8758 91916 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
8759 91916 : state.dataHeatBalSurf->SurfTempDiv(surfNum) =
8760 91916 : 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
8761 91916 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
8762 91916 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
8763 91916 : (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) +
8764 : iterDampConstant);
8765 : }
8766 11900 : }
8767 : }
8768 : }
8769 :
8770 : // Loop over non-window surfaces
8771 106704040 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8772 191476752 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8773 95851486 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8774 95851486 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8775 95851486 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8776 95851486 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8777 : // this loop auto-vectorizes
8778 814956717 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8779 : // Perform heat balance on the inside face of the surface ...
8780 : // The following are possibilities here (this function only does CTF, see CalcHeatBalanceInsideSurf2 for others):
8781 : // (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
8782 : // (b) the surface is adiabatic (a partition), in which case the temperature of both sides are the same
8783 : // (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
8784 : // (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
8785 : // (e) standard opaque surface with movable insulation, special two-part equation
8786 : // In the surface calculation there are the following Algorithm types for opaque surfaces that
8787 : // do not have movable insulation:
8788 : // (a) the regular CTF calc (SolutionAlgo = UseCTF)
8789 : // (b) the EMPD calc (Solutionalgo = UseEMPD)
8790 : // (c) the CondFD calc (SolutionAlgo = UseCondFD)
8791 : // (d) the HAMT calc (solutionalgo = UseHAMT).
8792 :
8793 : // For adiabatic surface:
8794 : // Adiabatic: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] + HConvIn_surf + IterDampConst));
8795 : // Adiabatic: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
8796 : // Ad+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst *
8797 : // SurfTempInsOld(SurfNum)) * TempDiv; Ad+Pool: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] +
8798 : // PoolHeatTransCoefs(SurfNum) + IterDampConst); Ad+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) +
8799 : // QPoolSurfNumerator(SurfNum) + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
8800 :
8801 : // For standard or interzone surface:
8802 : // Standard: TempDiv = (1.0 / (construct.CTFInside(0) + HConvIn_surf + IterDampConst));
8803 : // Standard: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) *
8804 : // TempDiv; Std+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst
8805 : // * SurfTempInsOld(SurfNum)) * TempDiv; Std+Pool: TempDiv = (1.0 / (construct.CTFInside(0) + PoolHeatTransCoefs(SurfNum) +
8806 : // IterDampConst); Std+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + QPoolSurfNumerator(SurfNum) +
8807 : // IterDampConst* SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) * TempDiv;
8808 :
8809 : // Composite with Adiabatic/Source/Pool flags:
8810 : // TempDiv = (1.0 / (construct.CTFInside(0) - SurfIsAdiabatic*construct.CTFCross[0]+
8811 : // SurfIsOperatingPool*PoolHeatTransCoefs(SurfNum) + IsNotPoolSurf*HConvIn_surf + IterDampConst));
8812 : // SurfTempInTmp(SurfNum) = (IsNotPoolSurf*TempTerm + IsSource*construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) +
8813 : // SurfIsOperatingPool*SurfCTFConstInPart(SurfNum) + SurfIsOperatingPool*QPoolSurfNumerator(SurfNum)
8814 : // + IterDampConst * SurfTempInsOld(SurfNum)+
8815 : // IsNotAdiabatic*IsNotSource*construct.CTFCross[0]
8816 : // * TH11) * TempDiv;
8817 :
8818 : // Calculate the current inside surface temperature
8819 719105231 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8820 719105231 : ((!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) *
8821 719105231 : (state.dataHeatBalSurf->SurfTempTerm(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum)) +
8822 719105231 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) * state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) *
8823 719105231 : state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) +
8824 719105231 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) +
8825 719105231 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum) +
8826 719105231 : iterDampConstant * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
8827 719105231 : (!state.dataHeatBalSurf->SurfIsAdiabatic(surfNum)) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) *
8828 719105231 : state.dataHeatBalSurf->SurfTempOutHist(surfNum)) *
8829 719105231 : state.dataHeatBalSurf->SurfTempDiv(surfNum);
8830 : // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
8831 : // radiation from internal sources | Convection from surface to zone air | Net radiant
8832 : // exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there
8833 : // is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot
8834 : // water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from
8835 : // an electric baseboard heater | Iterative damping term (for stability) | Current
8836 : // conduction from | the outside surface | Coefficient for conduction (current time) |
8837 : // Convection and damping term | Radiation from AFN ducts
8838 :
8839 719105231 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
8840 : }
8841 :
8842 : // Loop over non-window surfaces (includes TubularDaylightingDomes)
8843 814956717 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8844 719105231 : auto &movInsul = state.dataSurface->intMovInsuls(surfNum);
8845 :
8846 719105231 : bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && movInsul.present;
8847 719105231 : if (movableInsulPresent) { // Movable insulation present, recalc surface temps
8848 16981 : Real64 HMovInsul = movInsul.H;
8849 16981 : Real64 F1 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvInt(surfNum) + DataHeatBalSurface::IterDampConst);
8850 16981 : state.dataHeatBalSurf->SurfTempIn(surfNum) =
8851 16981 : (state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
8852 16981 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum) +
8853 16981 : F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8854 16981 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8855 16981 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8856 16981 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8857 16981 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8858 16981 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum))) /
8859 16981 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
8860 :
8861 16981 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8862 16981 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum) +
8863 16981 : HMovInsul * state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) -
8864 16981 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) -
8865 16981 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum)) /
8866 : (HMovInsul);
8867 : }
8868 :
8869 719105231 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
8870 12269820 : if (state.dataConstruction->Construct(Surface(surfNum).Construction).SourceSinkPresent) {
8871 : // Set the appropriate parameters for the radiant system
8872 : // Radiant system does not need the damping coefficient terms (hopefully)
8873 : Real64 const RadSysDiv(1.0 /
8874 2445348 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + state.dataHeatBalSurf->SurfHConvInt(surfNum)));
8875 : Real64 const TempTerm(
8876 2445348 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8877 2445348 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
8878 2445348 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8879 2445348 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8880 2445348 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8881 2445348 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / state.dataGlobal->TimeStepZoneSec));
8882 2445348 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum) =
8883 2445348 : TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
8884 : // radiation from internal sources | Convection from surface to zone air | Radiant flux
8885 : // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
8886 : // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
8887 : // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
8888 : // sides same temp) | Convection and damping term
8889 2445348 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum) =
8890 2445348 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * RadSysDiv; // Outside temp=inside temp for a partition |
8891 : // Cond term (both partition sides same temp) |
8892 : // Convection and damping term
8893 2445348 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum) =
8894 2445348 : state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * RadSysDiv; // QTF term for the source | Cond term (both
8895 : // partition sides same temp) | Convection and
8896 : // damping term
8897 :
8898 2445348 : if (Surface(surfNum).ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
8899 : // The inside coefficients of one side are equal to the outside coefficients of the other side. But,
8900 : // the inside coefficients are set up once the heat balance equation for that side has been calculated.
8901 : // For both sides to actually have been set, we have to wait until we get to the second side in the surface
8902 : // derived type. At that point, both inside coefficient sets have been evaluated.
8903 968842 : if (Surface(surfNum).ExtBoundCond <= surfNum) { // Both of the inside coefficients have now been set
8904 484421 : int OtherSideSurfNum = Surface(surfNum).ExtBoundCond;
8905 484421 : state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
8906 484421 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum);
8907 484421 : state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
8908 484421 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum);
8909 484421 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
8910 484421 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum);
8911 484421 : state.dataHeatBalFanSys->RadSysToHBConstCoef(surfNum) =
8912 484421 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
8913 484421 : state.dataHeatBalFanSys->RadSysToHBTinCoef(surfNum) =
8914 484421 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
8915 484421 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(surfNum) =
8916 484421 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
8917 : }
8918 : }
8919 : }
8920 : }
8921 : }
8922 :
8923 : // Loop over window surfaces
8924 95851486 : int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
8925 95851486 : int const lastWindowSurf = thisSpace.WindowSurfaceLast;
8926 205669911 : for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
8927 109818425 : auto &surface = state.dataSurface->Surface(surfNum);
8928 109818425 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8929 400322 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8930 400322 : if (surfNum != repSurfNum) {
8931 256386 : continue;
8932 : }
8933 : }
8934 109562039 : Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum));
8935 109562039 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(surfNum);
8936 109562039 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8937 109562039 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8938 : // Lookup up the TDD:DOME object
8939 20832 : int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
8940 20832 : int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
8941 : // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
8942 20832 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
8943 :
8944 : // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
8945 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
8946 : // = SurfWinQRadSWwinAbs(surfNum,1)/2.0
8947 20832 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surfNum));
8948 20832 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8949 20832 : (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, 1) / 2.0 +
8950 20832 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8951 20832 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8952 20832 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8953 20832 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
8954 20832 : Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
8955 20832 : (Ueff + HConvIn_surf +
8956 : DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
8957 : // solar | Convection from surface to zone air | Net radiant exchange with
8958 : // other zone surfaces | Iterative damping term (for stability) | Current
8959 : // conduction from the outside surface | Coefficient for conduction (current
8960 : // time) | Convection and damping term
8961 20832 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
8962 20832 : Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(surfNum) + Constant::Kelvin));
8963 :
8964 : // fill out report vars for components of Window Heat Gain
8965 20832 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
8966 41664 : HConvIn_surf * surface.Area *
8967 20832 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
8968 20832 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
8969 20832 : state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
8970 20832 : (Sigma_Temp_4 -
8971 20832 : (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum)));
8972 20832 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
8973 20832 : state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
8974 20832 : (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
8975 20832 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(surfNum);
8976 :
8977 : // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
8978 20832 : state.dataSurface->SurfWinHeatGain(surfNum) =
8979 20832 : state.dataSurface->SurfWinTransSolar(surfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) +
8980 20832 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) -
8981 20832 : surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum);
8982 : // Net transmitted solar | Convection | IR exchange | IR
8983 : // Zone diffuse interior shortwave reflected back into the TDD
8984 : } else { // Regular window
8985 109541207 : if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
8986 : // Get outside convection coeff for exterior window here to avoid calling
8987 : // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
8988 : // (HeatBalanceSurfaceManager USEing and WindowManager and
8989 : // WindowManager USEing HeatBalanceSurfaceManager)
8990 23819994 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
8991 23792802 : auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
8992 23792802 : assert(thisMaterial != nullptr);
8993 23792802 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
8994 23792802 : Real64 EmisOut = thisMaterial->AbsorpThermalFront; // Glass outside surface emissivity
8995 23792802 : DataSurfaces::WinShadingType const shading_flag = state.dataSurface->SurfWinShadingFlag(surfNum);
8996 23792802 : if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
8997 : // Exterior shade in place
8998 31665 : int const ConstrNumSh = Surface(surfNum).activeShadedConstruction;
8999 31665 : if (ConstrNumSh != 0) {
9000 21522 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
9001 21522 : auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
9002 21522 : RoughSurf = thisMaterial2->Roughness;
9003 21522 : EmisOut = thisMaterial2->AbsorpThermal;
9004 : }
9005 : }
9006 :
9007 : // Get the outside effective emissivity for Equivalent layer model
9008 23792802 : if (construct.WindowTypeEQL) {
9009 8109 : EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
9010 : }
9011 : // Set Exterior Convection Coefficient...
9012 23792802 : if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
9013 :
9014 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
9015 :
9016 23792802 : } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
9017 :
9018 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
9019 : // subroutine)
9020 23792802 : Convect::InitExtConvCoeff(state,
9021 : surfNum,
9022 : 0.0,
9023 : RoughSurf,
9024 : EmisOut,
9025 : TH11,
9026 23792802 : state.dataHeatBalSurf->SurfHConvExt(surfNum),
9027 23792802 : state.dataHeatBalSurf->SurfHSkyExt(surfNum),
9028 23792802 : state.dataHeatBalSurf->SurfHGrdExt(surfNum),
9029 23792802 : state.dataHeatBalSurf->SurfHAirExt(surfNum),
9030 23792802 : state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
9031 :
9032 23792802 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
9033 5882 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = 1000.0; // Reset SurfHcExt because of wetness
9034 : }
9035 :
9036 : } else { // Not Wind exposed
9037 :
9038 : // Calculate exterior heat transfer coefficients for windspeed = 0
9039 0 : Convect::InitExtConvCoeff(state,
9040 : surfNum,
9041 : 0.0,
9042 : RoughSurf,
9043 : EmisOut,
9044 : TH11,
9045 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum),
9046 0 : state.dataHeatBalSurf->SurfHSkyExt(surfNum),
9047 0 : state.dataHeatBalSurf->SurfHGrdExt(surfNum),
9048 0 : state.dataHeatBalSurf->SurfHAirExt(surfNum),
9049 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
9050 : }
9051 :
9052 : } else { // Interior Surface
9053 :
9054 27192 : if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
9055 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
9056 : } else {
9057 : // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
9058 : // same
9059 27192 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
9060 : }
9061 : }
9062 :
9063 : // Following call determines inside surface temperature of glazing, and of
9064 : // frame and/or divider, if present
9065 23819994 : Window::CalcWindowHeatBalance(
9066 23819994 : state, surfNum, state.dataHeatBalSurf->SurfHConvExt(surfNum), state.dataHeatBalSurf->SurfTempInTmp(surfNum), TH11);
9067 23819994 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
9068 : }
9069 : }
9070 : }
9071 :
9072 95851486 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
9073 95851486 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
9074 924775142 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
9075 828923656 : auto &zone = state.dataHeatBal->Zone(zoneNum);
9076 :
9077 828923656 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
9078 828923656 : Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(surfNum);
9079 828923656 : TH12 = state.dataHeatBalSurf->SurfTempIn(surfNum);
9080 828923656 : state.dataHeatBalSurf->SurfTempOut(surfNum) = TH11; // For reporting
9081 828923656 : if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
9082 : // Tubular daylighting devices are treated as one big object with an effective R value.
9083 : // The outside face temperature of the TDD:DOME and the inside face temperature of the
9084 : // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
9085 : // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
9086 : // and the outside face of the TDD:DIFFUSER for reporting.
9087 :
9088 : // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
9089 20832 : int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(surfNum)).Dome;
9090 20832 : state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
9091 20832 : state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(surfNum);
9092 :
9093 : // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
9094 : // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
9095 20832 : TH11 = state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
9096 20832 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
9097 : }
9098 :
9099 828923656 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
9100 0 : TestSurfTempCalcHeatBalanceInsideSurf(
9101 0 : state, TH12, surfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
9102 : }
9103 : }
9104 95625266 : }
9105 : } // ...end of main loops over all surfaces for inside heat balances
9106 :
9107 : // Interzone surface updating: interzone surfaces have other side temperatures
9108 : // which can vary as the simulation iterates through the inside heat
9109 : // balance. This block is intended to "lock" the opposite side (outside)
9110 : // temperatures to the correct value, namely the value calculated by the
9111 : // inside surface heat balance for the other side.
9112 : // assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
9113 : // int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
9114 339526690 : for (int SurfNum : IZSurfs) {
9115 328447916 : int const surfExtBoundCond = Surface(SurfNum).ExtBoundCond;
9116 : // Set the outside surface temperature to the inside surface temperature of the interzone pair.
9117 : // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
9118 : // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
9119 : // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
9120 328447916 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
9121 328447916 : state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
9122 328447916 : state.dataHeatBalSurf->SurfTempOutHist(SurfNum) = state.dataHeatBalSurf->SurfTempOut(SurfNum);
9123 11078774 : }
9124 :
9125 11078774 : ++state.dataHeatBal->InsideSurfIterations;
9126 :
9127 : // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
9128 11078774 : Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
9129 106704040 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
9130 191476752 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
9131 95851486 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
9132 95851486 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
9133 95851486 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
9134 814956717 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
9135 719105231 : Real64 delta = state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfTempInsOld(surfNum);
9136 719105231 : Real64 absDif = std::abs(delta);
9137 719105231 : MaxDelTemp = std::max(absDif, MaxDelTemp);
9138 : }
9139 95625266 : }
9140 : } // ...end of loop to check for convergence
9141 :
9142 11078774 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) {
9143 2721446 : Converged = true;
9144 : }
9145 :
9146 : #ifdef EP_Count_Calls
9147 : state.dataTimingsData->NumMaxInsideSurfIterations =
9148 : max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
9149 : #endif
9150 :
9151 11078774 : if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) {
9152 0 : Converged = false;
9153 : }
9154 :
9155 11078774 : if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
9156 0 : if (!state.dataGlobal->WarmupFlag) {
9157 0 : ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
9158 0 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
9159 0 : ShowWarningError(state,
9160 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max Allowed "
9161 : "Temp Diff [C] ={:.6R}",
9162 : MaxDelTemp,
9163 0 : state.dataHeatBal->MaxAllowedDelTempCondFD));
9164 0 : ShowContinueErrorTimeStamp(state, "");
9165 : } else {
9166 0 : ShowRecurringWarningErrorAtEnd(state,
9167 : "Inside surface heat balance convergence problem continues",
9168 0 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
9169 : MaxDelTemp,
9170 : MaxDelTemp,
9171 : _,
9172 : "[C]",
9173 : "[C]");
9174 : }
9175 : }
9176 0 : break; // iteration loop
9177 : }
9178 :
9179 : } // ...end of main inside heat balance iteration loop (ends when Converged)
9180 2721446 : }
9181 :
9182 3760544 : void sumSurfQdotRadHVAC(EnergyPlusData &state)
9183 : {
9184 6901990 : for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
9185 3141446 : auto const &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
9186 3141446 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = thisSurfQRadFromHVAC.HTRadSys + thisSurfQRadFromHVAC.HWBaseboard +
9187 3141446 : thisSurfQRadFromHVAC.SteamBaseboard + thisSurfQRadFromHVAC.ElecBaseboard +
9188 3141446 : thisSurfQRadFromHVAC.CoolingPanel;
9189 3760544 : }
9190 3760544 : }
9191 :
9192 0 : void TestSurfTempCalcHeatBalanceInsideSurf(EnergyPlusData &state, Real64 TH12, int const SurfNum, DataHeatBalance::ZoneData &zone, int WarmupSurfTemp)
9193 : {
9194 0 : std::string surfName = state.dataSurface->Surface(SurfNum).Name;
9195 :
9196 0 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
9197 0 : if (state.dataGlobal->WarmupFlag) {
9198 0 : ++WarmupSurfTemp;
9199 : }
9200 0 : if (!state.dataGlobal->WarmupFlag || WarmupSurfTemp > 10 || state.dataGlobal->DisplayExtraWarnings) {
9201 0 : if (TH12 < DataHeatBalSurface::MinSurfaceTempLimit) {
9202 0 : if (state.dataSurface->SurfLowTempErrCount(SurfNum) == 0) {
9203 0 : ShowSevereMessage(
9204 0 : state, format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9205 0 : ShowContinueErrorTimeStamp(state, "");
9206 0 : if (!zone.TempOutOfBoundsReported) {
9207 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9208 0 : if (zone.FloorArea > 0.0) {
9209 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9210 : } else {
9211 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
9212 : }
9213 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9214 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9215 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9216 : } else {
9217 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9218 : }
9219 0 : if (zone.IsControlled) {
9220 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9221 : } else {
9222 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9223 : }
9224 0 : zone.TempOutOfBoundsReported = true;
9225 : }
9226 0 : ShowRecurringSevereErrorAtEnd(state,
9227 0 : "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9228 0 : state.dataSurface->SurfLowTempErrCount(SurfNum),
9229 : TH12,
9230 : TH12,
9231 : _,
9232 : "C",
9233 : "C");
9234 : } else {
9235 0 : ShowRecurringSevereErrorAtEnd(state,
9236 0 : "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9237 0 : state.dataSurface->SurfLowTempErrCount(SurfNum),
9238 : TH12,
9239 : TH12,
9240 : _,
9241 : "C",
9242 : "C");
9243 : }
9244 : } else {
9245 0 : if (state.dataSurface->SurfHighTempErrCount(SurfNum) == 0) {
9246 0 : ShowSevereMessage(
9247 0 : state, format(R"(Temperature (high) out of bounds ({:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9248 0 : ShowContinueErrorTimeStamp(state, "");
9249 0 : if (!zone.TempOutOfBoundsReported) {
9250 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9251 0 : if (zone.FloorArea > 0.0) {
9252 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9253 : } else {
9254 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
9255 : }
9256 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9257 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9258 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9259 : } else {
9260 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9261 : }
9262 0 : if (zone.IsControlled) {
9263 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9264 : } else {
9265 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9266 : }
9267 0 : zone.TempOutOfBoundsReported = true;
9268 : }
9269 0 : ShowRecurringSevereErrorAtEnd(state,
9270 0 : "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9271 0 : state.dataSurface->SurfHighTempErrCount(SurfNum),
9272 : TH12,
9273 : TH12,
9274 : _,
9275 : "C",
9276 : "C");
9277 : } else {
9278 0 : ShowRecurringSevereErrorAtEnd(state,
9279 0 : "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9280 0 : state.dataSurface->SurfHighTempErrCount(SurfNum),
9281 : TH12,
9282 : TH12,
9283 : _,
9284 : "C",
9285 : "C");
9286 : }
9287 : }
9288 0 : if (zone.EnforcedReciprocity) {
9289 0 : if (WarmupSurfTemp > 3) {
9290 0 : ShowSevereError(state, format("CalcHeatBalanceInsideSurf: Zone=\"{}\" has view factor enforced reciprocity", zone.Name));
9291 0 : ShowContinueError(state, " and is having temperature out of bounds errors. Please correct zone geometry and rerun.");
9292 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
9293 : }
9294 0 : } else if (WarmupSurfTemp > 10) {
9295 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
9296 : }
9297 : }
9298 : }
9299 0 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal)) {
9300 0 : if (!state.dataGlobal->WarmupFlag) {
9301 0 : if (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal) {
9302 0 : ShowSevereError(state,
9303 0 : format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9304 0 : ShowContinueErrorTimeStamp(state, "");
9305 0 : if (!zone.TempOutOfBoundsReported) {
9306 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9307 0 : if (zone.FloorArea > 0.0) {
9308 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9309 : } else {
9310 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
9311 : }
9312 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9313 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9314 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9315 : } else {
9316 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9317 : }
9318 0 : if (zone.IsControlled) {
9319 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9320 : } else {
9321 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9322 : }
9323 0 : zone.TempOutOfBoundsReported = true;
9324 : }
9325 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9326 : } else {
9327 0 : ShowSevereError(state,
9328 0 : format(R"(Temperature (high) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9329 0 : ShowContinueErrorTimeStamp(state, "");
9330 0 : if (!zone.TempOutOfBoundsReported) {
9331 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9332 0 : if (zone.FloorArea > 0.0) {
9333 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9334 : } else {
9335 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
9336 : }
9337 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9338 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9339 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9340 : } else {
9341 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9342 : }
9343 0 : if (zone.IsControlled) {
9344 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9345 : } else {
9346 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9347 : }
9348 0 : zone.TempOutOfBoundsReported = true;
9349 : }
9350 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9351 : }
9352 : } else {
9353 0 : if (TH12 < -10000. || TH12 > 10000.) {
9354 0 : ShowSevereError(
9355 : state,
9356 0 : format(R"(CalcHeatBalanceInsideSurf: The temperature of {:.2R} C for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9357 0 : ShowContinueError(state, "..is very far out of bounds during warmup. This may be an indication of a malformed zone.");
9358 0 : ShowContinueErrorTimeStamp(state, "");
9359 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9360 : }
9361 : }
9362 : }
9363 0 : }
9364 :
9365 44461694 : void CalcOutsideSurfTemp(EnergyPlusData &state,
9366 : int const SurfNum, // Surface number DO loop counter
9367 : int const spaceNum, // Space number the current surface is attached to
9368 : int const ConstrNum, // Construction index for the current surface
9369 : Real64 const HMovInsul, // "Convection" coefficient of movable insulation
9370 : Real64 const TempExt, // Exterior temperature boundary condition
9371 : bool &ErrorFlag // Error flag for movable insulation problem
9372 : )
9373 : {
9374 :
9375 : // SUBROUTINE INFORMATION:
9376 : // AUTHOR George Walton
9377 : // DATE WRITTEN December 1979
9378 : // MODIFIED Jun 1990 (RDT for new CTF arrays)
9379 : // Jul 2000 (RJL for Moisture algorithms)
9380 : // Sep 2000 (RKS for new radiant exchange algorithm)
9381 : // Dec 2000 (RKS for radiant system model addition)
9382 : // Aug 2010 (BG added radiant heat flow rate reporting)
9383 : // RE-ENGINEERED Mar 1998 (RKS)
9384 :
9385 : // PURPOSE OF THIS SUBROUTINE:
9386 : // This subroutine performs a heat balance on the outside face of each
9387 : // surface in the building. NOTE that this also sets some coefficients
9388 : // that are needed for radiant system modeling. Thus, it is extremely
9389 : // important that if someone makes changes to the heat balance equations
9390 : // at a later date that they must also make changes to the coefficient
9391 : // setting portion of this subroutine as well.
9392 :
9393 : // METHODOLOGY EMPLOYED:
9394 : // Various boundary conditions are set and additional parameters are set-
9395 : // up. Then, the proper heat balance equation is selected based on the
9396 : // presence of movable insulation, thermal mass of the surface construction,
9397 : // and convection model being used.
9398 :
9399 : // REFERENCES:
9400 : // (I)BLAST legacy routine HBOUT
9401 : // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
9402 :
9403 : // Determine whether or not movable insulation is present
9404 44461694 : bool MovInsulPresent = (HMovInsul > 0.0); // .TRUE. if movable insulation is currently present for surface
9405 : bool QuickConductionSurf; // .TRUE. if the cross CTF term is relatively large
9406 : Real64 F1; // Intermediate calculation variable
9407 : Real64 F2; // Intermediate calculation variable
9408 : // Determine whether this surface is a "slow conductive" or "quick conductive"
9409 : // surface. Designates are inherited from BLAST. Basically, a "quick" surface
9410 : // requires the inside heat balance to be accounted for in the heat balance
9411 : // while a "slow" surface can used the last time step's value for inside
9412 : // surface temperature.
9413 44461694 : auto &s_mat = state.dataMaterial;
9414 :
9415 44461694 : auto &surface = state.dataSurface->Surface(SurfNum);
9416 44461694 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
9417 44461694 : if (construct.CTFCross[0] > 0.01) {
9418 4891518 : QuickConductionSurf = true;
9419 4891518 : F1 = construct.CTFCross[0] / (construct.CTFInside[0] + state.dataHeatBalSurf->SurfHConvInt(SurfNum));
9420 : } else {
9421 39570176 : QuickConductionSurf = false;
9422 : }
9423 :
9424 44461694 : Real64 TSky = state.dataEnvrn->SkyTemp;
9425 44461694 : Real64 TGround = state.dataEnvrn->OutDryBulbTemp;
9426 44461694 : Real64 TSrdSurfs = 0.0;
9427 :
9428 44461694 : if (surface.SurfHasSurroundingSurfProperty) {
9429 5412 : int SrdSurfsNum = surface.SurfSurroundingSurfacesNum;
9430 5412 : if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched != nullptr) {
9431 0 : TSky = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched->getCurrentVal();
9432 : }
9433 5412 : if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched != nullptr) {
9434 0 : TGround = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched->getCurrentVal();
9435 : }
9436 5412 : TSrdSurfs = state.dataSurface->Surface(SurfNum).SrdSurfTemp;
9437 : }
9438 44461694 : if (surface.UseSurfPropertyGndSurfTemp) {
9439 8118 : TGround = state.dataSurface->GroundSurfsProperty(surface.SurfPropertyGndSurfIndex).SurfsTempAvg;
9440 : }
9441 :
9442 : // Now, calculate the outside surface temperature using the proper heat balance equation.
9443 : // Each case has been separated out into its own IF-THEN block for clarity. Additional
9444 : // cases can simply be added anywhere in the following section. This is the last step
9445 : // in the main loop. Once the proper heat balance is done, the simulation goes on to
9446 : // the next SurfNum.
9447 :
9448 : // Outside heat balance case: Tubular daylighting device
9449 44461694 : Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum));
9450 44461694 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
9451 :
9452 : // Lookup up the TDD:DIFFUSER object
9453 4050 : int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
9454 4050 : int SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser;
9455 4050 : int spaceNum2 = state.dataSurface->Surface(SurfNum2).spaceNum;
9456 4050 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(PipeNum).Reff; // 1 / effective R value between TDD:DOME and TDD:DIFFUSER
9457 4050 : F1 = Ueff / (Ueff + state.dataHeatBalSurf->SurfHConvInt(SurfNum2));
9458 :
9459 : // Similar to opaque surface but inside conditions of TDD:DIFFUSER are used, and no embedded sources/sinks.
9460 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
9461 : // SurfOpaqQRadSWOutAbs(SurfNum) does not apply for TDD:DOME, must use SurfWinQRadSWwinAbs(SurfNum,1)/2.0 instead.
9462 : //+Construct(ConstrNum)%CTFSourceOut[0] & TDDs cannot be radiant systems
9463 : // *SurfQsrcHist(1,SurfNum) &
9464 : //+Construct(ConstrNum)%CTFSourceIn[0] & TDDs cannot be radiant systems
9465 : // *SurfQsrcHist(1,SurfNum) &
9466 4050 : TH11 = (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
9467 4050 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9468 4050 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) +
9469 4050 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9470 4050 : F1 * (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum2, 1) / 2.0 + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum2) +
9471 4050 : state.dataHeatBalSurf->SurfHConvInt(SurfNum2) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum2).MAT +
9472 4050 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum2))) /
9473 4050 : (Ueff + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9474 4050 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9475 4050 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9476 4050 : F1 * Ueff); // Instead of SurfOpaqQRadSWOutAbs(SurfNum) | ODB used to approx ground surface temp | Use TDD:DIFFUSER surface | Use
9477 : // TDD:DIFFUSER surface | Use TDD:DIFFUSER surface and zone | Use TDD:DIFFUSER surface
9478 :
9479 : // Outside heat balance case: No movable insulation, slow conduction
9480 44457644 : } else if ((!MovInsulPresent) && (!QuickConductionSurf)) {
9481 : // Add LWR from surrounding surfaces
9482 39562079 : if (surface.OSCMPtr == 0) {
9483 39420464 : if (construct.SourceSinkPresent) {
9484 83175 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9485 83175 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9486 83175 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9487 83175 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9488 83175 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9489 83175 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
9490 83175 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9491 83175 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9492 83175 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
9493 : } else {
9494 39337289 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9495 39337289 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9496 39337289 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9497 39337289 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9498 39337289 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
9499 39337289 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9500 39337289 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9501 39337289 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
9502 : }
9503 : // Outside Heat Balance case: Other Side Conditions Model
9504 : } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
9505 : // local copies of variables for clarity in radiation terms
9506 : // TODO: - int OSCMPtr; // "Pointer" to OSCM data structure (other side conditions from a model)
9507 : Real64 RadTemp =
9508 141615 : state.dataSurface->OSCM(surface.OSCMPtr).TRad; // local value for Effective radiation temperature for OtherSideConditions model
9509 141615 : Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad; // local value for effective (linearized) radiation coefficient
9510 :
9511 : // patterned after "No movable insulation, slow conduction," but with new radiation terms and no sun,
9512 141615 : if (construct.SourceSinkPresent) {
9513 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9514 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9515 0 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9516 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
9517 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
9518 : } else {
9519 141615 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9520 141615 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9521 141615 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
9522 141615 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
9523 : }
9524 : }
9525 : // Outside heat balance case: No movable insulation, quick conduction
9526 44457644 : } else if ((!MovInsulPresent) && (QuickConductionSurf)) {
9527 4891518 : if (surface.OSCMPtr == 0) {
9528 4821318 : if (construct.SourceSinkPresent) {
9529 24140 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9530 24140 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9531 24140 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9532 24140 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9533 24140 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9534 24140 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9535 24140 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9536 24140 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9537 24140 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9538 24140 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9539 24140 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9540 24140 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9541 24140 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9542 24140 : F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
9543 : } else {
9544 4797178 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9545 4797178 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9546 4797178 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9547 4797178 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9548 4797178 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9549 4797178 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9550 4797178 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9551 4797178 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9552 4797178 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9553 4797178 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9554 4797178 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9555 4797178 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9556 4797178 : F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
9557 : }
9558 : // Outside Heat Balance case: Other Side Conditions Model
9559 : } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
9560 : // local copies of variables for clarity in radiation terms
9561 70200 : Real64 RadTemp = state.dataSurface->OSCM(surface.OSCMPtr).TRad;
9562 70200 : Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad;
9563 : // patterned after "No movable insulation, quick conduction," but with new radiation terms and no sun,
9564 70200 : if (construct.SourceSinkPresent) {
9565 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9566 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9567 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9568 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9569 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9570 0 : construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9571 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9572 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9573 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
9574 0 : F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
9575 : } else {
9576 70200 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9577 70200 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9578 70200 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9579 70200 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9580 70200 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9581 70200 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9582 70200 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
9583 70200 : F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
9584 : }
9585 : }
9586 : // Outside heat balance case: Movable insulation, slow conduction
9587 4895565 : } else if ((MovInsulPresent) && (!QuickConductionSurf)) {
9588 :
9589 4047 : F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9590 4047 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9591 4047 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
9592 :
9593 4047 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9594 4047 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9595 4047 : F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
9596 4047 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9597 4047 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9598 4047 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
9599 4047 : (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul); // ODB used to approx ground surface temp
9600 :
9601 : // Outside heat balance case: Movable insulation, quick conduction
9602 0 : } else if ((MovInsulPresent) && (QuickConductionSurf)) {
9603 :
9604 0 : F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9605 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9606 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
9607 :
9608 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9609 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9610 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9611 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9612 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)) +
9613 0 : F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
9614 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9615 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9616 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
9617 0 : (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul - F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp
9618 :
9619 : } // ...end of outside heat balance cases IF-THEN block
9620 :
9621 : // multiply out linearized radiation coeffs for reporting
9622 : Real64 const HExtSurf_fac(
9623 44461694 : -(state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * (TH11 - TSky) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) * (TH11 - TempExt) +
9624 44461694 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * (TH11 - TGround) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * (TH11 - TSrdSurfs)));
9625 44461694 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = HExtSurf_fac;
9626 :
9627 : // Set the radiant system heat balance coefficients if this surface is also a radiant system
9628 44461694 : if (construct.SourceSinkPresent) {
9629 :
9630 107315 : if (MovInsulPresent) {
9631 : // Note: if movable insulation is ever added back in correctly, the heat balance equations above must be fixed
9632 0 : ShowSevereError(state, "Exterior movable insulation is not valid with embedded sources/sinks");
9633 0 : ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
9634 0 : ShowContinueError(state,
9635 0 : format("exterior movable insulation {} for a surface with that construction.",
9636 0 : s_mat->materials(state.dataSurface->extMovInsuls(SurfNum).matNum)->Name));
9637 0 : ShowContinueError(state,
9638 : "This is not currently allowed because the heat balance equations do not currently accommodate this combination.");
9639 0 : ErrorFlag = true;
9640 0 : return;
9641 :
9642 : } else {
9643 107315 : Real64 const RadSysDiv(1.0 / (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) +
9644 107315 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) +
9645 107315 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) +
9646 107315 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)));
9647 :
9648 107315 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
9649 107315 : (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9650 107315 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9651 107315 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9652 107315 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround) *
9653 : RadSysDiv; // ODB used to approx ground surface temp
9654 :
9655 107315 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = construct.CTFCross[0] * RadSysDiv;
9656 :
9657 107315 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = construct.CTFSourceOut[0] * RadSysDiv;
9658 : }
9659 : }
9660 : }
9661 :
9662 8124 : void CalcExteriorVentedCavity(EnergyPlusData &state, int const SurfNum) // index of surface
9663 : {
9664 :
9665 : // SUBROUTINE INFORMATION:
9666 : // AUTHOR B Griffith
9667 : // DATE WRITTEN January 2005
9668 :
9669 : // PURPOSE OF THIS SUBROUTINE:
9670 : // manages calculating the temperatures of baffle and air cavity for
9671 : // multi-skin configuration.
9672 :
9673 : // METHODOLOGY EMPLOYED:
9674 : // derived from CalcPassiveTranspiredCollector
9675 :
9676 : // local working variables
9677 : Real64 HrPlen;
9678 : Real64 HcPlen;
9679 : Real64 Isc;
9680 : Real64 MdotVent;
9681 : Real64 VdotWind;
9682 : Real64 VdotThermal;
9683 :
9684 8124 : int CavNum = state.dataSurface->SurfExtCavNum(SurfNum);
9685 8124 : Real64 TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
9686 8124 : Real64 OutHumRatExt = Psychrometrics::PsyWFnTdbTwbPb(
9687 8124 : state, state.dataSurface->SurfOutDryBulbTemp(SurfNum), state.dataSurface->SurfOutWetBulbTemp(SurfNum), state.dataEnvrn->OutBaroPress);
9688 8124 : Real64 RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, OutHumRatExt);
9689 8124 : Real64 holeArea = state.dataHeatBal->ExtVentedCavity(CavNum).ActualArea * state.dataHeatBal->ExtVentedCavity(CavNum).Porosity;
9690 : // Aspect Ratio of gap
9691 8124 : Real64 AspRat = state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL * 2.0 / state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick;
9692 8124 : Real64 TmpTscoll = state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast;
9693 8124 : Real64 TmpTaPlen = state.dataHeatBal->ExtVentedCavity(CavNum).TairLast;
9694 :
9695 : // all the work is done in this routine located in GeneralRoutines.cc
9696 :
9697 32496 : for (int iter = 1; iter <= 3; ++iter) { // this is a sequential solution approach.
9698 :
9699 48744 : TranspiredCollector::CalcPassiveExteriorBaffleGap(state,
9700 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).SurfPtrs,
9701 : holeArea,
9702 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).Cv,
9703 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).Cd,
9704 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL,
9705 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).SolAbsorp,
9706 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).LWEmitt,
9707 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).Tilt,
9708 : AspRat,
9709 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick,
9710 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).BaffleRoughness,
9711 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).QdotSource,
9712 : TmpTscoll,
9713 : TmpTaPlen,
9714 : HcPlen,
9715 : HrPlen,
9716 : Isc,
9717 : MdotVent,
9718 : VdotWind,
9719 : VdotThermal);
9720 :
9721 : } // sequential solution
9722 : // now fill results into derived types
9723 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).Isc = Isc;
9724 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav = TmpTaPlen;
9725 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle = TmpTscoll;
9726 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen = HrPlen;
9727 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen = HcPlen;
9728 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveACH =
9729 16248 : (MdotVent / RhoAir) *
9730 8124 : (1.0 / (state.dataHeatBal->ExtVentedCavity(CavNum).ProjArea * state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick)) *
9731 : Constant::rSecsInHour;
9732 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotVent = MdotVent;
9733 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotWind = VdotWind * RhoAir;
9734 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotTherm = VdotThermal * RhoAir;
9735 :
9736 : // now do some updates
9737 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).TairLast = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
9738 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
9739 :
9740 : // update the OtherSideConditionsModel coefficients.
9741 8124 : int thisOSCM = state.dataHeatBal->ExtVentedCavity(CavNum).OSCMPtr;
9742 :
9743 8124 : state.dataSurface->OSCM(thisOSCM).TConv = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
9744 8124 : state.dataSurface->OSCM(thisOSCM).HConv = state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen;
9745 8124 : state.dataSurface->OSCM(thisOSCM).TRad = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
9746 8124 : state.dataSurface->OSCM(thisOSCM).HRad = state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen;
9747 8124 : }
9748 :
9749 830322 : void GatherComponentLoadsSurfAbsFact(EnergyPlusData &state)
9750 : {
9751 : // SUBROUTINE INFORMATION:
9752 : // AUTHOR Jason Glazer
9753 : // DATE WRITTEN September 2012
9754 :
9755 : // PURPOSE OF THIS SUBROUTINE:
9756 : // Gather values during sizing used for surface absorption factors
9757 :
9758 : // METHODOLOGY EMPLOYED:
9759 : // Save sequence of values for report during sizing.
9760 :
9761 : // This is by surface, so it works for both space and zone component loads
9762 830322 : if (state.dataGlobal->CompLoadReportIsReq && !state.dataGlobal->isPulseZoneSizing) {
9763 36642 : int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
9764 36642 : auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
9765 2683542 : for (int jSurf = 1; jSurf <= state.dataSurface->TotSurfaces; ++jSurf) {
9766 2646900 : auto const &surface = state.dataSurface->Surface(jSurf);
9767 2646900 : if (!surface.HeatTransSurf || surface.Zone == 0) {
9768 164700 : continue; // Skip non-heat transfer surfaces
9769 : }
9770 2482200 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
9771 0 : continue; // Skip tubular daylighting device domes
9772 : }
9773 2482200 : surfCLDayTS.surf[jSurf - 1].ITABSFseq = state.dataHeatBalSurf->SurfAbsThermalInt(jSurf);
9774 2482200 : surfCLDayTS.surf[jSurf - 1].TMULTseq = state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).radThermAbsMult;
9775 : }
9776 : }
9777 830322 : }
9778 :
9779 58178491 : Real64 GetSurfIncidentSolarMultiplier(EnergyPlusData &state, int SurfNum)
9780 : {
9781 58178491 : if (!state.dataSurface->Surface(SurfNum).hasIncSolMultiplier) {
9782 58158649 : return 1.0;
9783 19842 : } else if (state.dataSurface->SurfIncSolMultiplier(SurfNum).sched != nullptr) {
9784 19842 : return state.dataSurface->SurfIncSolMultiplier(SurfNum).sched->getCurrentVal() * state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
9785 : } else {
9786 0 : return state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
9787 : }
9788 : }
9789 :
9790 801 : void InitSurfacePropertyViewFactors(EnergyPlusData &state)
9791 : {
9792 :
9793 : // purpose:
9794 : // Initializes sky and ground surfaces view factors of exterior surfaces
9795 : // used by SurfaceProperty:LocalEnvironment
9796 : // view factors are constant hence should be set only once
9797 :
9798 801 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9799 797 : return;
9800 : }
9801 4 : if (!state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
9802 0 : return;
9803 : }
9804 :
9805 414 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9806 410 : auto &Surface = state.dataSurface->Surface(SurfNum);
9807 410 : if (Surface.SurfHasSurroundingSurfProperty || Surface.IsSurfPropertyGndSurfacesDefined) {
9808 :
9809 18 : int GndSurfsNum = 0;
9810 18 : int SrdSurfsNum = 0;
9811 18 : Real64 SrdSurfsViewFactor = 0.0;
9812 18 : Real64 SurfsSkyViewFactor = 0.0;
9813 18 : Real64 GroundSurfsViewFactor = 0.0;
9814 18 : bool IsSkyViewFactorSet = false;
9815 18 : bool IsGroundViewFactorSet = false;
9816 18 : bool SetGroundViewFactorObject = false;
9817 18 : if (Surface.SurfHasSurroundingSurfProperty) {
9818 6 : SrdSurfsNum = Surface.SurfSurroundingSurfacesNum;
9819 6 : auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
9820 6 : SurfsSkyViewFactor = SrdSurfsProperty.SkyViewFactor;
9821 6 : IsSkyViewFactorSet = SrdSurfsProperty.IsSkyViewFactorSet;
9822 6 : if (SurfsSkyViewFactor > 0.0) {
9823 4 : SrdSurfsViewFactor += SurfsSkyViewFactor;
9824 : }
9825 6 : if (!Surface.IsSurfPropertyGndSurfacesDefined) {
9826 5 : SrdSurfsViewFactor += SrdSurfsProperty.GroundViewFactor;
9827 5 : IsGroundViewFactorSet = SrdSurfsProperty.IsGroundViewFactorSet;
9828 5 : GroundSurfsViewFactor = SrdSurfsProperty.GroundViewFactor;
9829 : }
9830 14 : for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
9831 8 : SrdSurfsViewFactor += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
9832 : }
9833 : }
9834 18 : if (Surface.IsSurfPropertyGndSurfacesDefined) {
9835 13 : GndSurfsNum = Surface.SurfPropertyGndSurfIndex;
9836 13 : IsGroundViewFactorSet = state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet;
9837 13 : GroundSurfsViewFactor = state.dataSurface->GroundSurfsProperty(GndSurfsNum).SurfsViewFactorSum;
9838 13 : SrdSurfsViewFactor += GroundSurfsViewFactor;
9839 : }
9840 :
9841 : // Check if the sum of all defined view factors > 1.0
9842 18 : if (SrdSurfsViewFactor > 1.0) {
9843 0 : ShowSevereError(state, format("Illegal surrounding surfaces view factors for {}.", Surface.Name));
9844 0 : ShowContinueError(state, " The sum of sky, ground, and all surrounding surfaces view factors should be less than or equal to 1.0.");
9845 : }
9846 18 : if (IsSkyViewFactorSet && IsGroundViewFactorSet) {
9847 : // If both surface sky and ground view factor defined, overwrite with the defined value
9848 4 : Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
9849 4 : Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
9850 14 : } else if (IsSkyViewFactorSet && !IsGroundViewFactorSet) {
9851 : // If only sky view factor defined, ground view factor = 1 - all other defined view factors.
9852 2 : Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
9853 2 : Surface.ViewFactorGroundIR = 1 - SrdSurfsViewFactor;
9854 2 : if (GndSurfsNum > 0) {
9855 0 : SetGroundViewFactorObject = true;
9856 0 : state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
9857 : } else {
9858 2 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
9859 : }
9860 12 : } else if (!IsSkyViewFactorSet && IsGroundViewFactorSet) {
9861 : // If only ground view factor defined, sky view factor = 1 - all other defined view factors.
9862 12 : Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
9863 12 : Surface.ViewFactorSkyIR = 1 - SrdSurfsViewFactor;
9864 12 : if (SrdSurfsNum > 0) {
9865 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
9866 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
9867 : }
9868 : } else {
9869 : // If neither ground nor sky view factor specified, continue to use the original proportion.
9870 0 : Surface.ViewFactorSkyIR *= 1 - SrdSurfsViewFactor;
9871 0 : Surface.ViewFactorGroundIR *= 1 - SrdSurfsViewFactor;
9872 0 : if (SrdSurfsNum > 0) {
9873 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
9874 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
9875 0 : if (GndSurfsNum == 0) {
9876 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
9877 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsGroundViewFactorSet = true;
9878 : }
9879 : }
9880 0 : if (GndSurfsNum > 0) {
9881 0 : SetGroundViewFactorObject = true;
9882 0 : state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
9883 : }
9884 : }
9885 18 : if (SetGroundViewFactorObject) {
9886 0 : ReSetGroundSurfacesViewFactor(state, SurfNum);
9887 : }
9888 : }
9889 : }
9890 : }
9891 :
9892 3727810 : void GetGroundSurfacesTemperatureAverage(EnergyPlusData &state)
9893 : {
9894 : // returns ground surfaces average temperature (deg C)
9895 : // ground surfaces viewed by a building exterior surface
9896 : // ground surfaces temperature weighed using view factors
9897 :
9898 3727810 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9899 3720374 : return;
9900 : }
9901 :
9902 620862 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9903 613426 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
9904 595837 : continue;
9905 : }
9906 17589 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9907 17589 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9908 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9909 0 : continue;
9910 : }
9911 17589 : Real64 GndSurfaceTemp = 0.0;
9912 17589 : Real64 GndSurfViewFactor = 0.0;
9913 17589 : Real64 GndSurfaceTempSum = 0.0;
9914 59532 : for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
9915 41943 : GndSurfViewFactor = GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor;
9916 41943 : if (GndSurfViewFactor == 0.0) {
9917 0 : continue;
9918 : }
9919 41943 : if (GndSurfsProperty.GndSurfs(gSurfNum).tempSched == nullptr) {
9920 1353 : continue;
9921 : }
9922 40590 : GndSurfaceTemp = GndSurfsProperty.GndSurfs(gSurfNum).tempSched->getCurrentVal();
9923 40590 : GndSurfaceTempSum += GndSurfViewFactor * pow_4(GndSurfaceTemp + Constant::Kelvin);
9924 : }
9925 17589 : if (GndSurfaceTempSum == 0.0) {
9926 1353 : GndSurfsProperty.SurfsTempAvg = 0.0;
9927 1353 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9928 1353 : continue;
9929 : }
9930 16236 : GndSurfsProperty.SurfsTempAvg = root_4(GndSurfaceTempSum / GndSurfsProperty.SurfsViewFactorSum) - Constant::Kelvin;
9931 : }
9932 : }
9933 :
9934 2828408 : void GetGroundSurfacesReflectanceAverage(EnergyPlusData &state)
9935 : {
9936 : // returns ground surfaces average reflectance (dimensionless)
9937 : // ground reflectance viewed by a building exterior surface
9938 : // ground surfaces reflectance weighed using view factors
9939 :
9940 2828408 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9941 2820972 : return;
9942 : }
9943 620862 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9944 :
9945 613426 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
9946 595837 : continue;
9947 : }
9948 17589 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9949 17589 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9950 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9951 0 : continue;
9952 : }
9953 17589 : Real64 GndSurfRefl = 0.0;
9954 17589 : Real64 GndSurfsReflSum = 0.0;
9955 59532 : for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
9956 41943 : if (GndSurfsProperty.GndSurfs(gSurfNum).reflSched == nullptr) {
9957 1353 : continue;
9958 : }
9959 40590 : GndSurfRefl = GndSurfsProperty.GndSurfs(gSurfNum).reflSched->getCurrentVal();
9960 40590 : GndSurfsReflSum += GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor * GndSurfRefl;
9961 : }
9962 17589 : if (GndSurfsReflSum == 0.0) {
9963 1353 : GndSurfsProperty.SurfsReflAvg = 0.0;
9964 1353 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9965 1353 : continue;
9966 : }
9967 16236 : GndSurfsProperty.SurfsReflAvg = GndSurfsReflSum / GndSurfsProperty.SurfsViewFactorSum;
9968 : }
9969 : }
9970 :
9971 0 : void ReSetGroundSurfacesViewFactor(EnergyPlusData &state, int const SurfNum)
9972 : {
9973 : // resets ground view factors based on view factors identity
9974 : // the ground view factor value is set to the first element
9975 : // when the ground view factor input field is blank
9976 :
9977 0 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
9978 0 : return;
9979 : }
9980 0 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9981 0 : GndSurfsProperty.SurfsViewFactorSum = state.dataSurface->Surface(SurfNum).ViewFactorGroundIR;
9982 :
9983 0 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9984 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9985 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9986 0 : return;
9987 : }
9988 0 : GndSurfsProperty.GndSurfs(1).ViewFactor = GndSurfsProperty.SurfsViewFactorSum;
9989 : }
9990 :
9991 3727810 : void GetSurroundingSurfacesTemperatureAverage(EnergyPlusData &state)
9992 : {
9993 : // returns surrounding surfaces average temperature (deg C)
9994 : // surrounding surfaces viewed by an exterior surface
9995 : // surrounding surfaces temperature weighed using view factors
9996 :
9997 3727810 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9998 3720374 : return;
9999 : }
10000 :
10001 620862 : for (auto &surface : state.dataSurface->Surface) {
10002 613426 : if (!surface.SurfHasSurroundingSurfProperty) {
10003 605308 : continue;
10004 : }
10005 : // local vars
10006 8118 : Real64 SrdSurfaceTemp = 0.0;
10007 8118 : Real64 SrdSurfaceTempSum = 0.0;
10008 8118 : auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(surface.SurfSurroundingSurfacesNum);
10009 18942 : for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
10010 10824 : SrdSurfaceTemp = SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() + Constant::Kelvin;
10011 10824 : SrdSurfaceTempSum += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor * pow_4(SrdSurfaceTemp);
10012 : }
10013 8118 : surface.SrdSurfTemp = root_4(SrdSurfaceTempSum / surface.ViewFactorSrdSurfs) - Constant::Kelvin;
10014 7436 : }
10015 : }
10016 : } // namespace EnergyPlus::HeatBalanceSurfaceManager
|