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 249946 : 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 249946 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Surfaces");
159 249946 : InitSurfaceHeatBalance(state); // Initialize all heat balance related parameters
160 :
161 : // Solve the zone heat balance 'Detailed' solution
162 : // Call the outside and inside surface heat balances
163 249946 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Calculate Outside Surface Heat Balance");
164 249946 : CalcHeatBalanceOutsideSurf(state);
165 249946 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Calculate Inside Surface Heat Balance");
166 249946 : CalcHeatBalanceInsideSurf(state);
167 :
168 : // The air heat balance must be called before the temperature history
169 : // updates because there may be a radiant system in the building
170 249946 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Calculate Air Heat Balance");
171 249946 : HeatBalanceAirManager::ManageAirHeatBalance(state);
172 :
173 : // IF NECESSARY, do one final "average" heat balance pass. This is only
174 : // necessary if a radiant system is present and it was actually on for
175 : // part or all of the time step.
176 249945 : UpdateFinalSurfaceHeatBalance(state);
177 :
178 : // Before we leave the Surface Manager the thermal histories need to be updated
179 249945 : if (state.dataHeatBal->AnyCTF || state.dataHeatBal->AnyEMPD) {
180 200973 : UpdateThermalHistories(state); // Update the thermal histories
181 : }
182 :
183 249945 : if (state.dataHeatBal->AnyCondFD) {
184 342804 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
185 293832 : auto const &surface = state.dataSurface->Surface(SurfNum);
186 293832 : int const ConstrNum = surface.Construction;
187 293832 : if (ConstrNum <= 0) continue; // Shading surface, not really a heat transfer surface
188 293832 : if (state.dataConstruction->Construct(ConstrNum).TypeIsWindow) continue; // Windows simulated in Window module
189 293832 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CondFD) continue;
190 293832 : state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).UpdateMoistureBalance();
191 : }
192 : }
193 :
194 249945 : ThermalComfort::ManageThermalComfort(state, false); // "Record keeping" for the zone
195 :
196 249945 : ReportSurfaceHeatBalance(state);
197 249945 : if (state.dataGlobal->ZoneSizingCalc) OutputReportTabular::GatherComponentLoadsSurface(state);
198 :
199 249945 : CalcThermalResilience(state);
200 :
201 249945 : if (state.dataOutRptTab->displayThermalResilienceSummary) {
202 69935 : ReportThermalResilience(state);
203 : }
204 :
205 249945 : if (state.dataOutRptTab->displayCO2ResilienceSummary) {
206 38 : ReportCO2Resilience(state);
207 : }
208 :
209 249945 : if (state.dataOutRptTab->displayVisualResilienceSummary) {
210 38 : ReportVisualResilience(state);
211 : }
212 :
213 249945 : state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime = false;
214 249945 : }
215 :
216 : // Beginning Initialization Section of the Module
217 : //******************************************************************************
218 :
219 249957 : void UpdateVariableAbsorptances(EnergyPlusData &state)
220 : {
221 249957 : auto &s_mat = state.dataMaterial;
222 249960 : for (int surfNum : state.dataSurface->AllVaryAbsOpaqSurfaceList) {
223 3 : auto const &thisConstruct = state.dataConstruction->Construct(state.dataSurface->Surface(surfNum).Construction);
224 3 : auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
225 3 : assert(thisMaterial != nullptr);
226 3 : if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::Scheduled) {
227 1 : if (thisMaterial->absorpThermalVarSched != nullptr) {
228 1 : state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
229 : }
230 1 : if (thisMaterial->absorpSolarVarSched != nullptr) {
231 0 : state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
232 : }
233 : } else {
234 : Real64 triggerValue;
235 2 : if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceTemperature) {
236 2 : triggerValue = state.dataHeatBalSurf->SurfTempOut(surfNum);
237 0 : } else if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceReceivedSolarRadiation) {
238 0 : triggerValue = state.dataHeatBal->SurfQRadSWOutIncident(surfNum);
239 : } else { // controlled by heating cooling mode
240 0 : int zoneNum = state.dataSurface->Surface(surfNum).Zone;
241 0 : bool isCooling = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).TotalOutputRequired < 0);
242 0 : triggerValue = static_cast<Real64>(isCooling);
243 : }
244 2 : if (thisMaterial->absorpThermalVarCurve != nullptr) {
245 2 : state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) =
246 2 : max(min(thisMaterial->absorpThermalVarCurve->value(state, triggerValue), 0.9999), 0.0001);
247 : }
248 2 : if (thisMaterial->absorpSolarVarCurve != nullptr) {
249 2 : state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) =
250 2 : max(min(thisMaterial->absorpSolarVarCurve->value(state, triggerValue), 0.9999), 0.0001);
251 : }
252 : }
253 : }
254 249957 : }
255 :
256 249956 : void InitSurfaceHeatBalance(EnergyPlusData &state)
257 : {
258 :
259 : // SUBROUTINE INFORMATION:
260 : // AUTHOR Richard J. Liesen
261 : // DATE WRITTEN January 1998
262 : // MODIFIED Nov. 1999, FCW,
263 : // Move ComputeIntThermalAbsorpFactors
264 : // so called every timestep
265 : // MODIFIED Aug. 2017
266 : // Add initializations of surface data to linked air node value if defined
267 :
268 : // PURPOSE OF THIS SUBROUTINE:
269 : // This subroutine is for surface initializations within the
270 : // heat balance.
271 :
272 : // METHODOLOGY EMPLOYED:
273 : // Uses the status flags to trigger record keeping events.
274 :
275 : // // Using/Aliasing
276 : // using namespace SolarShading;
277 : // using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
278 : // using HeatBalFiniteDiffManager::InitHeatBalFiniteDiff;
279 : // using InternalHeatGains::ManageInternalHeatGains;
280 : //
281 : // auto &Surface = state.dataSurface->Surface;
282 : //
283 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Outdoor environment for Surfaces");
284 :
285 : // set zone level wind dir to global value
286 : // Initialize zone outdoor environmental variables
287 : // Bulk Initialization for Temperatures & WindSpeed
288 : // using the zone, modify the zone Dry/Wet BulbTemps
289 :
290 : // Initialize surface outdoor environmental variables
291 : // Bulk Initialization for Temperatures & WindSpeed
292 : // using the surface centroids, modify the surface Dry/Wet BulbTemps
293 249956 : DataSurfaces::SetSurfaceOutBulbTempAt(state);
294 249956 : DataSurfaces::CheckSurfaceOutBulbTempAt(state);
295 :
296 249956 : DataSurfaces::SetSurfaceWindSpeedAt(state);
297 249956 : DataSurfaces::SetSurfaceWindDirAt(state);
298 249956 : if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
299 21 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
300 18 : if (state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode > 0) {
301 1 : auto const &linkedNode = state.dataLoopNodes->Node(state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode);
302 1 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) = linkedNode.OutAirDryBulb;
303 1 : state.dataSurface->SurfOutWetBulbTemp(SurfNum) = linkedNode.OutAirWetBulb;
304 1 : state.dataSurface->SurfOutWindSpeed(SurfNum) = linkedNode.OutAirWindSpeed;
305 1 : state.dataSurface->SurfOutWindDir(SurfNum) = linkedNode.OutAirWindDir;
306 : }
307 : }
308 : }
309 : // Overwriting surface and zone level environmental data with EMS override value
310 249956 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
311 867072 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
312 750999 : if (state.dataSurface->SurfOutDryBulbTempEMSOverrideOn(SurfNum)) {
313 0 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) = state.dataSurface->SurfOutDryBulbTempEMSOverrideValue(SurfNum);
314 : }
315 750999 : if (state.dataSurface->SurfOutWetBulbTempEMSOverrideOn(SurfNum)) {
316 0 : state.dataSurface->SurfOutWetBulbTemp(SurfNum) = state.dataSurface->SurfOutWetBulbTempEMSOverrideValue(SurfNum);
317 : }
318 750999 : if (state.dataSurface->SurfWindSpeedEMSOverrideOn(SurfNum)) {
319 0 : state.dataSurface->SurfOutWindSpeed(SurfNum) = state.dataSurface->SurfWindSpeedEMSOverrideValue(SurfNum);
320 : }
321 750999 : if (state.dataSurface->SurfWindDirEMSOverrideOn(SurfNum)) {
322 0 : state.dataSurface->SurfOutWindDir(SurfNum) = state.dataSurface->SurfWindDirEMSOverrideValue(SurfNum);
323 : }
324 750999 : if (state.dataSurface->SurfViewFactorGroundEMSOverrideOn(SurfNum)) {
325 1354 : state.dataSurface->Surface(SurfNum).ViewFactorGround = state.dataSurface->SurfViewFactorGroundEMSOverrideValue(SurfNum);
326 : }
327 : }
328 : }
329 :
330 : // Do the Begin Simulation initializations
331 249956 : if (state.dataGlobal->BeginSimFlag) {
332 112 : AllocateSurfaceHeatBalArrays(state); // Allocate the Module Arrays before any inits take place
333 112 : state.dataHeatBalSurf->InterZoneWindow =
334 112 : std::any_of(state.dataViewFactor->EnclSolInfo.begin(),
335 112 : state.dataViewFactor->EnclSolInfo.end(),
336 141 : [](DataViewFactorInformation::EnclosureViewFactorInformation const &e) { return e.HasInterZoneWindow; });
337 : }
338 249956 : if (state.dataGlobal->BeginSimFlag || state.dataGlobal->AnySurfPropOverridesInModel) {
339 244 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
340 282 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
341 150 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
342 150 : int const firstSurf = thisSpace.HTSurfaceFirst;
343 150 : int const lastSurf = thisSpace.HTSurfaceLast;
344 944 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
345 794 : int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // SurfActiveConstruction set above
346 794 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
347 794 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
348 794 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
349 794 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisConstruct.OutsideRoughness;
350 794 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisConstruct.OutsideAbsorpSolar;
351 794 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisConstruct.OutsideAbsorpThermal;
352 : }
353 : }
354 : }
355 : }
356 :
357 : // variable thermal solar absorptance overrides
358 249956 : UpdateVariableAbsorptances(state);
359 :
360 : // Do the Begin Environment initializations
361 249956 : if (state.dataGlobal->BeginEnvrnFlag) {
362 483 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Temperature and Flux Histories");
363 483 : InitThermalAndFluxHistories(state); // Set initial temperature and flux histories
364 : }
365 :
366 : // Calc movable insulation properties
367 249956 : if (state.dataSurface->AnyMovableInsulation) {
368 0 : EvalOutsideMovableInsulation(state);
369 0 : EvalInsideMovableInsulation(state);
370 : }
371 :
372 : // There are no daily initializations done in this portion of the surface heat balance
373 : // There are no hourly initializations done in this portion of the surface heat balance
374 :
375 249956 : GetGroundSurfacesReflectanceAverage(state);
376 :
377 : // Need to be called each timestep in order to check if surface points to new construction (EMS) and if does then
378 : // complex fenestration needs to be initialized for additional states
379 249956 : SolarShading::TimestepInitComplexFenestration(state);
380 :
381 : // Calculate exterior-surface multipliers that account for anisotropy of
382 : // sky radiance
383 249956 : if (state.dataEnvrn->SunIsUp && state.dataEnvrn->DifSolarRad > 0.0) {
384 71212 : SolarShading::AnisoSkyViewFactors(state);
385 : } else {
386 178744 : state.dataSolarShading->SurfAnisoSkyMult = 0.0;
387 : }
388 :
389 : // Set shading flag for exterior windows (except flags related to daylighting) and
390 : // window construction (unshaded or shaded) to be used in heat balance calculation
391 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Window Shading");
392 :
393 249956 : SolarShading::WindowShadingManager(state);
394 :
395 249956 : SolarShading::CheckGlazingShadingStatusChange(state);
396 :
397 : // Calculate factors that are used to determine how much long-wave radiation from internal
398 : // gains is absorbed by interior surfaces
399 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Computing Interior Absorption Factors");
400 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) HeatBalanceIntRadExchange::InitInteriorRadExchange(state);
401 249956 : ComputeIntThermalAbsorpFactors(state);
402 :
403 : // Calculate factors for diffuse solar absorbed by room surfaces and interior shades
404 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Computing Interior Diffuse Solar Absorption Factors");
405 249956 : ComputeIntSWAbsorpFactors(state);
406 :
407 249956 : if (state.dataHeatBalSurf->InterZoneWindow) {
408 1 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
409 0 : DisplayString(state, "Computing Interior Diffuse Solar Exchange through Interzone Windows");
410 : }
411 1 : ComputeDifSolExcZonesWIZWindows(state);
412 : }
413 :
414 249956 : Dayltg::initDaylighting(state, state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime);
415 :
416 499912 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
417 249956 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, "Main");
418 :
419 249956 : if (state.dataSurface->AirflowWindows) SolarShading::WindowGapAirflowControl(state);
420 :
421 : // The order of these initializations is important currently. Over time we hope to
422 : // take the appropriate parts of these inits to the other heat balance managers
423 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Solar Heat Gains");
424 :
425 249956 : InitSolarHeatGains(state);
426 :
427 249956 : Dayltg::manageDaylighting(state);
428 :
429 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Internal Heat Gains");
430 249956 : InternalHeatGains::ManageInternalHeatGains(state, false);
431 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Interior Solar Distribution");
432 249956 : InitIntSolarDistribution(state);
433 :
434 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Interior Convection Coefficients");
435 249956 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempInTmp);
436 :
437 249956 : if (state.dataGlobal->BeginSimFlag) { // Now's the time to report surfaces, if desired
438 : // if (firstTime) CALL DisplayString('Reporting Surfaces')
439 : // CALL ReportSurfaces
440 112 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Gathering Information for Predefined Reporting");
441 112 : GatherForPredefinedReport(state);
442 : }
443 :
444 : // Initialize the temperature history terms for conduction through the surfaces
445 249956 : if (state.dataHeatBal->AnyCondFD) {
446 48972 : HeatBalFiniteDiffManager::InitHeatBalFiniteDiff(state);
447 : }
448 :
449 586606 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
450 709603 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
451 372953 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
452 372953 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
453 372953 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
454 2358705 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
455 1985752 : auto const &surface = state.dataSurface->Surface(SurfNum);
456 1985752 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
457 293832 : surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)
458 293832 : continue;
459 : // Outside surface temp of "normal" windows not needed in Window5 calculation approach
460 : // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
461 :
462 1691920 : int const ConstrNum = surface.Construction;
463 1691920 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
464 1691920 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) = 0.0;
465 1691920 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) = 0.0;
466 1691920 : if (construct.NumCTFTerms <= 1) continue;
467 :
468 7614410 : for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
469 : // [ l11 ] == ( 1, Term + 1, SurfNum ), [ l12 ] == ( 1, Term + 1, SurfNum )
470 :
471 : // Sign convention for the various terms in the following two equations
472 : // is based on the form of the Conduction Transfer Function equation
473 : // given by:
474 : // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old)
475 : // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old)
476 : // In both equations, flux is positive from outside to inside.
477 :
478 : // Tuned Aliases and linear indexing
479 6552068 : Real64 const ctf_cross(construct.CTFCross[Term]);
480 :
481 6552068 : Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
482 6552068 : Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
483 6552068 : Real64 const QH11(state.dataHeatBalSurf->SurfOutsideFluxHist(Term + 1)(SurfNum));
484 6552068 : Real64 const QH12(state.dataHeatBalSurf->SurfInsideFluxHist(Term + 1)(SurfNum));
485 6552068 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) +=
486 6552068 : ctf_cross * TH11 - construct.CTFInside[Term] * TH12 + construct.CTFFlux[Term] * QH12;
487 :
488 6552068 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) +=
489 6552068 : construct.CTFOutside[Term] * TH11 - ctf_cross * TH12 + construct.CTFFlux[Term] * QH11;
490 : }
491 : }
492 : }
493 : }
494 249956 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
495 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
496 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
497 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
498 0 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
499 0 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
500 0 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
501 0 : auto const &surface = state.dataSurface->Surface(SurfNum);
502 0 : int const ConstrNum = surface.Construction;
503 0 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
504 0 : if (!construct.SourceSinkPresent) continue;
505 0 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
506 0 : surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)
507 0 : continue;
508 0 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) = 0.0;
509 0 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) = 0.0;
510 0 : if (construct.NumCTFTerms <= 1) continue;
511 0 : for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
512 0 : Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
513 0 : Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
514 0 : Real64 const QsrcHist1(state.dataHeatBalSurf->SurfQsrcHist(SurfNum, Term + 1));
515 :
516 0 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += construct.CTFSourceIn[Term] * QsrcHist1;
517 :
518 0 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += construct.CTFSourceOut[Term] * QsrcHist1;
519 :
520 0 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) +=
521 0 : construct.CTFTSourceOut[Term] * TH11 + construct.CTFTSourceIn[Term] * TH12 + construct.CTFTSourceQ[Term] * QsrcHist1 +
522 0 : construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTsrcHist(SurfNum, Term + 1);
523 :
524 0 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) +=
525 0 : construct.CTFTUserOut[Term] * TH11 + construct.CTFTUserIn[Term] * TH12 + construct.CTFTUserSource[Term] * QsrcHist1 +
526 0 : construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTuserHist(SurfNum, Term + 1);
527 : }
528 : }
529 : } // ...end of surfaces DO loop for initializing temperature history terms for the surface heat balances
530 : }
531 : }
532 :
533 : // Zero out all of the radiant system heat balance coefficient arrays
534 586606 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
535 709603 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
536 372953 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
537 372953 : int const firstSurf = thisSpace.HTSurfaceFirst;
538 372953 : int const lastSurf = thisSpace.HTSurfaceLast;
539 2447269 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
540 2074316 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) = 0.0;
541 2074316 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) = 0.0;
542 2074316 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) = 0.0;
543 2074316 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = 0.0;
544 2074316 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = 0.0;
545 2074316 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = 0.0;
546 :
547 2074316 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
548 2074316 : state.dataHeatBalFanSys->QPVSysSource(SurfNum) = 0.0;
549 2074316 : state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = 0.0;
550 2074316 : state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = 0.0;
551 :
552 : } // ...end of Zone Surf loop
553 : }
554 : } // ...end of Zone loop
555 :
556 249980 : for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
557 24 : auto &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
558 24 : thisSurfQRadFromHVAC.HTRadSys = 0.0;
559 24 : thisSurfQRadFromHVAC.HWBaseboard = 0.0;
560 24 : thisSurfQRadFromHVAC.SteamBaseboard = 0.0;
561 24 : thisSurfQRadFromHVAC.ElecBaseboard = 0.0;
562 24 : thisSurfQRadFromHVAC.CoolingPanel = 0.0;
563 : }
564 :
565 249956 : if (state.dataGlobal->ZoneSizingCalc) GatherComponentLoadsSurfAbsFact(state);
566 :
567 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
568 112 : DisplayString(state, "Completed Initializing Surface Heat Balance");
569 : }
570 249956 : state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime = false;
571 249956 : }
572 :
573 114 : void GatherForPredefinedReport(EnergyPlusData &state)
574 : {
575 :
576 : // SUBROUTINE INFORMATION:
577 : // AUTHOR Jason Glazer
578 : // DATE WRITTEN August 2006
579 :
580 : // PURPOSE OF THIS SUBROUTINE:
581 : // This subroutine reports the information for the predefined reports
582 : // related to envelope components.
583 :
584 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
585 114 : std::string surfName;
586 : Real64 mult;
587 : Real64 curAzimuth;
588 : Real64 curTilt;
589 : Real64 windowArea;
590 : Real64 frameWidth;
591 : Real64 frameArea;
592 : Real64 dividerArea;
593 : // counts for object count report
594 114 : int SurfaceClassCount = int(DataSurfaces::SurfaceClass::Num);
595 114 : Array1D_int numSurfaces(SurfaceClassCount);
596 114 : Array1D_int numExtSurfaces(SurfaceClassCount);
597 : int frameDivNum;
598 : bool isExterior;
599 114 : Array1D<Real64> computedNetArea; // holds the gross wall area minus the window and door areas
600 :
601 : // the following variables are for the CalcNominalWindowCond call but only SHGCSummer is needed
602 : Real64 nomCond;
603 : Real64 SHGCSummer;
604 : Real64 TransSolNorm;
605 : Real64 TransVisNorm;
606 : Real64 nomUfact;
607 : int errFlag;
608 : int curWSC;
609 : // following variables are totals for fenestration table
610 114 : Real64 windowAreaWMult(0.0);
611 114 : Real64 fenTotArea(0.0);
612 114 : Real64 fenTotAreaNorth(0.0);
613 114 : Real64 fenTotAreaNonNorth(0.0);
614 114 : Real64 ufactArea(0.0);
615 114 : Real64 ufactAreaNorth(0.0);
616 114 : Real64 ufactAreaNonNorth(0.0);
617 114 : Real64 shgcArea(0.0);
618 114 : Real64 shgcAreaNorth(0.0);
619 114 : Real64 shgcAreaNonNorth(0.0);
620 114 : Real64 vistranArea(0.0);
621 114 : Real64 vistranAreaNorth(0.0);
622 114 : Real64 vistranAreaNonNorth(0.0);
623 114 : Real64 intFenTotArea(0.0);
624 114 : Real64 intUfactArea(0.0);
625 114 : Real64 intShgcArea(0.0);
626 114 : Real64 intVistranArea(0.0);
627 : bool isNorth;
628 :
629 114 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WinShadingType::Num)> WindowShadingTypeNames = {
630 : "No Shade", // 0
631 : "Shade Off", // 1
632 : "Interior Shade",
633 : "Switchable Glazing",
634 : "Exterior Shade",
635 : "Exterior Screen",
636 : "Interior Blind",
637 : "Exterior Blind",
638 : "Between Glass Shade",
639 : "Between Glass Blind",
640 : };
641 :
642 114 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WindowShadingControlType::Num)> WindowShadingControlTypeNames = {
643 : "Uncontrolled",
644 : "AlwaysOn",
645 : "AlwaysOff",
646 : "OnIfScheduleAllows",
647 : "OnIfHighSolarOnWindow",
648 : "OnIfHighHorizontalSolar",
649 : "OnIfHighOutdoorAirTemperature",
650 : "OnIfHighZoneAirTemperature",
651 : "OnIfHighZoneCooling",
652 : "OnIfHighGlare",
653 : "MeetDaylightIlluminanceSetpoint",
654 : "OnNightIfLowOutdoorTempAndOffDay",
655 : "OnNightIfLowInsideTempAndOffDay",
656 : "OnNightIfHeatingAndOffDay",
657 : "OnNightIfLowOutdoorTempAndOnDayIfCooling",
658 : "OnNightIfHeatingAndOnDayIfCooling",
659 : "OffNightAndOnDayIfCoolingAndHighSolarOnWindow",
660 : "OnNightAndOnDayIfCoolingAndHighSolarOnWindow",
661 : "OnIfHighOutdoorAirTempAndHighSolarOnWindow",
662 : "OnIfHighOutdoorAirTempAndHighHorizontalSolar",
663 : "OnIfHighZoneAirTempAndHighSolarOnWindow",
664 : "OnIfHighZoneAirTempAndHighHorizontalSolar"};
665 :
666 114 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcProductNames = {
667 : "CasementDouble", "CasementSingle", "DualAction",
668 : "Fixed", "Garage", "Greenhouse",
669 : "HingedEscape", "HorizontalSlider", "Jal",
670 : "Pivoted", "ProjectingSingle", "ProjectingDual",
671 : "DoorSidelite", "Skylight", "SlidingPatioDoor",
672 : "CurtainWall", "SpandrelPanel", "SideHingedDoor",
673 : "DoorTransom", "TropicalAwning", "TubularDaylightingDevice",
674 : "VerticalSlider"};
675 :
676 114 : constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcWidth = {
677 : // width in meters from Table 4-3 of NFRC 100-2020
678 : 1.200, 0.600, 1.200, // CasementDouble, CasementSingle, DualAction,
679 : 1.200, 2.134, 1.500, // Fixed, Garage, Greenhouse,
680 : 1.500, 1.500, 1.200, // HingedEscape, HorizontalSlider, Jal,
681 : 1.200, 1.500, 1.500, // Pivoted, ProjectingSingle, ProjectingDual,
682 : 0.600, 1.200, 2.000, // DoorSidelite, Skylight, SlidingPatioDoor,
683 : 2.000, 2.000, 1.920, // CurtainWall, SpandrelPanel, SideHingedDoor,
684 : 2.000, 1.500, 0.350, // DoorTransom, TropicalAwning, TubularDaylightingDevice,
685 : 1.200 // VerticalSlider,
686 : };
687 :
688 114 : constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcHeight = {
689 : // height in meters from Table 4-3 of NFRC 100-2020
690 : 1.500, 1.500, 1.500, // CasementDouble, CasementSingle, DualAction,
691 : 1.500, 2.134, 1.200, // Fixed, Garage, Greenhouse,
692 : 1.200, 1.200, 1.500, // HingedEscape, HorizontalSlider, Jal,
693 : 1.500, 1.200, 0.600, // Pivoted, ProjectingSingle, ProjectingDual,
694 : 2.090, 1.200, 2.000, // DoorSidelite, Skylight, SlidingPatioDoor,
695 : 2.000, 1.200, 2.090, // CurtainWall, SpandrelPanel, SideHingedDoor,
696 : 0.600, 1.200, 0.350, // DoorTransom, TropicalAwning, TubularDaylightingDevice,
697 : 1.500 // VerticalSlider,
698 : };
699 :
700 114 : constexpr std::array<DataSurfaces::NfrcVisionType, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcVision = {
701 : DataSurfaces::NfrcVisionType::DualHorizontal, DataSurfaces::NfrcVisionType::Single,
702 : DataSurfaces::NfrcVisionType::DualVertical, // CasementDouble, CasementSingle, DualAction,
703 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
704 : DataSurfaces::NfrcVisionType::Single, // Fixed, Garage, Greenhouse,
705 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::DualHorizontal,
706 : DataSurfaces::NfrcVisionType::Single, // HingedEscape, HorizontalSlider, Jal,
707 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
708 : DataSurfaces::NfrcVisionType::DualHorizontal, // Pivoted, ProjectingSingle, ProjectingDual,
709 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
710 : DataSurfaces::NfrcVisionType::DualHorizontal, // DoorSidelite, Skylight, SlidingPatioDoor,
711 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
712 : DataSurfaces::NfrcVisionType::Single, // CurtainWall, SpandrelPanel, SideHingedDoor,
713 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
714 : DataSurfaces::NfrcVisionType::Single, // DoorTransom, TropicalAwning, TubularDaylightingDevice,
715 : DataSurfaces::NfrcVisionType::DualVertical // VerticalSlider
716 : };
717 :
718 114 : numSurfaces = 0;
719 114 : numExtSurfaces = 0;
720 :
721 114 : computedNetArea.allocate(state.dataSurface->TotSurfaces);
722 114 : computedNetArea = 0.0; // start at zero, add wall area and subtract window and door area
723 :
724 : // set up for EIO <FenestrationAssembly> output
725 114 : if (state.dataHeatBal->TotFrameDivider > 0 && state.dataGeneral->Constructions) {
726 0 : print(state.files.eio,
727 : "{}\n",
728 : "! <FenestrationAssembly>,Construction Name,Frame and Divider Name,NFRC Product Type,"
729 : "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
730 : }
731 : static constexpr std::string_view FenestrationAssemblyFormat("FenestrationAssembly,{},{},{},{:.3R},{:.3R},{:.3R}\n");
732 114 : std::vector<std::pair<int, int>> uniqConsFrame;
733 114 : std::pair<int, int> consAndFrame;
734 :
735 : // set up for EIO <FenestrationShadedState> output
736 114 : bool fenestrationShadedStateHeaderShown(false);
737 : static constexpr std::string_view FenestrationShadedStateFormat("FenestrationShadedState,{},{:.3R},{:.3R},{:.3R},{},{},{:.3R},{:.3R},{:.3R}\n");
738 114 : std::vector<std::pair<int, int>> uniqShdConsFrame;
739 114 : std::pair<int, int> shdConsAndFrame;
740 :
741 950 : for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
742 836 : auto &surface = state.dataSurface->Surface(iSurf);
743 836 : surfName = surface.Name;
744 : // only exterior surfaces including underground
745 836 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
746 216 : (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
747 620 : isExterior = true;
748 620 : switch (surface.Class) {
749 545 : case DataSurfaces::SurfaceClass::Wall:
750 : case DataSurfaces::SurfaceClass::Floor:
751 : case DataSurfaces::SurfaceClass::Roof: {
752 545 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
753 545 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
754 545 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
755 545 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
756 545 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpCons, surfName, construct.Name);
757 545 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpZone, surfName, thisZone.Name);
758 545 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpSpace, surfName, thisSpace.Name);
759 545 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
760 545 : OutputReportPredefined::PreDefTableEntry(
761 545 : state, state.dataOutRptPredefined->pdchOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
762 545 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpGrArea, surfName, surface.GrossArea * mult);
763 545 : computedNetArea(iSurf) += surface.GrossArea * mult;
764 545 : curAzimuth = surface.Azimuth;
765 : // Round to two decimals, like the display in tables
766 : // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
767 545 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
768 545 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpAzimuth, surfName, curAzimuth);
769 545 : curTilt = surface.Tilt;
770 545 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpTilt, surfName, curTilt);
771 545 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
772 362 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
773 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "N");
774 282 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
775 82 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "E");
776 200 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
777 121 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "S");
778 79 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
779 79 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "W");
780 : }
781 : }
782 545 : } break;
783 58 : case DataSurfaces::SurfaceClass::Window:
784 : case DataSurfaces::SurfaceClass::TDD_Dome: {
785 58 : auto &construct = state.dataConstruction->Construct(surface.Construction);
786 58 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
787 58 : mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
788 58 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
789 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenCons, surfName, construct.Name);
790 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenZone, surfName, thisZone.Name);
791 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSpace, surfName, thisSpace.Name);
792 : // if the construction report is requested the SummerSHGC is already calculated
793 58 : if (construct.SummerSHGC != 0) {
794 39 : SHGCSummer = construct.SummerSHGC;
795 39 : TransVisNorm = construct.VisTransNorm;
796 : } else {
797 : // must calculate Summer SHGC
798 19 : if (!construct.WindowTypeEQL) {
799 19 : Window::CalcNominalWindowCond(state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
800 19 : construct.SummerSHGC = SHGCSummer;
801 19 : construct.VisTransNorm = TransVisNorm;
802 19 : construct.SolTransNorm = TransSolNorm;
803 : }
804 : }
805 : // include the frame area if present
806 58 : windowArea = surface.GrossArea;
807 58 : frameArea = 0.0;
808 58 : dividerArea = 0.0;
809 58 : frameDivNum = surface.FrameDivider;
810 58 : if (frameDivNum != 0) {
811 3 : auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
812 3 : frameWidth = frameDivider.FrameWidth;
813 3 : frameArea = (surface.Height + 2.0 * frameWidth) * (surface.Width + 2.0 * frameWidth) - (surface.Height * surface.Width);
814 3 : windowArea += frameArea;
815 3 : dividerArea = frameDivider.DividerWidth * (frameDivider.HorDividers * surface.Width + frameDivider.VertDividers * surface.Height -
816 3 : frameDivider.HorDividers * frameDivider.VertDividers * frameDivider.DividerWidth);
817 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameDivName, surfName, frameDivider.Name);
818 3 : OutputReportPredefined::PreDefTableEntry(
819 3 : state, state.dataOutRptPredefined->pdchFenFrameConductance, surfName, frameDivider.FrameConductance, 3);
820 3 : OutputReportPredefined::PreDefTableEntry(
821 3 : state, state.dataOutRptPredefined->pdchFenDividerConductance, surfName, frameDivider.DividerConductance, 3);
822 :
823 : // report the selected NRFC product type (specific sizes) and the NFRC rating for the assembly (glass + frame + divider)
824 3 : std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
825 3 : const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
826 3 : const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
827 3 : const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
828 :
829 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemNfrcType, surfName, NFRCname);
830 :
831 3 : Real64 uValueAssembly = 0.0;
832 3 : Real64 shgcAssembly = 0.0;
833 3 : Real64 vtAssembly = 0.0;
834 :
835 3 : Window::GetWindowAssemblyNfrcForReport(
836 : state, iSurf, surface.Construction, windowWidth, windowHeight, vision, uValueAssembly, shgcAssembly, vtAssembly);
837 3 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
838 0 : state.dataHeatBal->NominalU(surface.Construction) =
839 0 : Window::GetIGUUValueForNFRCReport(state, iSurf, surface.Construction, windowWidth, windowHeight);
840 0 : SHGCSummer = Window::GetSHGCValueForNFRCReporting(state, iSurf, surface.Construction, windowWidth, windowHeight);
841 : }
842 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemUfact, surfName, uValueAssembly, 3);
843 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemSHGC, surfName, shgcAssembly, 3);
844 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemVisTr, surfName, vtAssembly, 3);
845 :
846 : // output EIO <FenestrationAssembly> for each unique combination of construction and frame/divider
847 3 : if (state.dataGeneral->Constructions) {
848 0 : consAndFrame = std::make_pair(surface.Construction, frameDivNum);
849 0 : if (std::find(uniqConsFrame.begin(), uniqConsFrame.end(), consAndFrame) == uniqConsFrame.end()) {
850 0 : uniqConsFrame.push_back(consAndFrame);
851 0 : print(state.files.eio,
852 : FenestrationAssemblyFormat,
853 0 : construct.Name,
854 0 : frameDivider.Name,
855 : NFRCname,
856 : uValueAssembly,
857 : shgcAssembly,
858 : vtAssembly);
859 : }
860 : }
861 : }
862 58 : windowAreaWMult = windowArea * mult;
863 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAreaOf1, surfName, windowArea);
864 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameAreaOf1, surfName, frameArea);
865 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDividerAreaOf1, surfName, dividerArea);
866 116 : OutputReportPredefined::PreDefTableEntry(
867 58 : state, state.dataOutRptPredefined->pdchFenGlassAreaOf1, surfName, windowArea - (frameArea + dividerArea));
868 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, surfName, windowAreaWMult);
869 58 : computedNetArea(surface.BaseSurf) -= windowAreaWMult;
870 58 : nomUfact = state.dataHeatBal->NominalU(surface.Construction);
871 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, surfName, nomUfact, 3);
872 :
873 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, surfName, SHGCSummer, 3);
874 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, surfName, TransVisNorm, 3);
875 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenParent, surfName, surface.BaseSurfName);
876 58 : curAzimuth = surface.Azimuth;
877 : // Round to two decimals, like the display in tables
878 58 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
879 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAzimuth, surfName, curAzimuth);
880 58 : isNorth = false;
881 58 : curTilt = surface.Tilt;
882 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenTilt, surfName, curTilt);
883 58 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
884 55 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
885 11 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "N");
886 11 : isNorth = true;
887 44 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
888 9 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "E");
889 35 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
890 29 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "S");
891 6 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
892 6 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "W");
893 : }
894 : }
895 :
896 : // Report table for every shading control state
897 58 : const unsigned int totalStates = surface.windowShadingControlList.size();
898 58 : if (frameDivNum != 0) {
899 3 : auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
900 3 : for (unsigned int i = 0; i < totalStates; ++i) {
901 0 : const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
902 0 : const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
903 0 : const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
904 :
905 0 : const int stateConstrNum = surface.shadedConstructionList[i];
906 0 : const Real64 stateUValue = Window::GetIGUUValueForNFRCReport(state, iSurf, stateConstrNum, windowWidth, windowHeight);
907 0 : const Real64 stateSHGC = Window::GetSHGCValueForNFRCReporting(state, iSurf, stateConstrNum, windowWidth, windowHeight);
908 0 : std::string const &constructionName = state.dataConstruction->Construct(stateConstrNum).Name;
909 :
910 0 : OutputReportPredefined::PreDefTableEntry(
911 0 : state, state.dataOutRptPredefined->pdchFenShdFrameDiv, constructionName, frameDivider.Name);
912 0 : OutputReportPredefined::PreDefTableEntry(
913 0 : state, state.dataOutRptPredefined->pdchFenShdUfact, constructionName, stateUValue, 3);
914 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenShdSHGC, constructionName, stateSHGC, 3);
915 0 : OutputReportPredefined::PreDefTableEntry(state,
916 0 : state.dataOutRptPredefined->pdchFenShdVisTr,
917 : constructionName,
918 0 : state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
919 0 : 3);
920 :
921 0 : Real64 stateAssemblyUValue{0.0};
922 0 : Real64 stateAssemblySHGC{0.0};
923 0 : Real64 stateAssemblyVT{0.0};
924 :
925 0 : Window::GetWindowAssemblyNfrcForReport(
926 : state, iSurf, stateConstrNum, windowWidth, windowHeight, vision, stateAssemblyUValue, stateAssemblySHGC, stateAssemblyVT);
927 :
928 0 : std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
929 0 : OutputReportPredefined::PreDefTableEntry(
930 0 : state, state.dataOutRptPredefined->pdchFenShdAssemNfrcType, constructionName, NFRCname);
931 :
932 0 : OutputReportPredefined::PreDefTableEntry(
933 0 : state, state.dataOutRptPredefined->pdchFenShdAssemUfact, constructionName, stateAssemblyUValue, 3);
934 0 : OutputReportPredefined::PreDefTableEntry(
935 0 : state, state.dataOutRptPredefined->pdchFenShdAssemSHGC, constructionName, stateAssemblySHGC, 3);
936 0 : OutputReportPredefined::PreDefTableEntry(
937 0 : state, state.dataOutRptPredefined->pdchFenShdAssemVisTr, constructionName, stateAssemblyVT, 3);
938 :
939 0 : if (state.dataGeneral->Constructions) {
940 0 : if (!fenestrationShadedStateHeaderShown) {
941 0 : print(state.files.eio,
942 : "{}\n",
943 : "! <FenestrationShadedState>,Construction Name,Glass U-Factor {W/m2-K},"
944 : "Glass SHGC, Glass Visible Transmittance, Frame and Divider Name,NFRC Product Type,"
945 : "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
946 0 : fenestrationShadedStateHeaderShown = true;
947 : }
948 :
949 0 : shdConsAndFrame = std::make_pair(stateConstrNum, frameDivNum);
950 0 : if (std::find(uniqShdConsFrame.begin(), uniqShdConsFrame.end(), shdConsAndFrame) == uniqShdConsFrame.end()) {
951 0 : uniqShdConsFrame.push_back(shdConsAndFrame);
952 0 : print(state.files.eio,
953 : FenestrationShadedStateFormat,
954 : constructionName,
955 : stateUValue,
956 : stateSHGC,
957 0 : state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
958 0 : frameDivider.Name,
959 : NFRCname,
960 : stateAssemblyUValue,
961 : stateAssemblySHGC,
962 : stateAssemblyVT);
963 : }
964 : }
965 : }
966 : }
967 :
968 58 : curWSC = surface.activeWindowShadingControl;
969 : // compute totals for area weighted averages
970 58 : fenTotArea += windowAreaWMult;
971 58 : ufactArea += nomUfact * windowAreaWMult;
972 58 : shgcArea += SHGCSummer * windowAreaWMult;
973 58 : vistranArea += TransVisNorm * windowAreaWMult;
974 58 : if (isNorth) {
975 11 : fenTotAreaNorth += windowAreaWMult;
976 11 : ufactAreaNorth += nomUfact * windowAreaWMult;
977 11 : shgcAreaNorth += SHGCSummer * windowAreaWMult;
978 11 : vistranAreaNorth += TransVisNorm * windowAreaWMult;
979 : } else {
980 47 : fenTotAreaNonNorth += windowAreaWMult;
981 47 : ufactAreaNonNorth += nomUfact * windowAreaWMult;
982 47 : shgcAreaNonNorth += SHGCSummer * windowAreaWMult;
983 47 : vistranAreaNonNorth += TransVisNorm * windowAreaWMult;
984 : }
985 : // shading
986 58 : if (surface.HasShadeControl) {
987 8 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "Yes");
988 16 : OutputReportPredefined::PreDefTableEntry(
989 16 : state, state.dataOutRptPredefined->pdchWscName, surfName, state.dataSurface->WindowShadingControl(curWSC).Name);
990 : // shading report
991 16 : OutputReportPredefined::PreDefTableEntry(
992 : state,
993 8 : state.dataOutRptPredefined->pdchWscShading,
994 : surfName,
995 8 : WindowShadingTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).ShadingType)]);
996 16 : OutputReportPredefined::PreDefTableEntry(
997 : state,
998 8 : state.dataOutRptPredefined->pdchWscControl,
999 : surfName,
1000 8 : WindowShadingControlTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).shadingControlType)]);
1001 :
1002 : // output list of all possible shading constructions for shaded windows including those with storms
1003 8 : std::string names;
1004 16 : for (int construction : surface.shadedConstructionList) {
1005 8 : if (!names.empty()) names.append("; ");
1006 8 : names.append(state.dataConstruction->Construct(construction).Name);
1007 : }
1008 8 : for (int construction : surface.shadedStormWinConstructionList) {
1009 0 : if (!names.empty()) names.append("; ");
1010 0 : names.append(state.dataConstruction->Construct(construction).Name);
1011 : }
1012 8 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscShadCons, surfName, names);
1013 :
1014 8 : if (state.dataSurface->WindowShadingControl(curWSC).GlareControlIsActive) {
1015 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "Yes");
1016 : } else {
1017 8 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "No");
1018 : }
1019 8 : } else {
1020 50 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "No");
1021 : }
1022 58 : } break;
1023 1 : case DataSurfaces::SurfaceClass::Door: {
1024 1 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1025 1 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1026 1 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1027 2 : OutputReportPredefined::PreDefTableEntry(
1028 2 : state, state.dataOutRptPredefined->pdchDrCons, surfName, state.dataConstruction->Construct(surface.Construction).Name);
1029 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrZone, surfName, thisZone.Name);
1030 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrSpace, surfName, thisSpace.Name);
1031 1 : OutputReportPredefined::PreDefTableEntry(
1032 1 : state, state.dataOutRptPredefined->pdchDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1033 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrGrArea, surfName, surface.GrossArea * mult);
1034 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrParent, surfName, surface.BaseSurfName);
1035 1 : computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
1036 1 : } break;
1037 16 : default:
1038 16 : break;
1039 : }
1040 620 : } else {
1041 : // interior surfaces
1042 216 : isExterior = false;
1043 216 : if ((surface.Class == DataSurfaces::SurfaceClass::Wall) || (surface.Class == DataSurfaces::SurfaceClass::Floor) ||
1044 18 : (surface.Class == DataSurfaces::SurfaceClass::Roof) || (surface.Class == DataSurfaces::SurfaceClass::IntMass)) {
1045 214 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1046 214 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1047 214 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1048 214 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1049 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpCons, surfName, construct.Name);
1050 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpZone, surfName, thisZone.Name);
1051 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpSpace, surfName, thisSpace.Name);
1052 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAdjSurf, surfName, surface.ExtBoundCondName);
1053 428 : OutputReportPredefined::PreDefTableEntry(
1054 214 : state, state.dataOutRptPredefined->pdchIntOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
1055 214 : OutputReportPredefined::PreDefTableEntry(
1056 214 : state, state.dataOutRptPredefined->pdchIntOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1057 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpGrArea, surfName, surface.GrossArea * mult);
1058 214 : computedNetArea(iSurf) += surface.GrossArea * mult;
1059 214 : curAzimuth = surface.Azimuth;
1060 : // Round to two decimals, like the display in tables
1061 : // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
1062 214 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
1063 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAzimuth, surfName, curAzimuth);
1064 214 : curTilt = surface.Tilt;
1065 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpTilt, surfName, curTilt);
1066 214 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
1067 126 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
1068 67 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "N");
1069 59 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
1070 36 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "E");
1071 23 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
1072 13 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "S");
1073 10 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
1074 10 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "W");
1075 : }
1076 : }
1077 : // interior window report
1078 216 : } else if ((surface.Class == DataSurfaces::SurfaceClass::Window) || (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)) {
1079 0 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1080 0 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1081 0 : mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
1082 0 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1083 0 : if (!has_prefix(surface.Name,
1084 : "iz-")) { // don't count created interzone surfaces that are mirrors of other surfaces
1085 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenCons, surfName, construct.Name);
1086 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenZone, surfName, thisZone.Name);
1087 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSpace, surfName, thisSpace.Name);
1088 : // include the frame area if present
1089 0 : windowArea = surface.GrossArea;
1090 0 : if (surface.FrameDivider != 0) {
1091 0 : frameWidth = state.dataSurface->FrameDivider(surface.FrameDivider).FrameWidth;
1092 0 : frameArea = (surface.Height + 2 * frameWidth) * (surface.Width + 2 * frameWidth) - (surface.Height * surface.Width);
1093 0 : windowArea += frameArea;
1094 : }
1095 0 : windowAreaWMult = windowArea * mult;
1096 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenAreaOf1, surfName, windowArea);
1097 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, surfName, windowAreaWMult);
1098 0 : computedNetArea(surface.BaseSurf) -= windowAreaWMult;
1099 0 : nomUfact = state.dataHeatBal->NominalU(surface.Construction);
1100 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, surfName, nomUfact, 3);
1101 0 : if (!construct.TypeIsAirBoundary) {
1102 : // Solar properties not applicable for air boundary surfaces
1103 : // if the construction report is requested the SummerSHGC is already calculated
1104 0 : if (construct.SummerSHGC != 0) {
1105 0 : SHGCSummer = construct.SummerSHGC;
1106 0 : TransVisNorm = construct.VisTransNorm;
1107 : } else {
1108 : // must calculate Summer SHGC
1109 0 : if (!construct.WindowTypeEQL) {
1110 0 : Window::CalcNominalWindowCond(
1111 : state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
1112 : }
1113 : }
1114 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, surfName, SHGCSummer, 3);
1115 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, surfName, TransVisNorm, 3);
1116 : // compute totals for area weighted averages
1117 0 : intShgcArea += SHGCSummer * windowAreaWMult;
1118 0 : intVistranArea += TransVisNorm * windowAreaWMult;
1119 : }
1120 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenParent, surfName, surface.BaseSurfName);
1121 : // compute totals for area weighted averages
1122 0 : intFenTotArea += windowAreaWMult;
1123 0 : intUfactArea += nomUfact * windowAreaWMult;
1124 : }
1125 2 : } else if (surface.Class == DataSurfaces::SurfaceClass::Door) {
1126 2 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1127 2 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1128 2 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1129 2 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1130 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrCons, surfName, construct.Name);
1131 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrZone, surfName, thisZone.Name);
1132 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrSpace, surfName, thisSpace.Name);
1133 2 : OutputReportPredefined::PreDefTableEntry(
1134 2 : state, state.dataOutRptPredefined->pdchIntDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1135 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrGrArea, surfName, surface.GrossArea * mult);
1136 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrParent, surfName, surface.BaseSurfName);
1137 2 : computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
1138 : }
1139 : }
1140 836 : int currSurfaceClass = int(surface.Class);
1141 836 : assert(currSurfaceClass < int(DataSurfaces::SurfaceClass::Num));
1142 836 : assert(currSurfaceClass > int(DataSurfaces::SurfaceClass::None));
1143 836 : ++numSurfaces(currSurfaceClass);
1144 836 : if (isExterior) {
1145 620 : ++numExtSurfaces(currSurfaceClass);
1146 : }
1147 836 : if (surface.Class == DataSurfaces::SurfaceClass::Window) {
1148 58 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::GlassDoor || surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
1149 4 : ++numSurfaces((int)surface.OriginalClass);
1150 4 : if (isExterior) {
1151 4 : ++numExtSurfaces((int)surface.OriginalClass);
1152 : }
1153 : }
1154 : }
1155 : }
1156 : // for fins and overhangs just add them explicitly since not otherwise classified
1157 114 : int totOverhangs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang") +
1158 114 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang:Projection");
1159 114 : numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
1160 114 : numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
1161 114 : int totFins = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin") +
1162 114 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin:Projection");
1163 114 : numSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
1164 114 : numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
1165 : // go through all the surfaces again and this time insert the net area results
1166 950 : for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
1167 836 : auto const &surface = state.dataSurface->Surface(iSurf);
1168 836 : DataSurfaces::SurfaceClass const SurfaceClass(surface.Class);
1169 : // exterior surfaces including underground
1170 836 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
1171 216 : (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
1172 620 : if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
1173 : (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
1174 545 : surfName = surface.Name;
1175 545 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpNetArea, surfName, computedNetArea(iSurf));
1176 : }
1177 : } else {
1178 216 : if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
1179 : (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
1180 211 : surfName = surface.Name;
1181 211 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpNetArea, surfName, computedNetArea(iSurf));
1182 : }
1183 : } // interior surfaces
1184 : }
1185 : // total
1186 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Total or Average", fenTotArea);
1187 114 : if (fenTotArea > 0.0) {
1188 24 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", ufactArea / fenTotArea, 3);
1189 24 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", shgcArea / fenTotArea, 3);
1190 24 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", vistranArea / fenTotArea, 3);
1191 : } else {
1192 90 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", "-");
1193 90 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", "-");
1194 90 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", "-");
1195 : }
1196 : // north
1197 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "North Total or Average", fenTotAreaNorth);
1198 114 : if (fenTotAreaNorth > 0.0) {
1199 12 : OutputReportPredefined::PreDefTableEntry(
1200 12 : state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", ufactAreaNorth / fenTotAreaNorth, 3);
1201 12 : OutputReportPredefined::PreDefTableEntry(
1202 12 : state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", shgcAreaNorth / fenTotAreaNorth, 3);
1203 12 : OutputReportPredefined::PreDefTableEntry(
1204 18 : state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", vistranAreaNorth / fenTotAreaNorth, 3);
1205 : } else {
1206 108 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", "-");
1207 108 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", "-");
1208 108 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", "-");
1209 : }
1210 : // non-north
1211 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Non-North Total or Average", fenTotAreaNonNorth);
1212 114 : if (fenTotAreaNonNorth > 0.0) {
1213 46 : OutputReportPredefined::PreDefTableEntry(
1214 46 : state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", ufactAreaNonNorth / fenTotAreaNonNorth, 3);
1215 46 : OutputReportPredefined::PreDefTableEntry(
1216 46 : state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", shgcAreaNonNorth / fenTotAreaNonNorth, 3);
1217 46 : OutputReportPredefined::PreDefTableEntry(
1218 69 : state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", vistranAreaNonNorth / fenTotAreaNonNorth, 3);
1219 : } else {
1220 91 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", "-");
1221 91 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", "-");
1222 91 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", "-");
1223 : }
1224 : // interior fenestration totals
1225 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, "Total or Average", intFenTotArea);
1226 114 : if (intFenTotArea > 0.0) {
1227 0 : OutputReportPredefined::PreDefTableEntry(
1228 0 : state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", intUfactArea / intFenTotArea, 3);
1229 0 : OutputReportPredefined::PreDefTableEntry(
1230 0 : state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", intShgcArea / intFenTotArea, 3);
1231 0 : OutputReportPredefined::PreDefTableEntry(
1232 0 : state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", intVistranArea / intFenTotArea, 3);
1233 : } else {
1234 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", "-");
1235 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", "-");
1236 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", "-");
1237 : }
1238 : // counts
1239 114 : OutputReportPredefined::PreDefTableEntry(
1240 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Wall", numSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
1241 114 : OutputReportPredefined::PreDefTableEntry(
1242 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Wall", numExtSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
1243 114 : OutputReportPredefined::PreDefTableEntry(
1244 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Floor", numSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
1245 114 : OutputReportPredefined::PreDefTableEntry(
1246 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Floor", numExtSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
1247 114 : OutputReportPredefined::PreDefTableEntry(
1248 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Roof", numSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
1249 114 : OutputReportPredefined::PreDefTableEntry(
1250 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Roof", numExtSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
1251 114 : OutputReportPredefined::PreDefTableEntry(
1252 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Internal Mass", numSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
1253 114 : OutputReportPredefined::PreDefTableEntry(
1254 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Internal Mass", numExtSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
1255 114 : OutputReportPredefined::PreDefTableEntry(
1256 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Building Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
1257 114 : OutputReportPredefined::PreDefTableEntry(
1258 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Building Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
1259 114 : OutputReportPredefined::PreDefTableEntry(
1260 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Fixed Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
1261 114 : OutputReportPredefined::PreDefTableEntry(
1262 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Fixed Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
1263 114 : OutputReportPredefined::PreDefTableEntry(
1264 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Window", numSurfaces(int(DataSurfaces::SurfaceClass::Window)));
1265 114 : OutputReportPredefined::PreDefTableEntry(
1266 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Window", numExtSurfaces(int(DataSurfaces::SurfaceClass::Window)));
1267 114 : OutputReportPredefined::PreDefTableEntry(
1268 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Door", numSurfaces(int(DataSurfaces::SurfaceClass::Door)));
1269 114 : OutputReportPredefined::PreDefTableEntry(
1270 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::Door)));
1271 114 : OutputReportPredefined::PreDefTableEntry(
1272 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Glass Door", numSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
1273 114 : OutputReportPredefined::PreDefTableEntry(
1274 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Glass Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
1275 114 : OutputReportPredefined::PreDefTableEntry(
1276 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
1277 114 : OutputReportPredefined::PreDefTableEntry(
1278 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
1279 114 : OutputReportPredefined::PreDefTableEntry(
1280 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Overhang", numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
1281 114 : OutputReportPredefined::PreDefTableEntry(
1282 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Overhang", numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
1283 114 : OutputReportPredefined::PreDefTableEntry(
1284 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Fin", numSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
1285 114 : OutputReportPredefined::PreDefTableEntry(
1286 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Fin", numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
1287 114 : OutputReportPredefined::PreDefTableEntry(
1288 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Tubular Daylighting Device Dome", numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
1289 114 : OutputReportPredefined::PreDefTableEntry(state,
1290 114 : state.dataOutRptPredefined->pdchSurfCntExt,
1291 : "Tubular Daylighting Device Dome",
1292 114 : numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
1293 114 : OutputReportPredefined::PreDefTableEntry(state,
1294 114 : state.dataOutRptPredefined->pdchSurfCntTot,
1295 : "Tubular Daylighting Device Diffuser",
1296 114 : numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
1297 114 : OutputReportPredefined::PreDefTableEntry(state,
1298 114 : state.dataOutRptPredefined->pdchSurfCntExt,
1299 : "Tubular Daylighting Device Diffuser",
1300 114 : numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
1301 114 : }
1302 :
1303 145 : void AllocateSurfaceHeatBalArrays(EnergyPlusData &state)
1304 : {
1305 :
1306 : // SUBROUTINE INFORMATION:
1307 : // AUTHOR Richard Liesen
1308 : // DATE WRITTEN February 1998
1309 :
1310 : // METHODOLOGY EMPLOYED:
1311 : // Uses the status flags to trigger variable allocation.
1312 :
1313 : // Use the total number of surfaces to allocate variables to avoid a surface number limit
1314 145 : state.dataHeatBalSurf->SurfCTFConstInPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1315 145 : state.dataHeatBalSurf->SurfCTFConstOutPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1316 145 : state.dataHeatBalSurf->SurfCTFCross0.dimension(state.dataSurface->TotSurfaces, 0.0);
1317 145 : state.dataHeatBalSurf->SurfCTFInside0.dimension(state.dataSurface->TotSurfaces, 0.0);
1318 145 : state.dataHeatBalSurf->SurfTempOutHist.dimension(state.dataSurface->TotSurfaces, 0.0);
1319 145 : state.dataHeatBalSurf->SurfCTFSourceIn0.dimension(state.dataSurface->TotSurfaces, 0.0);
1320 145 : state.dataHeatBalSurf->SurfQSourceSinkHist.dimension(state.dataSurface->TotSurfaces, 0.0);
1321 145 : state.dataHeatBalSurf->SurfIsAdiabatic.dimension(state.dataSurface->TotSurfaces, 0);
1322 145 : state.dataHeatBalSurf->SurfIsSourceOrSink.dimension(state.dataSurface->TotSurfaces, 0);
1323 145 : state.dataHeatBalSurf->SurfIsOperatingPool.dimension(state.dataSurface->TotSurfaces, 0);
1324 145 : state.dataHeatBalSurf->SurfTempTerm.dimension(state.dataSurface->TotSurfaces, 0);
1325 145 : state.dataHeatBalSurf->SurfTempDiv.dimension(state.dataSurface->TotSurfaces, 0);
1326 145 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
1327 2 : state.dataHeatBalFanSys->CTFTsrcConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1328 2 : state.dataHeatBalFanSys->CTFTuserConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1329 : }
1330 :
1331 145 : state.dataHeatBal->SurfTempEffBulkAir.dimension(state.dataSurface->TotSurfaces, DataHeatBalance::ZoneInitialTemp);
1332 145 : state.dataHeatBalSurf->SurfHConvInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1333 145 : state.dataHeatBalSurf->SurfHConvExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1334 145 : state.dataHeatBalSurf->SurfHAirExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1335 145 : state.dataHeatBalSurf->SurfHSkyExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1336 145 : state.dataHeatBalSurf->SurfHGrdExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1337 145 : state.dataHeatBalSurf->SurfHSrdSurfExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1338 :
1339 145 : state.dataHeatBalSurf->SurfTempIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1340 145 : state.dataHeatBalSurf->SurfTempInsOld.dimension(state.dataSurface->TotSurfaces, 0.0);
1341 145 : state.dataHeatBalSurf->SurfTempInTmp.dimension(state.dataSurface->TotSurfaces, 0.0);
1342 145 : state.dataHeatBalSurfMgr->RefAirTemp.dimension(state.dataSurface->TotSurfaces, 0.0);
1343 145 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs.dimension(state.dataSurface->TotSurfaces, 0.0);
1344 :
1345 145 : state.dataHeatBal->SurfWinQRadSWwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL + 1, 0.0);
1346 145 : state.dataHeatBal->SurfWinInitialDifSolwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL, 0.0);
1347 145 : state.dataHeatBalSurf->SurfQRadSWOutMvIns.dimension(state.dataSurface->TotSurfaces, 0.0);
1348 145 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1349 145 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside.dimension(state.dataSurface->TotSurfaces, 0.0);
1350 145 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside.dimension(state.dataSurface->TotSurfaces, 0.0);
1351 :
1352 145 : state.dataHeatBalSurf->SurfInsideTempHist.allocate(Construction::MaxCTFTerms);
1353 145 : state.dataHeatBalSurf->SurfOutsideTempHist.allocate(Construction::MaxCTFTerms);
1354 145 : state.dataHeatBalSurf->SurfInsideFluxHist.allocate(Construction::MaxCTFTerms);
1355 145 : state.dataHeatBalSurf->SurfOutsideFluxHist.allocate(Construction::MaxCTFTerms);
1356 2900 : for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
1357 2755 : state.dataHeatBalSurf->SurfInsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1358 2755 : state.dataHeatBalSurf->SurfOutsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1359 2755 : state.dataHeatBalSurf->SurfInsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1360 2755 : state.dataHeatBalSurf->SurfOutsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1361 : }
1362 :
1363 145 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
1364 26 : state.dataHeatBalSurf->SurfCurrNumHist.dimension(state.dataSurface->TotSurfaces, 0);
1365 :
1366 26 : state.dataHeatBalSurf->SurfInsideTempHistMaster.allocate(Construction::MaxCTFTerms);
1367 26 : state.dataHeatBalSurf->SurfOutsideTempHistMaster.allocate(Construction::MaxCTFTerms);
1368 26 : state.dataHeatBalSurf->SurfInsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
1369 26 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
1370 :
1371 520 : for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
1372 494 : state.dataHeatBalSurf->SurfInsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1373 494 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1374 494 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1375 494 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1376 : }
1377 : }
1378 :
1379 145 : state.dataHeatBalSurf->SurfTempOut.dimension(state.dataSurface->TotSurfaces, 0.0);
1380 145 : state.dataHeatBalSurf->SurfTempInMovInsRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1381 145 : state.dataHeatBalSurf->SurfQConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1382 145 : state.dataHeatBalSurf->SurfQdotConvInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1383 145 : state.dataHeatBalSurf->SurfQdotConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1384 :
1385 145 : state.dataHeatBalSurf->SurfQRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1386 145 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1387 :
1388 145 : state.dataHeatBalSurf->SurfQRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1389 145 : state.dataHeatBalSurf->SurfQdotRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1390 145 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1391 :
1392 145 : state.dataHeatBalSurf->SurfQRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1393 145 : state.dataHeatBalSurf->SurfQdotRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1394 :
1395 145 : state.dataHeatBalSurf->SurfQRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1396 145 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1397 :
1398 145 : state.dataHeatBalSurf->SurfQRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1399 145 : state.dataHeatBalSurf->SurfQdotRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1400 145 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1401 :
1402 145 : state.dataHeatBalSurf->SurfQConvOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1403 145 : state.dataHeatBalSurf->SurfQdotConvOutPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1404 145 : state.dataHeatBalSurf->SurfQdotConvOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1405 :
1406 145 : state.dataHeatBalSurf->SurfQdotRadOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1407 145 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1408 145 : state.dataHeatBalSurf->SurfQRadOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1409 :
1410 145 : state.dataHeatBalSurf->SurfQAirExtReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1411 145 : state.dataHeatBalSurf->SurfQHeatEmiReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1412 :
1413 145 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1414 145 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1415 :
1416 145 : state.dataHeatBalSurf->SurfOpaqInsFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1417 145 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1418 145 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1419 145 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1420 145 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1421 :
1422 145 : state.dataHeatBalSurf->SurfOpaqOutFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1423 145 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1424 145 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1425 145 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1426 145 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1427 :
1428 145 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1429 145 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1430 145 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1431 145 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1432 145 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1433 :
1434 145 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1435 145 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1436 145 : state.dataHeatBalSurf->SurfOpaqStorageCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1437 145 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1438 145 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1439 :
1440 145 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed.dimension(state.dataSurface->TotSurfaces, 0.0);
1441 :
1442 145 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1443 145 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1444 :
1445 145 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1446 145 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
1447 145 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
1448 :
1449 145 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1450 145 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1451 :
1452 145 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
1453 2 : state.dataHeatBalSurf->SurfTempSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1454 2 : state.dataHeatBalSurf->SurfTempUserLoc.dimension(state.dataSurface->TotSurfaces, 0.0);
1455 2 : state.dataHeatBalSurf->SurfTsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1456 2 : state.dataHeatBalSurf->SurfTuserHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1457 2 : state.dataHeatBalSurf->SurfQsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1458 2 : state.dataHeatBalSurf->SurfTsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1459 2 : state.dataHeatBalSurf->SurfTuserHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1460 2 : state.dataHeatBalSurf->SurfQsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1461 : }
1462 :
1463 145 : state.dataHeatBalFanSys->RadSysTiHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1464 145 : state.dataHeatBalFanSys->RadSysTiHBToutCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1465 145 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1466 145 : state.dataHeatBalFanSys->RadSysToHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1467 145 : state.dataHeatBalFanSys->RadSysToHBTinCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1468 145 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1469 145 : state.dataHeatBalFanSys->QRadSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1470 145 : state.dataHeatBalFanSys->TCondFDSourceNode.dimension(state.dataSurface->TotSurfaces, 15.0);
1471 145 : state.dataHeatBalFanSys->surfQRadFromHVAC.allocate(state.dataSurface->TotSurfaces);
1472 145 : state.dataHeatBalFanSys->QRadSurfAFNDuct.dimension(state.dataSurface->TotSurfaces, 0.0);
1473 :
1474 : // allocate terms used for pool surface heat balance
1475 145 : state.dataHeatBalFanSys->QPoolSurfNumerator.dimension(state.dataSurface->TotSurfaces, 0.0);
1476 145 : state.dataHeatBalFanSys->PoolHeatTransCoefs.dimension(state.dataSurface->TotSurfaces, 0.0);
1477 :
1478 : // allocate term used as sink for PV electricity
1479 145 : state.dataHeatBalFanSys->QPVSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1480 :
1481 : // Allocate the moisture balance arrays
1482 145 : state.dataMstBal->TempOutsideAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1483 145 : state.dataMstBal->RhoVaporAirOut.dimension(state.dataSurface->TotSurfaces, 0.0);
1484 145 : state.dataMstBal->RhoVaporSurfIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1485 145 : state.dataMstBal->RhoVaporAirIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1486 145 : state.dataMstBal->HConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1487 145 : state.dataMstBal->HMassConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1488 145 : state.dataMstBal->HConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1489 145 : state.dataMstBal->HMassConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1490 145 : state.dataMstBal->HSkyFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1491 145 : state.dataMstBal->HGrndFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1492 145 : state.dataMstBal->HAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1493 :
1494 145 : state.dataSurface->SurfSkySolarInc.dimension(state.dataSurface->TotSurfaces, 0);
1495 145 : state.dataSurface->SurfGndSolarInc.dimension(state.dataSurface->TotSurfaces, 0);
1496 :
1497 145 : state.dataHeatBalSurf->SurfAbsSolarExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1498 145 : state.dataHeatBalSurf->SurfAbsThermalExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1499 145 : state.dataHeatBalSurf->SurfRoughnessExt.dimension(state.dataSurface->TotSurfaces, Material::SurfaceRoughness::Invalid);
1500 145 : state.dataHeatBalSurf->SurfAbsSolarInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1501 145 : state.dataHeatBalSurf->SurfAbsThermalInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1502 :
1503 145 : DisplayString(state, "Setting up Surface Reporting Variables");
1504 : // Setup surface report variables CurrentModuleObject='Opaque Surfaces'
1505 1166 : for (int loop = 1; loop <= state.dataSurface->TotSurfaces; ++loop) {
1506 1021 : auto &surface = state.dataSurface->Surface(loop);
1507 1021 : if (!surface.HeatTransSurf) continue;
1508 1994 : SetupOutputVariable(state,
1509 : "Surface Inside Face Temperature",
1510 : Constant::Units::C,
1511 997 : state.dataHeatBalSurf->SurfTempIn(loop),
1512 : OutputProcessor::TimeStepType::Zone,
1513 : OutputProcessor::StoreType::Average,
1514 997 : surface.Name);
1515 1994 : SetupOutputVariable(state,
1516 : "Surface Inside Face Interior Movable Insulation Temperature",
1517 : Constant::Units::C,
1518 997 : state.dataHeatBalSurf->SurfTempInMovInsRep(loop),
1519 : OutputProcessor::TimeStepType::Zone,
1520 : OutputProcessor::StoreType::Average,
1521 997 : surface.Name);
1522 :
1523 997 : if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
1524 1994 : SetupOutputVariable(state,
1525 : "Surface Outside Face Temperature",
1526 : Constant::Units::C,
1527 997 : state.dataHeatBalSurf->SurfTempOut(loop),
1528 : OutputProcessor::TimeStepType::Zone,
1529 : OutputProcessor::StoreType::Average,
1530 997 : surface.Name);
1531 : }
1532 :
1533 1994 : SetupOutputVariable(state,
1534 : "Surface Inside Face Adjacent Air Temperature",
1535 : Constant::Units::C,
1536 997 : state.dataHeatBal->SurfTempEffBulkAir(loop),
1537 : OutputProcessor::TimeStepType::Zone,
1538 : OutputProcessor::StoreType::Average,
1539 997 : surface.Name);
1540 1994 : SetupOutputVariable(state,
1541 : "Surface Inside Face Convection Heat Transfer Coefficient",
1542 : Constant::Units::W_m2K,
1543 997 : state.dataHeatBalSurf->SurfHConvInt(loop),
1544 : OutputProcessor::TimeStepType::Zone,
1545 : OutputProcessor::StoreType::Average,
1546 997 : surface.Name);
1547 1994 : SetupOutputVariable(state,
1548 : "Surface Inside Face Convection Heat Gain Rate",
1549 : Constant::Units::W,
1550 997 : state.dataHeatBalSurf->SurfQdotConvInRep(loop),
1551 : OutputProcessor::TimeStepType::Zone,
1552 : OutputProcessor::StoreType::Average,
1553 997 : surface.Name);
1554 1994 : SetupOutputVariable(state,
1555 : "Surface Inside Face Convection Heat Gain Rate per Area",
1556 : Constant::Units::W_m2,
1557 997 : state.dataHeatBalSurf->SurfQdotConvInPerArea(loop),
1558 : OutputProcessor::TimeStepType::Zone,
1559 : OutputProcessor::StoreType::Average,
1560 997 : surface.Name);
1561 1994 : SetupOutputVariable(state,
1562 : "Surface Inside Face Convection Heat Gain Energy",
1563 : Constant::Units::J,
1564 997 : state.dataHeatBalSurf->SurfQConvInRep(loop),
1565 : OutputProcessor::TimeStepType::Zone,
1566 : OutputProcessor::StoreType::Sum,
1567 997 : surface.Name);
1568 :
1569 1994 : SetupOutputVariable(state,
1570 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate",
1571 : Constant::Units::W,
1572 997 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(loop),
1573 : OutputProcessor::TimeStepType::Zone,
1574 : OutputProcessor::StoreType::Average,
1575 997 : surface.Name);
1576 1994 : SetupOutputVariable(state,
1577 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate per Area",
1578 : Constant::Units::W_m2,
1579 997 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(loop),
1580 : OutputProcessor::TimeStepType::Zone,
1581 : OutputProcessor::StoreType::Average,
1582 997 : surface.Name);
1583 1994 : SetupOutputVariable(state,
1584 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy",
1585 : Constant::Units::J,
1586 997 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(loop),
1587 : OutputProcessor::TimeStepType::Zone,
1588 : OutputProcessor::StoreType::Sum,
1589 997 : surface.Name);
1590 :
1591 997 : if (surface.Class != DataSurfaces::SurfaceClass::Window) {
1592 1884 : SetupOutputVariable(state,
1593 : "Surface Inside Face Solar Radiation Heat Gain Rate",
1594 : Constant::Units::W,
1595 942 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(loop),
1596 : OutputProcessor::TimeStepType::Zone,
1597 : OutputProcessor::StoreType::Average,
1598 942 : surface.Name);
1599 1884 : SetupOutputVariable(state,
1600 : "Surface Inside Face Solar Radiation Heat Gain Rate per Area",
1601 : Constant::Units::W_m2,
1602 942 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(loop),
1603 : OutputProcessor::TimeStepType::Zone,
1604 : OutputProcessor::StoreType::Average,
1605 942 : surface.Name);
1606 1884 : SetupOutputVariable(state,
1607 : "Surface Inside Face Solar Radiation Heat Gain Energy",
1608 : Constant::Units::J,
1609 942 : state.dataHeatBalSurf->SurfQRadSolarInRep(loop),
1610 : OutputProcessor::TimeStepType::Zone,
1611 : OutputProcessor::StoreType::Sum,
1612 942 : surface.Name);
1613 :
1614 1884 : SetupOutputVariable(state,
1615 : "Surface Inside Face Lights Radiation Heat Gain Rate",
1616 : Constant::Units::W,
1617 942 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(loop),
1618 : OutputProcessor::TimeStepType::Zone,
1619 : OutputProcessor::StoreType::Average,
1620 942 : surface.Name);
1621 1884 : SetupOutputVariable(state,
1622 : "Surface Inside Face Lights Radiation Heat Gain Rate per Area",
1623 : Constant::Units::W_m2,
1624 942 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(loop),
1625 : OutputProcessor::TimeStepType::Zone,
1626 : OutputProcessor::StoreType::Average,
1627 942 : surface.Name);
1628 1884 : SetupOutputVariable(state,
1629 : "Surface Inside Face Lights Radiation Heat Gain Energy",
1630 : Constant::Units::J,
1631 942 : state.dataHeatBalSurf->SurfQRadLightsInRep(loop),
1632 : OutputProcessor::TimeStepType::Zone,
1633 : OutputProcessor::StoreType::Sum,
1634 942 : surface.Name);
1635 : }
1636 :
1637 1994 : SetupOutputVariable(state,
1638 : "Surface Inside Face Internal Gains Radiation Heat Gain Rate",
1639 : Constant::Units::W,
1640 997 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(loop),
1641 : OutputProcessor::TimeStepType::Zone,
1642 : OutputProcessor::StoreType::Average,
1643 997 : surface.Name);
1644 1994 : SetupOutputVariable(state,
1645 : "Surface Inside Face Internal Gains Radiation Heat Gain Rate per Area",
1646 : Constant::Units::W_m2,
1647 997 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(loop),
1648 : OutputProcessor::TimeStepType::Zone,
1649 : OutputProcessor::StoreType::Average,
1650 997 : surface.Name);
1651 1994 : SetupOutputVariable(state,
1652 : "Surface Inside Face Internal Gains Radiation Heat Gain Energy",
1653 : Constant::Units::J,
1654 997 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(loop),
1655 : OutputProcessor::TimeStepType::Zone,
1656 : OutputProcessor::StoreType::Sum,
1657 997 : surface.Name);
1658 :
1659 1994 : SetupOutputVariable(state,
1660 : "Surface Inside Face System Radiation Heat Gain Rate",
1661 : Constant::Units::W,
1662 997 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(loop),
1663 : OutputProcessor::TimeStepType::Zone,
1664 : OutputProcessor::StoreType::Average,
1665 997 : surface.Name);
1666 1994 : SetupOutputVariable(state,
1667 : "Surface Inside Face System Radiation Heat Gain Rate per Area",
1668 : Constant::Units::W_m2,
1669 997 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(loop),
1670 : OutputProcessor::TimeStepType::Zone,
1671 : OutputProcessor::StoreType::Average,
1672 997 : surface.Name);
1673 1994 : SetupOutputVariable(state,
1674 : "Surface Inside Face System Radiation Heat Gain Energy",
1675 : Constant::Units::J,
1676 997 : state.dataHeatBalSurf->SurfQRadHVACInRep(loop),
1677 : OutputProcessor::TimeStepType::Zone,
1678 : OutputProcessor::StoreType::Sum,
1679 997 : surface.Name);
1680 :
1681 997 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment || state.dataGlobal->DisplayAdvancedReportVariables) {
1682 1434 : SetupOutputVariable(state,
1683 : "Surface Outside Face Outdoor Air Drybulb Temperature",
1684 : Constant::Units::C,
1685 717 : state.dataSurface->SurfOutDryBulbTemp(loop),
1686 : OutputProcessor::TimeStepType::Zone,
1687 : OutputProcessor::StoreType::Average,
1688 717 : surface.Name);
1689 1434 : SetupOutputVariable(state,
1690 : "Surface Outside Face Outdoor Air Wetbulb Temperature",
1691 : Constant::Units::C,
1692 717 : state.dataSurface->SurfOutWetBulbTemp(loop),
1693 : OutputProcessor::TimeStepType::Zone,
1694 : OutputProcessor::StoreType::Average,
1695 717 : surface.Name);
1696 1434 : SetupOutputVariable(state,
1697 : "Surface Outside Face Outdoor Air Wind Speed",
1698 : Constant::Units::m_s,
1699 717 : state.dataSurface->SurfOutWindSpeed(loop),
1700 : OutputProcessor::TimeStepType::Zone,
1701 : OutputProcessor::StoreType::Average,
1702 717 : surface.Name);
1703 1434 : SetupOutputVariable(state,
1704 : "Surface Outside Face Outdoor Air Wind Direction",
1705 : Constant::Units::deg,
1706 717 : state.dataSurface->SurfOutWindDir(loop),
1707 : OutputProcessor::TimeStepType::Zone,
1708 : OutputProcessor::StoreType::Average,
1709 717 : surface.Name);
1710 1434 : SetupOutputVariable(state,
1711 : "Surface Outside Face Convection Heat Gain Rate",
1712 : Constant::Units::W,
1713 717 : state.dataHeatBalSurf->SurfQdotConvOutRep(loop),
1714 : OutputProcessor::TimeStepType::Zone,
1715 : OutputProcessor::StoreType::Average,
1716 717 : surface.Name);
1717 1434 : SetupOutputVariable(state,
1718 : "Surface Outside Face Convection Heat Gain Rate per Area",
1719 : Constant::Units::W_m2,
1720 717 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(loop),
1721 : OutputProcessor::TimeStepType::Zone,
1722 : OutputProcessor::StoreType::Average,
1723 717 : surface.Name);
1724 1434 : SetupOutputVariable(state,
1725 : "Surface Outside Face Convection Heat Gain Energy",
1726 : Constant::Units::J,
1727 717 : state.dataHeatBalSurf->SurfQConvOutReport(loop),
1728 : OutputProcessor::TimeStepType::Zone,
1729 : OutputProcessor::StoreType::Sum,
1730 717 : surface.Name);
1731 1434 : SetupOutputVariable(state,
1732 : "Surface Outside Face Convection Heat Transfer Coefficient",
1733 : Constant::Units::W_m2K,
1734 717 : state.dataHeatBalSurf->SurfHConvExt(loop),
1735 : OutputProcessor::TimeStepType::Zone,
1736 : OutputProcessor::StoreType::Average,
1737 717 : surface.Name);
1738 1434 : SetupOutputVariable(state,
1739 : "Surface Outside Face Net Thermal Radiation Heat Gain Rate",
1740 : Constant::Units::W,
1741 717 : state.dataHeatBalSurf->SurfQdotRadOutRep(loop),
1742 : OutputProcessor::TimeStepType::Zone,
1743 : OutputProcessor::StoreType::Average,
1744 717 : surface.Name);
1745 1434 : SetupOutputVariable(state,
1746 : "Surface Outside Face Net Thermal Radiation Heat Gain Rate per Area",
1747 : Constant::Units::W_m2,
1748 717 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(loop),
1749 : OutputProcessor::TimeStepType::Zone,
1750 : OutputProcessor::StoreType::Average,
1751 717 : surface.Name);
1752 1434 : SetupOutputVariable(state,
1753 : "Surface Outside Face Net Thermal Radiation Heat Gain Energy",
1754 : Constant::Units::J,
1755 717 : state.dataHeatBalSurf->SurfQRadOutReport(loop),
1756 : OutputProcessor::TimeStepType::Zone,
1757 : OutputProcessor::StoreType::Sum,
1758 717 : surface.Name);
1759 1434 : SetupOutputVariable(state,
1760 : "Surface Outside Face Thermal Radiation to Air Heat Transfer Coefficient",
1761 : Constant::Units::W_m2K,
1762 717 : state.dataHeatBalSurf->SurfHAirExt(loop),
1763 : OutputProcessor::TimeStepType::Zone,
1764 : OutputProcessor::StoreType::Average,
1765 717 : surface.Name);
1766 1434 : SetupOutputVariable(state,
1767 : "Surface Outside Face Thermal Radiation to Sky Heat Transfer Coefficient",
1768 : Constant::Units::W_m2K,
1769 717 : state.dataHeatBalSurf->SurfHSkyExt(loop),
1770 : OutputProcessor::TimeStepType::Zone,
1771 : OutputProcessor::StoreType::Average,
1772 717 : surface.Name);
1773 1434 : SetupOutputVariable(state,
1774 : "Surface Outside Face Thermal Radiation to Ground Heat Transfer Coefficient",
1775 : Constant::Units::W_m2K,
1776 717 : state.dataHeatBalSurf->SurfHGrdExt(loop),
1777 : OutputProcessor::TimeStepType::Zone,
1778 : OutputProcessor::StoreType::Average,
1779 717 : surface.Name);
1780 1434 : SetupOutputVariable(state,
1781 : "Surface Outside Face Thermal Radiation to Air Heat Transfer Rate",
1782 : Constant::Units::W,
1783 717 : state.dataHeatBalSurf->SurfQAirExtReport(loop),
1784 : OutputProcessor::TimeStepType::Zone,
1785 : OutputProcessor::StoreType::Average,
1786 717 : surface.Name);
1787 1434 : SetupOutputVariable(state,
1788 : "Surface Outside Face Heat Emission to Air Rate",
1789 : Constant::Units::W,
1790 717 : state.dataHeatBalSurf->SurfQHeatEmiReport(loop),
1791 : OutputProcessor::TimeStepType::Zone,
1792 : OutputProcessor::StoreType::Average,
1793 717 : surface.Name);
1794 :
1795 717 : if (surface.Class != DataSurfaces::SurfaceClass::Window) {
1796 1324 : SetupOutputVariable(state,
1797 : "Surface Outside Face Solar Radiation Heat Gain Rate",
1798 : Constant::Units::W,
1799 662 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(loop),
1800 : OutputProcessor::TimeStepType::Zone,
1801 : OutputProcessor::StoreType::Average,
1802 662 : surface.Name);
1803 1324 : SetupOutputVariable(state,
1804 : "Surface Outside Face Solar Radiation Heat Gain Rate per Area",
1805 : Constant::Units::W_m2,
1806 662 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(loop),
1807 : OutputProcessor::TimeStepType::Zone,
1808 : OutputProcessor::StoreType::Average,
1809 662 : surface.Name);
1810 1324 : SetupOutputVariable(state,
1811 : "Surface Outside Face Solar Radiation Heat Gain Energy",
1812 : Constant::Units::J,
1813 662 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(loop),
1814 : OutputProcessor::TimeStepType::Zone,
1815 : OutputProcessor::StoreType::Sum,
1816 662 : surface.Name);
1817 : }
1818 : }
1819 997 : if (surface.Class == DataSurfaces::SurfaceClass::Floor || surface.Class == DataSurfaces::SurfaceClass::Wall ||
1820 224 : surface.Class == DataSurfaces::SurfaceClass::IntMass || surface.Class == DataSurfaces::SurfaceClass::Roof ||
1821 58 : surface.Class == DataSurfaces::SurfaceClass::Door) {
1822 : // IF (DisplayAdvancedReportVariables) THEN !CurrentModuleObject='Opaque Surfaces(Advanced)'
1823 1880 : SetupOutputVariable(state,
1824 : "Surface Inside Face Conduction Heat Transfer Rate",
1825 : Constant::Units::W,
1826 940 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(loop),
1827 : OutputProcessor::TimeStepType::Zone,
1828 : OutputProcessor::StoreType::Average,
1829 940 : surface.Name);
1830 1880 : SetupOutputVariable(state,
1831 : "Surface Inside Face Conduction Heat Gain Rate",
1832 : Constant::Units::W,
1833 940 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(loop),
1834 : OutputProcessor::TimeStepType::Zone,
1835 : OutputProcessor::StoreType::Average,
1836 940 : surface.Name);
1837 1880 : SetupOutputVariable(state,
1838 : "Surface Inside Face Conduction Heat Loss Rate",
1839 : Constant::Units::W,
1840 940 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(loop),
1841 : OutputProcessor::TimeStepType::Zone,
1842 : OutputProcessor::StoreType::Average,
1843 940 : surface.Name);
1844 1880 : SetupOutputVariable(state,
1845 : "Surface Inside Face Conduction Heat Transfer Rate per Area",
1846 : Constant::Units::W_m2,
1847 940 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(loop),
1848 : OutputProcessor::TimeStepType::Zone,
1849 : OutputProcessor::StoreType::Average,
1850 940 : surface.Name);
1851 1880 : SetupOutputVariable(state,
1852 : "Surface Inside Face Conduction Heat Transfer Energy",
1853 : Constant::Units::J,
1854 940 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(loop),
1855 : OutputProcessor::TimeStepType::Zone,
1856 : OutputProcessor::StoreType::Sum,
1857 940 : surface.Name);
1858 :
1859 940 : if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
1860 1880 : SetupOutputVariable(state,
1861 : "Surface Outside Face Conduction Heat Transfer Rate",
1862 : Constant::Units::W,
1863 940 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(loop),
1864 : OutputProcessor::TimeStepType::Zone,
1865 : OutputProcessor::StoreType::Average,
1866 940 : surface.Name);
1867 1880 : SetupOutputVariable(state,
1868 : "Surface Outside Face Conduction Heat Gain Rate",
1869 : Constant::Units::W,
1870 940 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(loop),
1871 : OutputProcessor::TimeStepType::Zone,
1872 : OutputProcessor::StoreType::Average,
1873 940 : surface.Name);
1874 1880 : SetupOutputVariable(state,
1875 : "Surface Outside Face Conduction Heat Loss Rate",
1876 : Constant::Units::W,
1877 940 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(loop),
1878 : OutputProcessor::TimeStepType::Zone,
1879 : OutputProcessor::StoreType::Average,
1880 940 : surface.Name);
1881 1880 : SetupOutputVariable(state,
1882 : "Surface Outside Face Conduction Heat Transfer Rate per Area",
1883 : Constant::Units::W_m2,
1884 940 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(loop),
1885 : OutputProcessor::TimeStepType::Zone,
1886 : OutputProcessor::StoreType::Average,
1887 940 : surface.Name);
1888 1880 : SetupOutputVariable(state,
1889 : "Surface Outside Face Conduction Heat Transfer Energy",
1890 : Constant::Units::J,
1891 940 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(loop),
1892 : OutputProcessor::TimeStepType::Zone,
1893 : OutputProcessor::StoreType::Sum,
1894 940 : surface.Name);
1895 :
1896 1880 : SetupOutputVariable(state,
1897 : "Surface Average Face Conduction Heat Transfer Rate",
1898 : Constant::Units::W,
1899 940 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(loop),
1900 : OutputProcessor::TimeStepType::Zone,
1901 : OutputProcessor::StoreType::Average,
1902 940 : surface.Name);
1903 1880 : SetupOutputVariable(state,
1904 : "Surface Average Face Conduction Heat Gain Rate",
1905 : Constant::Units::W,
1906 940 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(loop),
1907 : OutputProcessor::TimeStepType::Zone,
1908 : OutputProcessor::StoreType::Average,
1909 940 : surface.Name);
1910 1880 : SetupOutputVariable(state,
1911 : "Surface Average Face Conduction Heat Loss Rate",
1912 : Constant::Units::W,
1913 940 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(loop),
1914 : OutputProcessor::TimeStepType::Zone,
1915 : OutputProcessor::StoreType::Average,
1916 940 : surface.Name);
1917 1880 : SetupOutputVariable(state,
1918 : "Surface Average Face Conduction Heat Transfer Rate per Area",
1919 : Constant::Units::W_m2,
1920 940 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(loop),
1921 : OutputProcessor::TimeStepType::Zone,
1922 : OutputProcessor::StoreType::Average,
1923 940 : surface.Name);
1924 1880 : SetupOutputVariable(state,
1925 : "Surface Average Face Conduction Heat Transfer Energy",
1926 : Constant::Units::J,
1927 940 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(loop),
1928 : OutputProcessor::TimeStepType::Zone,
1929 : OutputProcessor::StoreType::Sum,
1930 940 : surface.Name);
1931 :
1932 1880 : SetupOutputVariable(state,
1933 : "Surface Heat Storage Rate",
1934 : Constant::Units::W,
1935 940 : state.dataHeatBalSurf->SurfOpaqStorageCond(loop),
1936 : OutputProcessor::TimeStepType::Zone,
1937 : OutputProcessor::StoreType::Average,
1938 940 : surface.Name);
1939 1880 : SetupOutputVariable(state,
1940 : "Surface Heat Storage Gain Rate",
1941 : Constant::Units::W,
1942 940 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(loop),
1943 : OutputProcessor::TimeStepType::Zone,
1944 : OutputProcessor::StoreType::Average,
1945 940 : surface.Name);
1946 1880 : SetupOutputVariable(state,
1947 : "Surface Heat Storage Loss Rate",
1948 : Constant::Units::W,
1949 940 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(loop),
1950 : OutputProcessor::TimeStepType::Zone,
1951 : OutputProcessor::StoreType::Average,
1952 940 : surface.Name);
1953 1880 : SetupOutputVariable(state,
1954 : "Surface Heat Storage Rate per Area",
1955 : Constant::Units::W_m2,
1956 940 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux(loop),
1957 : OutputProcessor::TimeStepType::Zone,
1958 : OutputProcessor::StoreType::Average,
1959 940 : surface.Name);
1960 1880 : SetupOutputVariable(state,
1961 : "Surface Heat Storage Energy",
1962 : Constant::Units::J,
1963 940 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(loop),
1964 : OutputProcessor::TimeStepType::Zone,
1965 : OutputProcessor::StoreType::Sum,
1966 940 : surface.Name);
1967 : }
1968 :
1969 : // ENDIF
1970 : // CurrentModuleObject='Opaque Surfaces'
1971 :
1972 1880 : SetupOutputVariable(state,
1973 : "Surface Inside Face Beam Solar Radiation Heat Gain Rate",
1974 : Constant::Units::W,
1975 940 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(loop),
1976 : OutputProcessor::TimeStepType::Zone,
1977 : OutputProcessor::StoreType::Average,
1978 940 : surface.Name);
1979 : }
1980 997 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
1981 2 : SetupOutputVariable(state,
1982 : "Surface Internal Source Location Temperature",
1983 : Constant::Units::C,
1984 1 : state.dataHeatBalSurf->SurfTempSource(loop),
1985 : OutputProcessor::TimeStepType::Zone,
1986 : OutputProcessor::StoreType::Average,
1987 1 : surface.Name);
1988 2 : SetupOutputVariable(state,
1989 : "Surface Internal User Specified Location Temperature",
1990 : Constant::Units::C,
1991 1 : state.dataHeatBalSurf->SurfTempUserLoc(loop),
1992 : OutputProcessor::TimeStepType::Zone,
1993 : OutputProcessor::StoreType::Average,
1994 1 : surface.Name);
1995 : }
1996 :
1997 997 : if (surface.Class == DataSurfaces::SurfaceClass::Window) { // CurrentModuleObject='Windows'
1998 55 : auto &surfShade = state.dataSurface->surfShades(loop);
1999 110 : SetupOutputVariable(state,
2000 : "Surface Shading Device Is On Time Fraction",
2001 : Constant::Units::None,
2002 55 : state.dataSurface->SurfWinFracTimeShadingDeviceOn(loop),
2003 : OutputProcessor::TimeStepType::Zone,
2004 : OutputProcessor::StoreType::Average,
2005 55 : surface.Name);
2006 55 : SetupOutputVariable(state,
2007 : "Surface Storm Window On Off Status",
2008 : Constant::Units::None,
2009 55 : state.dataSurface->SurfWinStormWinFlag(loop),
2010 : OutputProcessor::TimeStepType::Zone,
2011 : OutputProcessor::StoreType::Average,
2012 55 : surface.Name);
2013 110 : SetupOutputVariable(state,
2014 : "Surface Window Blind Slat Angle",
2015 : Constant::Units::deg,
2016 55 : surfShade.blind.slatAngDeg,
2017 : OutputProcessor::TimeStepType::Zone,
2018 : OutputProcessor::StoreType::Average,
2019 55 : surface.Name);
2020 : }
2021 : // IF (DisplayAdvancedReportVariables) THEN !CurrentModuleObject='Opaque Surfaces(Advanced)'
2022 997 : SetupOutputVariable(state,
2023 : "Surface Inside Face Convection Classification Index",
2024 : Constant::Units::None,
2025 997 : state.dataSurface->surfIntConv(loop).convClassRpt,
2026 : OutputProcessor::TimeStepType::Zone,
2027 : OutputProcessor::StoreType::Average,
2028 997 : surface.Name);
2029 997 : SetupOutputVariable(state,
2030 : "Surface Inside Face Convection Model Equation Index",
2031 : Constant::Units::None,
2032 997 : state.dataSurface->surfIntConv(loop).hcModelEqRpt,
2033 : OutputProcessor::TimeStepType::Zone,
2034 : OutputProcessor::StoreType::Average,
2035 997 : surface.Name);
2036 997 : SetupOutputVariable(state,
2037 : "Surface Inside Face Convection Reference Air Index",
2038 : Constant::Units::None,
2039 997 : state.dataSurface->SurfTAirRefRpt(loop),
2040 : OutputProcessor::TimeStepType::Zone,
2041 : OutputProcessor::StoreType::Average,
2042 997 : surface.Name);
2043 997 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
2044 716 : SetupOutputVariable(state,
2045 : "Surface Outside Face Convection Classification Index",
2046 : Constant::Units::None,
2047 716 : state.dataSurface->surfExtConv(loop).convClassRpt,
2048 : OutputProcessor::TimeStepType::Zone,
2049 : OutputProcessor::StoreType::Average,
2050 716 : surface.Name);
2051 716 : SetupOutputVariable(state,
2052 : "Surface Outside Face Forced Convection Model Equation Index",
2053 : Constant::Units::None,
2054 716 : state.dataSurface->surfExtConv(loop).hfModelEqRpt,
2055 : OutputProcessor::TimeStepType::Zone,
2056 : OutputProcessor::StoreType::Average,
2057 716 : surface.Name);
2058 716 : SetupOutputVariable(state,
2059 : "Surface Outside Face Natural Convection Model Equation Index",
2060 : Constant::Units::None,
2061 716 : state.dataSurface->surfExtConv(loop).hnModelEqRpt,
2062 : OutputProcessor::TimeStepType::Zone,
2063 : OutputProcessor::StoreType::Average,
2064 716 : surface.Name);
2065 : }
2066 :
2067 1994 : SetupOutputVariable(state,
2068 : "Surface Inside Face Heat Source Gain Rate per Area",
2069 : Constant::Units::W_m2,
2070 997 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(loop),
2071 : OutputProcessor::TimeStepType::Zone,
2072 : OutputProcessor::StoreType::Average,
2073 997 : surface.Name);
2074 1994 : SetupOutputVariable(state,
2075 : "Surface Outside Face Heat Source Gain Rate per Area",
2076 : Constant::Units::W_m2,
2077 997 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(loop),
2078 : OutputProcessor::TimeStepType::Zone,
2079 : OutputProcessor::StoreType::Average,
2080 997 : surface.Name);
2081 :
2082 : // ENDIF
2083 997 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
2084 1 : SetupOutputVariable(state,
2085 : "Surface Construction Index",
2086 : Constant::Units::None,
2087 1 : surface.Construction,
2088 : OutputProcessor::TimeStepType::Zone,
2089 : OutputProcessor::StoreType::Average,
2090 1 : surface.Name);
2091 : }
2092 : }
2093 580 : SetupOutputVariable(state,
2094 : "Site Total Surface Heat Emission to Air",
2095 : Constant::Units::J,
2096 145 : state.dataHeatBalSurf->SumSurfaceHeatEmission,
2097 : OutputProcessor::TimeStepType::Zone,
2098 : OutputProcessor::StoreType::Sum,
2099 : "Environment");
2100 145 : }
2101 :
2102 483 : void InitThermalAndFluxHistories(EnergyPlusData &state)
2103 : {
2104 :
2105 : // SUBROUTINE INFORMATION:
2106 : // AUTHOR George Walton
2107 : // DATE WRITTEN March 1978
2108 : // RE-ENGINEERED Feb98 (RKS)
2109 :
2110 : // PURPOSE OF THIS SUBROUTINE:
2111 : // This subroutine sets the initial temperature and flux histories
2112 : // needed for a stable and reasonable heat balance solution starting
2113 : // point.
2114 :
2115 : // METHODOLOGY EMPLOYED:
2116 : // This subroutine assumes that the simulation is at steady state at
2117 : // the beginning and then begins to vary. Thus, the temperatures, the
2118 : // fluxes. and their histories can all be set to the same value. Some
2119 : // of the initializations depend on the surface characteristics. This
2120 : // requires a DO loop to perform the proper calculation.
2121 :
2122 : // REFERENCES:
2123 : // (I)BLAST legacy routine INITTH
2124 :
2125 : // First do the "bulk" initializations of arrays sized to NumOfZones
2126 1157 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2127 674 : new (&state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum)) ZoneTempPredictorCorrector::ZoneHeatBalanceData();
2128 : // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
2129 674 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
2130 674 : thisZoneHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
2131 674 : thisZoneHB.airHumRat = state.dataEnvrn->OutHumRat;
2132 674 : state.dataHeatBalFanSys->TempTstatAir(zoneNum) = DataHeatBalance::ZoneInitialTemp;
2133 : }
2134 1213 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
2135 730 : thisEnclosure.MRT = DataHeatBalance::ZoneInitialTemp;
2136 : }
2137 : // Reset spaceHeatBalance even if doSpaceHeatBalance is false, because spaceHB is used to gether zoneHB in some cases
2138 1263 : for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
2139 780 : new (&thisSpaceHB) ZoneTempPredictorCorrector::SpaceHeatBalanceData();
2140 : // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
2141 780 : thisSpaceHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
2142 780 : thisSpaceHB.airHumRat = state.dataEnvrn->OutHumRat;
2143 : }
2144 :
2145 : // "Bulk" initializations of arrays sized to TotSurfaces
2146 1157 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2147 1454 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2148 780 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2149 780 : int const firstSurf = thisSpace.HTSurfaceFirst;
2150 780 : int const lastSurf = thisSpace.HTSurfaceLast;
2151 4918 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2152 4138 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = DataHeatBalance::SurfInitialTemp;
2153 4138 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp; // module level array
2154 4138 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = DataHeatBalance::SurfInitialTemp; // module level array
2155 4138 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) = DataHeatBalance::SurfInitialConvCoeff; // module level array
2156 4138 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
2157 4138 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
2158 4138 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
2159 4138 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
2160 4138 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = 0.0;
2161 4138 : state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = 0.0;
2162 4138 : state.dataHeatBalSurf->SurfQConvInRep(SurfNum) = 0.0;
2163 4138 : state.dataHeatBalSurf->SurfQdotConvInRep(SurfNum) = 0.0;
2164 4138 : state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum) = 0.0;
2165 4138 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(SurfNum) = 0.0;
2166 4138 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(SurfNum) = 0.0;
2167 4138 : state.dataHeatBalSurf->SurfQRadSolarInRep(SurfNum) = 0.0;
2168 4138 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(SurfNum) = 0.0;
2169 4138 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(SurfNum) = 0.0;
2170 4138 : state.dataHeatBalSurf->SurfQRadLightsInRep(SurfNum) = 0.0;
2171 4138 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(SurfNum) = 0.0;
2172 4138 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(SurfNum) = 0.0;
2173 4138 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(SurfNum) = 0.0;
2174 4138 : state.dataHeatBalSurf->SurfQRadHVACInRep(SurfNum) = 0.0;
2175 4138 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(SurfNum) = 0.0;
2176 4138 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) = 0.0;
2177 4138 : state.dataHeatBalSurf->SurfQConvOutReport(SurfNum) = 0.0;
2178 4138 : state.dataHeatBalSurf->SurfQdotConvOutRep(SurfNum) = 0.0;
2179 4138 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = 0.0;
2180 4138 : state.dataHeatBalSurf->SurfQRadOutReport(SurfNum) = 0.0;
2181 4138 : state.dataHeatBalSurf->SurfQdotRadOutRep(SurfNum) = 0.0;
2182 4138 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = 0.0;
2183 4138 : state.dataHeatBalSurf->SurfQAirExtReport(SurfNum) = 0.0;
2184 4138 : state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) = 0.0;
2185 : } // end of Surf array
2186 780 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
2187 780 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
2188 780 : if (firstSurfOpaq >= 0) {
2189 4692 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
2190 3912 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = 0.0;
2191 3912 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 0.0;
2192 3912 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(SurfNum) = 0.0;
2193 3912 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
2194 : } // end of Zone Surf
2195 : }
2196 780 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2197 780 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2198 780 : if (firstSurfWin >= 0) {
2199 1006 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2200 : // Initialize window frame and divider temperatures
2201 226 : state.dataSurface->SurfWinFrameTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
2202 226 : state.dataSurface->SurfWinFrameTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
2203 226 : state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
2204 226 : state.dataSurface->SurfWinDividerTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
2205 226 : state.dataSurface->SurfWinDividerTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
2206 226 : state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
2207 :
2208 : // Initialize previous-timestep shading indicators
2209 226 : state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) = DataSurfaces::WinShadingType::NoShade;
2210 226 : state.dataSurface->SurfWinShadingFlag(SurfNum) = DataSurfaces::WinShadingType::NoShade;
2211 : } // end of Zone Surf
2212 : }
2213 : }
2214 : } // end of Zone
2215 :
2216 : // "Bulk" initializations of temperature arrays with dimensions (TotSurface,MaxCTFTerms,2)
2217 1157 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2218 1454 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2219 780 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2220 780 : int const firstSurf = thisSpace.HTSurfaceFirst;
2221 780 : int const lastSurf = thisSpace.HTSurfaceLast;
2222 15600 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2223 93442 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2224 78622 : state.dataHeatBalSurf->SurfInsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2225 78622 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2226 78622 : state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
2227 78622 : state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
2228 : }
2229 : }
2230 : }
2231 : }
2232 483 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
2233 236 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2234 252 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2235 126 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2236 126 : int const firstSurf = thisSpace.HTSurfaceFirst;
2237 126 : int const lastSurf = thisSpace.HTSurfaceLast;
2238 888 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2239 762 : state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
2240 : }
2241 2520 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2242 16872 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2243 14478 : state.dataHeatBalSurf->SurfInsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2244 14478 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2245 14478 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
2246 14478 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
2247 : }
2248 : }
2249 : }
2250 : }
2251 : }
2252 483 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
2253 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2254 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2255 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2256 0 : int const firstSurf = thisSpace.HTSurfaceFirst;
2257 0 : int const lastSurf = thisSpace.HTSurfaceLast;
2258 0 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2259 0 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2260 0 : state.dataHeatBalSurf->SurfTsrcHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2261 0 : state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2262 0 : state.dataHeatBalSurf->SurfTuserHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2263 0 : state.dataHeatBalSurf->SurfTuserHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2264 0 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, CTFTermNum) = 0.0;
2265 0 : state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, CTFTermNum) = 0.0;
2266 : }
2267 : }
2268 : }
2269 : }
2270 : }
2271 483 : state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
2272 :
2273 : // Perform other initializations that depend on the surface characteristics
2274 4190 : for (int CTFTermNum = 1; CTFTermNum <= state.dataHeatBal->MaxCTFTerms + 1; ++CTFTermNum) {
2275 38343 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2276 34636 : auto &surface = state.dataSurface->Surface(SurfNum);
2277 : // Reset outside boundary conditions if necessary
2278 34636 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
2279 21427 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
2280 13209 : } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
2281 2753 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
2282 2753 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
2283 10456 : } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
2284 0 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
2285 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
2286 : }
2287 : // Initialize the flux histories
2288 34636 : state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) =
2289 34636 : state.dataConstruction->Construct(surface.Construction).UValue *
2290 34636 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum));
2291 34636 : state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2292 : }
2293 : }
2294 4621 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2295 4138 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
2296 0 : state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TbaffleLast = 20.0;
2297 0 : state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TairLast = 20.0;
2298 : }
2299 : }
2300 : // Initialize Kiva convection algorithms
2301 483 : for (int SurfNum : state.dataSurface->AllHTKivaSurfaceList) {
2302 0 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = KIVA_CONST_CONV(3.076);
2303 0 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].f = KIVA_HF_DEF;
2304 0 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].out = KIVA_CONST_CONV(0.0);
2305 : }
2306 483 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
2307 872 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2308 762 : auto &surface = state.dataSurface->Surface(SurfNum);
2309 762 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
2310 11880 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2311 11286 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
2312 : }
2313 762 : } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
2314 0 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2315 0 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
2316 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
2317 : }
2318 168 : } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
2319 0 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2320 0 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
2321 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
2322 : }
2323 : }
2324 3046 : for (int CTFTermNum = 2; CTFTermNum <= state.dataConstruction->Construct(surface.Construction).NumCTFTerms + 1; ++CTFTermNum) {
2325 2284 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2326 2284 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2327 : }
2328 : }
2329 : }
2330 :
2331 483 : if (state.dataSurface->TotOSCM >= 1) {
2332 2 : for (int OSCMnum = 1; OSCMnum <= state.dataSurface->TotOSCM; ++OSCMnum) {
2333 1 : auto &thisOSC = state.dataSurface->OSCM(OSCMnum);
2334 1 : thisOSC.TConv = 20.0;
2335 1 : thisOSC.HConv = 4.0;
2336 1 : thisOSC.TRad = 20.0;
2337 1 : thisOSC.HRad = 4.0;
2338 : }
2339 : }
2340 483 : }
2341 :
2342 3 : void EvalOutsideMovableInsulation(EnergyPlusData &state)
2343 : {
2344 : // This subroutine determines whether or not outside movable insulation on opaque surfaces is present at the current time.
2345 3 : auto &s_mat = state.dataMaterial;
2346 3 : auto &s_surf = state.dataSurface;
2347 :
2348 6 : for (int SurfNum : s_surf->extMovInsulSurfNums) {
2349 3 : auto &movInsul = s_surf->extMovInsuls(SurfNum);
2350 3 : Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
2351 3 : if (MovInsulSchedVal <= 0) { // Movable insulation not present at current time
2352 0 : movInsul.present = false;
2353 0 : int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
2354 0 : auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
2355 0 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisMaterial->AbsorpSolar;
2356 0 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisMaterial->AbsorpThermal;
2357 0 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisMaterial->Roughness;
2358 0 : continue;
2359 0 : }
2360 :
2361 3 : auto const *mat = s_mat->materials(movInsul.matNum);
2362 3 : movInsul.present = true;
2363 3 : movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
2364 3 : if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) {
2365 2 : auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
2366 2 : assert(matGlass != nullptr);
2367 2 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
2368 2 : } else {
2369 1 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = mat->AbsorpSolar;
2370 : }
2371 3 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = mat->AbsorpThermal;
2372 3 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = mat->Roughness;
2373 : }
2374 3 : }
2375 :
2376 3 : void EvalInsideMovableInsulation(EnergyPlusData &state)
2377 : {
2378 3 : auto &s_mat = state.dataMaterial;
2379 3 : auto &s_surf = state.dataSurface;
2380 : // This subroutine determines whether or not inside movable insulation is present at the current time.
2381 6 : for (int SurfNum : s_surf->intMovInsulSurfNums) {
2382 3 : auto &movInsul = s_surf->intMovInsuls(SurfNum);
2383 3 : Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
2384 3 : if (MovInsulSchedVal <= 0.0) { // Movable insulation not present at current time
2385 0 : movInsul.present = false;
2386 0 : int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
2387 0 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
2388 0 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
2389 0 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
2390 0 : continue;
2391 0 : }
2392 :
2393 3 : auto const *mat = s_mat->materials(movInsul.matNum);
2394 :
2395 3 : movInsul.present = true;
2396 3 : movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
2397 3 : if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) { // Glass is insulating?
2398 2 : auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
2399 2 : assert(matGlass != nullptr);
2400 2 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
2401 2 : } else {
2402 1 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = mat->AbsorpSolar;
2403 : }
2404 3 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = mat->AbsorpThermal;
2405 : }
2406 3 : }
2407 :
2408 249960 : void InitSolarHeatGains(EnergyPlusData &state)
2409 : {
2410 :
2411 : // SUBROUTINE INFORMATION:
2412 : // AUTHOR Anonymous
2413 : // DATE WRITTEN July 1977
2414 : // MODIFIED Mar99 (FW): handle movable interior shades and
2415 : // switchable glazing
2416 : // Oct99 (FW): account for Window5 glass calculation approach
2417 : // May01 (FW): handle interior and exterior blinds
2418 : // Sep03 (FW): initialize SurfaceWindow%FrameQRadOutAbs
2419 : // May06 (RR): handle exterior window screens
2420 : // RE-ENGINEERED Feb98 (RKS)
2421 :
2422 : // PURPOSE OF THIS SUBROUTINE:
2423 : // This subroutine initializes the arrays associated with solar heat
2424 : // gains for both individual surfaces and for zones. As a result,
2425 : // this routine sets the following variable arrays:
2426 : // QBV(unused), QDV, QC, QD; SurfOpaqQRadSWOutAbs and SurfOpaqQRadSWInAbs (for opaque surfaces);
2427 : // SurfWinQRadSWwinAbs (for windows)
2428 :
2429 : // METHODOLOGY EMPLOYED:
2430 : // If the sun is down, all of the pertinent arrays are zeroed. If the
2431 : // sun is up, various calculations are made.
2432 :
2433 : // REFERENCES:
2434 : // (I)BLAST legacy routine QSUN
2435 :
2436 249960 : auto &s_mat = state.dataMaterial;
2437 249960 : auto &Surface = state.dataSurface->Surface;
2438 :
2439 : // Using/Aliasing
2440 : using Dayltg::TransTDD;
2441 : using SolarShading::CalcInteriorSolarDistribution;
2442 : using namespace DataWindowEquivalentLayer;
2443 : using SolarShading::SurfaceScheduledSolarInc;
2444 : using SolarShading::WindowScheduledSolarAbs;
2445 :
2446 : // Why are these globals?
2447 249960 : auto &AbsDiffWin = state.dataHeatBalSurfMgr->AbsDiffWin;
2448 249960 : auto &AbsDiffWinGnd = state.dataHeatBalSurfMgr->AbsDiffWinGnd;
2449 249960 : auto &AbsDiffWinSky = state.dataHeatBalSurfMgr->AbsDiffWinSky;
2450 :
2451 586612 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2452 336652 : state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = 0.0;
2453 336652 : state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = 0.0;
2454 336652 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = 0.0;
2455 336652 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = 0.0;
2456 336652 : state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) = 0.0;
2457 336652 : state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) = 0.0;
2458 :
2459 336652 : state.dataHeatBal->ZoneWinHeatGain(zoneNum) = 0.0;
2460 336652 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = 0.0;
2461 336652 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = 0.0;
2462 336652 : state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) = 0.0;
2463 336652 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = 0.0;
2464 336652 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = 0.0;
2465 336652 : state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) = 0.0;
2466 336652 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = 0.0;
2467 336652 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = 0.0;
2468 : }
2469 605538 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2470 355578 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0;
2471 : }
2472 586612 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2473 709607 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2474 372955 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2475 372955 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
2476 372955 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
2477 2358715 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
2478 1985760 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = 0.0;
2479 1985760 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = 0.0;
2480 1985760 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) = 0.0;
2481 1985760 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) = 0.0;
2482 1985760 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = 0.0;
2483 1985760 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum) = 0.0;
2484 1985760 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
2485 1985760 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(SurfNum) = 0.0;
2486 1985760 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(SurfNum) = 0.0;
2487 : }
2488 :
2489 372955 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2490 372955 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2491 461525 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2492 : // Faster "inline" than calling SurfaceWindow( SurfNum ).InitSolarHeatGains()
2493 88570 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = 0.0;
2494 88570 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = 0.0;
2495 88570 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = 0.0;
2496 88570 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = 0.0;
2497 88570 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = 0.0;
2498 88570 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = 0.0;
2499 88570 : state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) = 0.0;
2500 88570 : state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = 0.0;
2501 88570 : state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = 0.0;
2502 88570 : state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0;
2503 : }
2504 :
2505 461525 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2506 88570 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0;
2507 88570 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0;
2508 88570 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0;
2509 88570 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0;
2510 88570 : state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0;
2511 88570 : state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0;
2512 88570 : state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
2513 88570 : state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0;
2514 88570 : state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
2515 : }
2516 461525 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2517 88570 : state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0;
2518 88570 : state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0;
2519 88570 : state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0;
2520 88570 : state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0;
2521 88570 : state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0;
2522 88570 : state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
2523 88570 : state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0;
2524 : }
2525 2983640 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
2526 3230675 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2527 619990 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = 0.0;
2528 : }
2529 : }
2530 : }
2531 : }
2532 249960 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
2533 926 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2534 812 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
2535 812 : state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
2536 : }
2537 : }
2538 : bool currSolRadPositive =
2539 249960 : state.dataEnvrn->SunIsUp && (state.dataEnvrn->BeamSolarRad + state.dataEnvrn->GndSolarRad + state.dataEnvrn->DifSolarRad > 0.0);
2540 249960 : bool sunset = (!currSolRadPositive) && state.dataEnvrn->PreviousSolRadPositive;
2541 249960 : bool sunIsUpNoRad = state.dataEnvrn->SunIsUp && (!currSolRadPositive);
2542 249960 : bool resetSolar = state.dataGlobal->BeginEnvrnFlag || sunIsUpNoRad ||
2543 249960 : sunset; // Reset at (1) Beginning of simulation (2) sunset time, and SunIsUp but not solar time.
2544 249960 : state.dataEnvrn->PreviousSolRadPositive = currSolRadPositive;
2545 :
2546 249960 : if (currSolRadPositive || resetSolar) {
2547 1169133 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2548 1046167 : state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
2549 1046167 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) = 0.0;
2550 1046167 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) = 0.0;
2551 1046167 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) = 0.0;
2552 1046167 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
2553 :
2554 1046167 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) = 0.0;
2555 1046167 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = 0.0;
2556 1046167 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = 0.0;
2557 1046167 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = 0.0;
2558 :
2559 1046167 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) = 0.0;
2560 1046167 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) = 0.0;
2561 1046167 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = 0.0;
2562 1046167 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) = 0.0;
2563 1046167 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = 0.0;
2564 :
2565 1046167 : state.dataSurface->SurfSkySolarInc(SurfNum) = 0.0;
2566 1046167 : state.dataSurface->SurfGndSolarInc(SurfNum) = 0.0;
2567 : }
2568 299934 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2569 176968 : state.dataHeatBal->ZoneTransSolar(enclNum) = 0.0;
2570 176968 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclNum) = 0.0;
2571 176968 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclNum) = 0.0;
2572 176968 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclNum) = 0.0;
2573 176968 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclNum) = 0.0;
2574 176968 : state.dataHeatBal->ZoneTransSolarEnergy(enclNum) = 0.0;
2575 176968 : state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclNum) = 0.0;
2576 176968 : state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclNum) = 0.0;
2577 176968 : state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclNum) = 0.0;
2578 176968 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0;
2579 : }
2580 290055 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2581 353288 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2582 186199 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2583 186199 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2584 186199 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2585 231264 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2586 45065 : state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = 0.0;
2587 45065 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = 0.0;
2588 45065 : state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = 0.0;
2589 45065 : state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum) = 0.0;
2590 45065 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
2591 45065 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0;
2592 45065 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0;
2593 45065 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum) = 0.0;
2594 45065 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum) = 0.0;
2595 45065 : state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0;
2596 : }
2597 231264 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2598 45065 : state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = 0.0;
2599 45065 : state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = 0.0;
2600 45065 : state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = 0.0;
2601 45065 : state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = 0.0;
2602 45065 : state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = 0.0;
2603 45065 : state.dataSurface->SurfWinScTsolBmBm(SurfNum) = 0.0;
2604 45065 : state.dataSurface->SurfWinScTsolBmDif(SurfNum) = 0.0;
2605 45065 : state.dataSurface->SurfWinScTsolDifDif(SurfNum) = 0.0;
2606 45065 : state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = 0.0;
2607 45065 : state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = 0.0;
2608 45065 : state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = 0.0;
2609 45065 : state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = 0.0;
2610 45065 : state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = 0.0;
2611 : }
2612 231264 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2613 45065 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfNum) = 0.0;
2614 45065 : state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
2615 45065 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
2616 45065 : state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
2617 45065 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
2618 45065 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
2619 45065 : state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
2620 45065 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
2621 45065 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
2622 : }
2623 231264 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2624 45065 : state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
2625 45065 : state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
2626 45065 : state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
2627 45065 : state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
2628 45065 : state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
2629 45065 : state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
2630 45065 : state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfNum) = 0.0;
2631 45065 : state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0;
2632 45065 : state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0;
2633 : }
2634 :
2635 231264 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2636 45065 : state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0;
2637 45065 : state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0;
2638 45065 : state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0;
2639 45065 : state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0;
2640 45065 : state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0;
2641 45065 : state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0;
2642 45065 : state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0;
2643 45065 : state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0;
2644 45065 : state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0;
2645 45065 : state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0;
2646 45065 : state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = 0;
2647 45065 : state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) = 0.0;
2648 45065 : state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = 0.0;
2649 : }
2650 1478034 : for (int Lay = 1; Lay <= state.dataHeatBal->MaxSolidWinLayers; Lay++) {
2651 1607320 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2652 315485 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = 0.0;
2653 : }
2654 : }
2655 1303393 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL; Lay++) {
2656 1387584 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2657 270390 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay) = 0.0;
2658 : }
2659 : }
2660 : }
2661 : }
2662 : }
2663 249960 : if (resetSolar) {
2664 122672 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
2665 70921 : state.dataHeatBal->EnclSolQD(enclosureNum) = 0.0;
2666 70921 : state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) = 0.0;
2667 : }
2668 :
2669 : // TTD domes are currently not considered in the window list of a zone
2670 51751 : if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) {
2671 0 : for (auto &e : state.dataDaylightingDevicesData->TDDPipe) {
2672 0 : e.TransSolBeam = 0.0;
2673 0 : e.TransSolDiff = 0.0;
2674 0 : e.TransVisBeam = 0.0;
2675 0 : e.TransVisDiff = 0.0;
2676 0 : e.TransmittedSolar = 0.0;
2677 0 : int SurfDome = e.Dome;
2678 0 : state.dataSurface->SurfWinTransSolar(SurfDome) = 0.0;
2679 0 : state.dataHeatBal->SurfQRadSWOutIncident(SurfDome) = 0.0;
2680 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfDome) = 0.0;
2681 0 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
2682 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfDome, Lay) = 0.0;
2683 : }
2684 : }
2685 : }
2686 :
2687 51751 : if (state.dataSurface->CalcSolRefl) {
2688 0 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2689 0 : state.dataSurface->SurfBmToBmReflFacObs(SurfNum) = 0.0;
2690 0 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) = 0.0;
2691 0 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = 0.0;
2692 : }
2693 : }
2694 472795 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2695 421044 : state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0;
2696 421044 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = 0.0;
2697 421044 : state.dataHeatBal->SurfSWInAbsTotalReport(SurfNum) = 0.0;
2698 421044 : state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0;
2699 421044 : state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0;
2700 421044 : state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
2701 421044 : state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
2702 : }
2703 : }
2704 249960 : if (currSolRadPositive) { // Sun is up, calculate solar quantities
2705 71216 : assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
2706 : state.dataSurface->SurfReflFacBmToDiffSolObs)); // For linear indexing
2707 71216 : assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
2708 : state.dataSurface->SurfReflFacBmToDiffSolGnd)); // For linear indexing
2709 71216 : Real64 GndReflSolarRad = 0.0;
2710 71216 : Real64 GndSolarRadInc = max(state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad, 0.0);
2711 :
2712 696350 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2713 625134 : state.dataSurface->Surface(SurfNum).IncSolMultiplier = GetSurfIncidentSolarMultiplier(state, SurfNum);
2714 : }
2715 696350 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2716 625134 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2717 625134 : state.dataSurface->SurfSkySolarInc(SurfNum) =
2718 625134 : state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2719 625134 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2720 0 : GndReflSolarRad = GndSolarRadInc * SurfIncSolarMultiplier *
2721 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2722 0 : Surface(SurfNum).GndReflSolarRad = GndReflSolarRad;
2723 : } else {
2724 625134 : GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
2725 : }
2726 625134 : state.dataSurface->SurfGndSolarInc(SurfNum) = GndReflSolarRad * Surface(SurfNum).ViewFactorGround;
2727 625134 : state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2728 625134 : state.dataSurface->SurfWinBmGndSolarInc(SurfNum) = 0.0;
2729 : }
2730 71216 : if (state.dataSurface->CalcSolRefl) {
2731 : // [ lSH ] == ( HourOfDay, SurfNum ) // [ lSP ] == ( PreviousHour, SurfNum )
2732 0 : Array1D<Real64>::size_type lSH = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->HourOfDay, 1) - 1;
2733 0 : Array1D<Real64>::size_type lSP = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->PreviousHour, 1) - 1;
2734 : // For Complex Fenestrations:
2735 0 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2736 0 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2737 :
2738 0 : Real64 GndSurfReflectance = 0.0;
2739 0 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2740 0 : GndSurfReflectance =
2741 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2742 : } else {
2743 0 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2744 : }
2745 0 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2746 0 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2747 0 : state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) =
2748 0 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2749 0 : state.dataSurface->SurfWinBmGndSolarInc(SurfNum) =
2750 0 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2751 0 : state.dataSurface->SurfBmToBmReflFacObs(SurfNum) =
2752 0 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToBmSolObs[lSH + SurfNum] +
2753 0 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToBmSolObs[lSP + SurfNum];
2754 0 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) =
2755 0 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolObs[lSH + SurfNum] +
2756 0 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolObs[lSP + SurfNum];
2757 0 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) =
2758 0 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSH + SurfNum] +
2759 0 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSP + SurfNum];
2760 : // TH2 CR 9056
2761 0 : state.dataSurface->SurfSkySolarInc(SurfNum) +=
2762 0 : currBeamSolarRad * (state.dataSurface->SurfBmToBmReflFacObs(SurfNum) + state.dataSurface->SurfBmToDiffReflFacObs(SurfNum)) +
2763 0 : currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
2764 0 : state.dataSurface->SurfGndSolarInc(SurfNum) =
2765 0 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) +
2766 0 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2767 0 : state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2768 : }
2769 : }
2770 :
2771 71216 : SolarShading::CalcWindowProfileAngles(state);
2772 :
2773 71216 : if (state.dataHeatBal->CalcWindowRevealReflection) SolarShading::CalcBeamSolarOnWinRevealSurface(state);
2774 :
2775 71216 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() && state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
2776 0 : SolarShading::CalcAbsorbedOnExteriorOpaqueSurfaces(state);
2777 0 : if (state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
2778 0 : SolarShading::CalcInteriorSolarDistributionWCESimple(state);
2779 : }
2780 : } else {
2781 71216 : SolarShading::CalcInteriorSolarDistribution(state);
2782 : }
2783 :
2784 177264 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
2785 :
2786 : // TH 3/24/2010 - QBV is not used!
2787 : // unused QBV(ZoneNum) = (CBZone(ZoneNum) + EnclSolDB(ZoneNum))*BeamSolarRad
2788 :
2789 : // RJH 08/30/07 - QDV does not seem to ever be used. NOT USED!
2790 : // QDV(ZoneNum) = EnclSolDS(ZoneNum)*DifSolarRad &
2791 : // +EnclSolDG(ZoneNum)*GndSolarRad
2792 :
2793 : // Original QD calc used only for EnclSolQSDifSol and daylighting calcs
2794 : // QDforDaylight(ZoneNum) = EnclSolDB(ZoneNum)*BeamSolarRad &
2795 : // +EnclSolDS(ZoneNum)*DifSolarRad &
2796 : // +EnclSolDG(ZoneNum)*GndSolarRad
2797 :
2798 : // Beam from interior windows (EnclSolDBIntWin) reflected from floor is counted in DayltgInterReflIllFrIntWins,
2799 : // EnclSolDB needs to subtract this part since it is already counted in EnclSolDB.
2800 : // Use EnclSolInitialDifSolReflW (Rob's previous work) as it better counts initial distribution of
2801 : // diffuse solar rather than using weighted area*absorptance
2802 106048 : state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) =
2803 106048 : (state.dataHeatBal->EnclSolDB(enclosureNum) - state.dataHeatBal->EnclSolDBIntWin(enclosureNum)) * state.dataEnvrn->BeamSolarRad +
2804 106048 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) + state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
2805 :
2806 : // to exclude diffuse solar now absorbed/transmitted in CalcWinTransDifSolInitialDistribution
2807 : // EnclSolDB(ZoneNum) is Diffuse Solar from beam reflected from interior surfaces
2808 : // and transmitted through interior windows
2809 : // EnclSolDB is a factor that when multiplied by BeamSolarRad [W/m2] gives Watts
2810 : // QD(ZoneNum) = EnclSolDB(ZoneNum)*BeamSolarRad &
2811 : // +EnclSolDS(ZoneNum)*DifSolarRad &
2812 : // +EnclSolDG(ZoneNum)*GndSolarRad
2813 212096 : state.dataHeatBal->EnclSolQD(enclosureNum) = state.dataHeatBal->EnclSolDB(enclosureNum) * state.dataEnvrn->BeamSolarRad +
2814 106048 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) +
2815 106048 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
2816 : }
2817 :
2818 : // Flux of diffuse solar in each zone
2819 :
2820 177264 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2821 106048 : state.dataHeatBal->EnclSolQSDifSol(enclNum) = state.dataHeatBal->EnclSolQDforDaylight(enclNum);
2822 : }
2823 :
2824 71216 : if (state.dataHeatBalSurf->InterZoneWindow) {
2825 0 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2826 0 : if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclNum)) {
2827 0 : Real64 EnclSolQSDifSol_sum(0.0); // Accumulator
2828 0 : int lZone(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.index(enclNum,
2829 0 : 1)); // Tuned Linear indexing
2830 0 : for (int otherEnclNum = 1; otherEnclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++otherEnclNum, ++lZone) {
2831 0 : if ((otherEnclNum != enclNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(otherEnclNum))) {
2832 0 : EnclSolQSDifSol_sum += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[lZone] *
2833 0 : state.dataHeatBal->EnclSolQDforDaylight(otherEnclNum); // [ lZone ] == ( enclNum, otherEnclNum )
2834 : }
2835 : }
2836 0 : state.dataHeatBal->EnclSolQSDifSol(enclNum) += EnclSolQSDifSol_sum;
2837 : }
2838 : }
2839 : }
2840 :
2841 177264 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2842 106048 : if (state.dataHeatBalSurf->InterZoneWindow)
2843 0 : state.dataHeatBal->EnclSolQSDifSol(enclNum) *=
2844 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclNum, enclNum) * state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
2845 : else
2846 106048 : state.dataHeatBal->EnclSolQSDifSol(enclNum) *= state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
2847 : }
2848 :
2849 : // RJH - 09-12-07 commented out report variable calcs here since they refer to old distribution method
2850 : // DO SurfNum = 1, TotSurfaces
2851 : // IF (.NOT. Surface(SurfNum)%HeatTransSurf) CYCLE
2852 : //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
2853 : // IF (Surface(SurfNum)%Class == SurfaceClass::Shading) CYCLE
2854 : // ZoneNum = Surface(SurfNum)%Zone
2855 : // Diffuse solar entering zone through exterior windows is assumed to be uniformly
2856 : // distributed on inside face of surfaces of zone
2857 : // DifIncInsSurfIntensRep(SurfNum) = (EnclSolDS(ZoneNum)*DifSolarRad + EnclSolDG(ZoneNum)*GndSolarRad) / &
2858 : // Zone(ZoneNum)%TotalSurfArea
2859 : // DifIncInsSurfAmountRep(SurfNum) = (Surface(SurfNum)%Area + SurfaceWindow(SurfNum)%DividerArea) * &
2860 : // DifIncInsSurfIntensRep(SurfNum)
2861 : // DifIncInsSurfAmountRepEnergy(SurfNum) = DifIncInsSurfAmountRep(SurfNum) * TimeStepZoneSec
2862 : // END DO
2863 :
2864 : // Calculate Exterior Incident Short Wave (i.e. Solar) Radiation on shading surfaces
2865 71216 : if (state.dataSurface->BuildingShadingCount || state.dataSurface->FixedShadingCount || state.dataSurface->AttachedShadingCount) {
2866 14980 : for (int SurfNum = state.dataSurface->ShadingSurfaceFirst; SurfNum <= state.dataSurface->ShadingSurfaceLast; SurfNum++) {
2867 11984 : Real64 GndSurfReflectance = 0.0;
2868 11984 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2869 0 : GndSurfReflectance =
2870 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2871 : } else {
2872 11984 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2873 : }
2874 : // Cosine of incidence angle and solar incident on outside of surface, for reporting
2875 11984 : Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
2876 11984 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = CosInc;
2877 11984 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2878 11984 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2879 11984 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2880 : // Incident direct (unreflected) beam
2881 11984 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
2882 11984 : currBeamSolarRad * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) * CosInc;
2883 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
2884 11984 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2885 : // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
2886 11984 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2887 : // Incident diffuse solar from beam-to-diffuse reflection from ground
2888 11984 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
2889 11984 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2890 : // Incident diffuse solar from sky diffuse reflection from ground
2891 11984 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
2892 11984 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
2893 : // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
2894 : // in SkySolarInc.
2895 11984 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
2896 11984 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
2897 11984 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
2898 : }
2899 : }
2900 :
2901 71216 : Array1D<Real64> currBeamSolar(state.dataSurface->TotSurfaces); // Local variable for BeamSolarRad
2902 :
2903 462416 : for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
2904 391200 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2905 : // Regular surface
2906 391200 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2907 391200 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2908 : // Cosine of incidence angle and solar incident on outside of surface, for reporting
2909 391200 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
2910 391200 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
2911 :
2912 : // Report variables for various incident solar quantities
2913 : // Incident direct (unreflected) beam
2914 391200 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
2915 391200 : currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
2916 391200 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum);
2917 :
2918 391200 : Real64 GndSurfReflectance = 0.0;
2919 391200 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2920 0 : GndSurfReflectance =
2921 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2922 : } else {
2923 391200 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2924 : }
2925 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
2926 391200 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2927 : // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
2928 391200 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2929 : // Incident diffuse solar from beam-to-diffuse reflection from ground
2930 391200 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
2931 391200 : currBeamSolar(SurfNum) * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2932 :
2933 : // Incident diffuse solar from sky diffuse reflection from ground
2934 391200 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
2935 391200 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
2936 : // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
2937 : // in SkySolarInc.
2938 : // SurfQRadSWOutIncident(SurfNum) = SurfQRadSWOutIncidentBeam(SurfNum) + SkySolarInc + GndSolarInc
2939 : // TH2 CR 9056
2940 391200 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
2941 391200 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
2942 391200 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
2943 :
2944 391200 : if (state.dataSurface->CalcSolRefl) {
2945 : // Incident beam solar from beam-to-beam (specular) reflection from obstructions
2946 0 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = state.dataSurface->SurfBmToBmReflFacObs(SurfNum) * currBeamSolar(SurfNum);
2947 : // Incident diffuse solar from beam-to-diffuse reflection from obstructions
2948 0 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) =
2949 0 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) * currBeamSolar(SurfNum);
2950 : // Incident diffuse solar from sky diffuse reflection from obstructions
2951 0 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
2952 : // TH2 CR 9056: Add reflections from obstructions to the total incident
2953 0 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) += state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) +
2954 0 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) +
2955 0 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum);
2956 : }
2957 : }
2958 71216 : for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
2959 0 : int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser; // TDD: Diffuser object number
2960 0 : int const SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
2961 0 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
2962 0 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
2963 :
2964 : // Reconstruct the beam, sky, and ground radiation transmittance of just the TDD:DOME and TDD pipe
2965 : // by dividing out diffuse solar transmittance of TDD:DIFFUSER
2966 0 : Real64 ConInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
2967 :
2968 0 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = ConInc;
2969 0 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2970 0 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier *
2971 0 : TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarBeam) / thisConstruct.TransDiff;
2972 :
2973 0 : state.dataSurface->SurfSkySolarInc(SurfNum) = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier *
2974 0 : state.dataSolarShading->SurfAnisoSkyMult(SurfNum2) *
2975 0 : TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarAniso) / thisConstruct.TransDiff;
2976 :
2977 0 : state.dataSurface->SurfGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum2) *
2978 0 : state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolIso / thisConstruct.TransDiff;
2979 : // Incident direct (unreflected) beam
2980 0 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = currBeamSolar(SurfNum) *
2981 0 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay,
2982 0 : state.dataGlobal->TimeStep,
2983 0 : SurfNum2) *
2984 : ConInc; // NOTE: sunlit and coninc array set to SurfNum2
2985 :
2986 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
2987 0 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = state.dataSurface->SurfSkySolarInc(SurfNum);
2988 0 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
2989 0 : (state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
2990 0 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum));
2991 : }
2992 :
2993 71216 : for (int ShelfNum = 1; ShelfNum <= (int)state.dataDaylightingDevicesData->Shelf.size(); ++ShelfNum) {
2994 0 : int SurfNum = state.dataDaylightingDevicesData->Shelf(ShelfNum).Window; // Daylighting shelf object number
2995 0 : int OutShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf; // Outside daylighting shelf present if > 0
2996 0 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
2997 0 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
2998 0 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2999 0 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3000 : // Shelf diffuse solar radiation
3001 : Real64 ShelfSolarRad =
3002 0 : (currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) *
3003 0 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) +
3004 0 : state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(OutShelfSurf)) *
3005 0 : state.dataDaylightingDevicesData->Shelf(ShelfNum).OutReflectSol;
3006 :
3007 0 : GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
3008 0 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
3009 0 : GndReflSolarRad = state.dataSurface->Surface(SurfNum).GndReflSolarRad;
3010 : }
3011 : // Add all reflected solar from the outside shelf to the ground solar
3012 : // NOTE: If the shelf blocks part of the view to the ground, the user must reduce the ground view factor!!
3013 0 : state.dataSurface->SurfGndSolarInc(SurfNum) =
3014 0 : GndReflSolarRad * Surface(SurfNum).ViewFactorGround + ShelfSolarRad * state.dataDaylightingDevicesData->Shelf(ShelfNum).ViewFactor;
3015 : }
3016 :
3017 : // Calculate Exterior and Interior Absorbed Short Wave Radiation
3018 170521 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3019 212058 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3020 112753 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
3021 112753 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
3022 112753 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
3023 694797 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
3024 582044 : int const ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
3025 582044 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3026 582044 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3027 582044 : if (Surface(SurfNum).ExtSolar) {
3028 : Real64 AbsExt =
3029 348112 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); // Absorptivity of outer most layer (or movable insulation if present)
3030 348112 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
3031 348112 : state.dataSurface->SurfOpaqAO(SurfNum) * currBeamSolar(SurfNum) +
3032 348112 : AbsExt * (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum));
3033 : }
3034 582044 : if (ConstrNum > 0) {
3035 582044 : int SurfSolIncPtr = SolarShading::SurfaceScheduledSolarInc(state, SurfNum, ConstrNum);
3036 582044 : if (SurfSolIncPtr == 0) {
3037 582044 : if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Opaque surface
3038 582044 : int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum); // Daylighting shelf object number
3039 582044 : int InShelfSurf = 0; // Inside daylighting shelf surface number
3040 582044 : if (ShelfNum > 0) {
3041 0 : InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf; // Inside daylighting shelf present if > 0
3042 : }
3043 582044 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +=
3044 582044 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum);
3045 582044 : if (InShelfSurf > 0) { // Inside daylighting shelf
3046 : // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init)
3047 0 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
3048 0 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * (0.5 * Surface(SurfNum).Area);
3049 : } else { // Regular surface
3050 582044 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
3051 582044 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * Surface(SurfNum).Area;
3052 : }
3053 : }
3054 : } else {
3055 0 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum);
3056 : }
3057 : }
3058 : }
3059 112753 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
3060 112753 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
3061 143857 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
3062 31104 : auto &surf = state.dataSurface->Surface(SurfNum);
3063 31104 : auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
3064 31104 : if (surf.ExtSolar || surf.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
3065 : // Exclude special shading surfaces which required SurfOpaqQRadSWOut calculations above
3066 31104 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3067 31104 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3068 31104 : Real64 CosInc = state.dataHeatBal->SurfCosIncidenceAngle(SurfNum); // Cosine of incidence angle of beam solar on glass
3069 31104 : Real64 BeamSolar = currBeamSolar(SurfNum); // Local variable for BeamSolarRad
3070 31104 : Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum); // Sky diffuse solar incident on a surface
3071 31104 : Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum); // Ground diffuse solar incident on a surface
3072 :
3073 31104 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
3074 :
3075 60836 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed &&
3076 29732 : !state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
3077 29732 : int TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
3078 66665 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3079 36933 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
3080 : }
3081 :
3082 29732 : if (IS_SHADED(ShadeFlag)) { // Shaded window
3083 :
3084 0 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); // Shaded window construction
3085 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3086 :
3087 0 : if (ANY_SHADE_SCREEN(ShadeFlag)) { // Shade/screen on
3088 0 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3089 0 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = constructionSh.AbsDiff(Lay);
3090 : }
3091 0 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = constructionSh.AbsDiffShade * (SkySolarInc + GndSolarInc);
3092 :
3093 0 : } else if (ANY_BLIND(ShadeFlag)) { // Blind on
3094 0 : auto &surfShade = state.dataSurface->surfShades(SurfNum);
3095 0 : int slatIdxLo = surfShade.blind.slatAngIdxLo;
3096 0 : int slatIdxHi = surfShade.blind.slatAngIdxHi;
3097 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3098 : Real64 AbsDiffBlind;
3099 :
3100 : // For constructions, have to do interpolation whether we have movable slats or not
3101 0 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3102 0 : auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
3103 0 : auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
3104 :
3105 0 : AbsDiffWin(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.Abs, dfAbsSlatHi.Sol.Ft.Df.Abs, interpFac);
3106 0 : AbsDiffWinGnd(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3107 0 : AbsDiffWinSky(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3108 : }
3109 :
3110 0 : auto const &tarSlatLo = constructionSh.blindTARs[slatIdxLo];
3111 0 : auto const &tarSlatHi = constructionSh.blindTARs[slatIdxHi];
3112 0 : AbsDiffBlind = Interp(tarSlatLo.Sol.Ft.Df.Abs, tarSlatHi.Sol.Ft.Df.Abs, interpFac);
3113 :
3114 0 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = AbsDiffBlind * (SkySolarInc + GndSolarInc);
3115 :
3116 0 : auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
3117 0 : if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
3118 0 : Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt);
3119 :
3120 : // Need to do these interpolations unless we want to cache this in surfShade.blind.
3121 0 : Real64 AbsDiffBlindGnd = Interp(tarSlatLo.Sol.Ft.Df.AbsGnd, tarSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3122 0 : Real64 AbsDiffBlindSky = Interp(tarSlatLo.Sol.Ft.Df.AbsSky, tarSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3123 :
3124 0 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) =
3125 0 : SkySolarInc * (0.5 * ACosTlt * AbsDiffBlindGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffBlindSky) +
3126 0 : GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffBlindGnd + 0.5 * ACosTlt * AbsDiffBlindSky);
3127 : }
3128 : }
3129 :
3130 : // Correct for shadowing of divider onto interior shading device (note that dividers are
3131 : // not allowed in windows with between-glass shade/blind)
3132 :
3133 0 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0)
3134 0 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) *= surfWin.glazedFrac;
3135 :
3136 0 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3137 0 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for switchable glazing
3138 0 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3139 0 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) =
3140 0 : Window::InterpSw(SwitchFac, state.dataHeatBalSurfMgr->AbsDiffWin(Lay), constructionSh.AbsDiff(Lay));
3141 : }
3142 : }
3143 :
3144 : } // End of check if window has shading device on
3145 :
3146 29732 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3147 66665 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3148 36933 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3149 36933 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc) +
3150 36933 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3151 : // SurfWinA is from InteriorSolarDistribution
3152 36933 : if (ANY_BLIND(ShadeFlag)) {
3153 0 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3154 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3155 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3156 0 : auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
3157 0 : if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
3158 :
3159 0 : Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); // Absolute value of cosine of surface tilt angle
3160 :
3161 0 : int slatIdxLo = surfShade.blind.slatAngIdxLo;
3162 0 : int slatIdxHi = surfShade.blind.slatAngIdxLo;
3163 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3164 0 : auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
3165 0 : auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
3166 :
3167 0 : Real64 AbsDiffGlassLayGnd = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3168 0 : Real64 AbsDiffGlassLaySky = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3169 :
3170 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3171 0 : SkySolarInc * (0.5 * ACosTlt * AbsDiffGlassLayGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffGlassLaySky) +
3172 0 : GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffGlassLayGnd + 0.5 * ACosTlt * AbsDiffGlassLaySky) +
3173 0 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3174 : }
3175 : }
3176 : // Total solar absorbed in solid layer (W), for reporting
3177 36933 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3178 36933 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3179 :
3180 : // Total solar absorbed in all glass layers (W), for reporting
3181 36933 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3182 : }
3183 29732 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3184 29732 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3185 : // Need to do it this way for now because of scheduled surface gains. They do work only with
3186 : // BSDF windows and overwriting absorbtances will work only for ordinary windows
3187 : // } else if ( SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: BSDF &&
3188 : // SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: EQL &&
3189 : // inExtWindowModel->isExternalLibraryModel() ) {
3190 : // TotSolidLay = Construct( ConstrNum ).TotSolidLayers;
3191 : // for ( Lay = 1; Lay <= TotSolidLay; ++Lay ) {
3192 : // SurfWinQRadSWwinAbs( Lay, SurfNum ) = SurfWinA( Lay, SurfNum ) *
3193 : // ( SurfQRadSWOutIncident( SurfNum ) + QS( Surface( SurfNum ).Zone ) );
3194 : // }
3195 1372 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
3196 0 : int TotSolidLay = state.dataConstruction->Construct(ConstrNum).TotSolidLayers;
3197 : // Number of solid layers in fenestration system (glass + shading)
3198 0 : int CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState;
3199 : // Current state for Complex Fenestration
3200 : // Examine for schedule surface gain
3201 0 : Real64 SurfSolAbs = SolarShading::WindowScheduledSolarAbs(
3202 : state,
3203 : SurfNum,
3204 0 : ConstrNum); // Pointer to scheduled surface gains object for fenestration systems
3205 :
3206 0 : for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
3207 0 : if (SurfSolAbs != 0) {
3208 0 : state.dataSurface->SurfWinA(SurfNum, Lay) =
3209 0 : state.dataSurface->FenLayAbsSSG(SurfSolAbs).scheds(Lay)->getCurrentVal();
3210 : // ABWin(Lay) = SurfWinA(SurfNum,Lay)
3211 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = state.dataSurface->SurfWinA(SurfNum, Lay);
3212 : } else {
3213 : // Several notes about this equation. First part is accounting for diffuse solar radiation for the ground
3214 : // and from the sky. Second item (SurfWinA(SurfNum,Lay) * BeamSolar) is accounting for absorbed solar
3215 : // radiation originating from beam on exterior side. Third item (SurfWinACFOverlap(SurfNum,Lay)) is
3216 : // accounting for absorptances from beam hitting back of the window which passes through rest of exterior
3217 : // windows
3218 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3219 0 : state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyFtAbs(Lay) * SkySolarInc +
3220 0 : state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyGndAbs(Lay) * GndSolarInc +
3221 0 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
3222 0 : state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * BeamSolar;
3223 : }
3224 : // Total solar absorbed in solid layer (W), for reporting
3225 0 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3226 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3227 :
3228 : // Total solar absorbed in all glass layers (W), for reporting
3229 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3230 : }
3231 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3232 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3233 :
3234 1372 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
3235 1372 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3236 : // EQLNum = Construct(Surface(SurfNum)%Construction)%EQLConsPtr
3237 : int TotSolidLay =
3238 1372 : state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(Surface(SurfNum).Construction).EQLConsPtr).NL;
3239 4970 : for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
3240 : // Absorbed window components include:
3241 : // (1) beam solar radiation absorbed by all layers in the fenestration
3242 : // (2) sky and ground reflected diffuse solar radiation absorbed by all layers
3243 : // (3) diffuse short wave incident on the inside face of the fenestration. The short wave internal sources
3244 : // include light, ...
3245 3598 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay);
3246 3598 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3247 3598 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
3248 3598 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc);
3249 :
3250 : // Total solar absorbed in solid layer (W), for reporting
3251 3598 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3252 3598 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3253 :
3254 : // Total solar absorbed in all glass layers (W), for reporting
3255 3598 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3256 : }
3257 :
3258 1372 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3259 1372 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3260 0 : } else if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
3261 0 : int SurfNum2 = SurfNum;
3262 0 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
3263 0 : SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
3264 : }
3265 :
3266 : std::pair<Real64, Real64> incomingAngle =
3267 0 : Window::getSunWCEAngles(state, SurfNum2, SingleLayerOptics::BSDFDirection::Incoming);
3268 0 : Real64 Theta = incomingAngle.first;
3269 0 : Real64 Phi = incomingAngle.second;
3270 :
3271 : std::shared_ptr<MultiLayerOptics::CMultiLayerScattered> aLayer =
3272 0 : Window::CWindowConstructionsSimplified::instance(state).getEquivalentLayer(
3273 0 : state, FenestrationCommon::WavelengthRange::Solar, ConstrNum);
3274 :
3275 0 : size_t totLayers = aLayer->getNumOfLayers();
3276 0 : for (size_t Lay = 1; Lay <= totLayers; ++Lay) {
3277 0 : Real64 AbWinDiff = aLayer->getAbsorptanceLayer(
3278 : Lay, FenestrationCommon::Side::Front, FenestrationCommon::ScatteringSimple::Diffuse, Theta, Phi);
3279 :
3280 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3281 0 : AbWinDiff * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3282 :
3283 : // Total solar absorbed in solid layer (W), for reporting
3284 0 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3285 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3286 :
3287 : // Total solar absorbed in all glass layers (W), for reporting
3288 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3289 : }
3290 0 : }
3291 :
3292 : // Solar absorbed by window frame and dividers
3293 31104 : int FrDivNum = Surface(SurfNum).FrameDivider; // Frame/divider number
3294 31104 : if (FrDivNum > 0) {
3295 0 : Real64 FrArea = state.dataSurface->SurfWinFrameArea(SurfNum); // Frame, divider area (m2)
3296 0 : Real64 FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut; // Frame, divider outside projection (m)
3297 0 : Real64 FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn;
3298 0 : Real64 DivArea = state.dataSurface->SurfWinDividerArea(SurfNum);
3299 0 : Real64 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
3300 0 : Real64 DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut;
3301 0 : Real64 DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn;
3302 0 : Real64 CosIncAngHorProj = 0.0; // Cosine of incidence angle of sun on horizontal faces of a frame or divider projection
3303 0 : Real64 CosIncAngVertProj = 0.0; // Cosine of incidence angle of sun on vertical faces of a frame or divider projection
3304 0 : Real64 FracSunLit = 0.0; // Fraction of window sunlit this time step
3305 : Real64 BeamFaceInc; // Beam solar incident window plane this time step (W/m2)
3306 : Real64 DifSolarFaceInc; // Diffuse solar incident on window plane this time step (W/m2)
3307 0 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3308 0 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3309 0 : if (FrArea > 0.0 || DivArea > 0.0) {
3310 0 : FracSunLit = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
3311 0 : BeamFaceInc = currBeamSolarRad *
3312 0 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
3313 : CosInc;
3314 0 : DifSolarFaceInc = SkySolarInc + GndSolarInc;
3315 : }
3316 0 : if (FracSunLit > 0.0) {
3317 0 : if ((FrArea > 0.0 && (FrProjOut > 0.0 || FrProjIn > 0.0)) ||
3318 0 : (DivArea > 0.0 && (DivProjOut > 0.0 || DivProjIn > 0.0))) {
3319 : // Dot products used to calculate beam solar incident on faces of
3320 : // frame and divider perpendicular to the glass surface.
3321 : // Note that SOLCOS is the current timestep's solar direction cosines.
3322 : // PhiWin = ASIN(WALCOS(3,SurfNum))
3323 : Real64 PhiWin =
3324 0 : std::asin(Surface(SurfNum).OutNormVec(3)); // Altitude and azimuth angle of outward window normal (radians)
3325 0 : Real64 ThWin = std::atan2(Surface(SurfNum).OutNormVec(2), Surface(SurfNum).OutNormVec(1));
3326 0 : Real64 PhiSun = std::asin(state.dataEnvrn->SOLCOS(3)); // Altitude and azimuth angle of sun (radians)
3327 0 : Real64 ThSun = std::atan2(state.dataEnvrn->SOLCOS(2), state.dataEnvrn->SOLCOS(1));
3328 0 : Real64 const cos_PhiWin(std::cos(PhiWin));
3329 0 : Real64 const cos_PhiSun(std::cos(PhiSun));
3330 : CosIncAngHorProj =
3331 0 : std::abs(std::sin(PhiWin) * cos_PhiSun * std::cos(ThWin - ThSun) - cos_PhiWin * std::sin(PhiSun));
3332 0 : CosIncAngVertProj = std::abs(cos_PhiWin * cos_PhiSun * std::sin(ThWin - ThSun));
3333 : }
3334 : }
3335 : // Frame solar
3336 : // (A window shade or blind, if present, is assumed to not shade the frame, so no special
3337 : // treatment of frame solar needed if window has an exterior shade or blind.)
3338 0 : if (FrArea > 0.0) {
3339 0 : Real64 FrIncSolarOut = BeamFaceInc; // Total solar incident on outside of frame including solar
3340 0 : Real64 FrIncSolarIn = 0.0; // Total solar incident on inside of frame including solar on frame projection (W/m2)
3341 0 : Real64 TransDiffGl = 0.0; // Diffuse solar transmittance
3342 0 : if (FrProjOut > 0.0 || FrProjIn > 0.0) {
3343 : Real64 BeamFrHorFaceInc =
3344 0 : currBeamSolarRad * CosIncAngHorProj *
3345 0 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit /
3346 0 : FrArea;
3347 : Real64 BeamFrVertFaceInc =
3348 0 : currBeamSolarRad * CosIncAngVertProj *
3349 0 : (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
3350 0 : FrArea;
3351 : // Beam solar on outside of frame
3352 0 : FrIncSolarOut += (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjOut;
3353 0 : if (FrProjIn > 0.0) {
3354 0 : Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
3355 0 : TransDiffGl = thisConstruct.TransDiff;
3356 0 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3357 0 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3358 0 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3359 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3360 0 : Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
3361 0 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3362 0 : Real64 TransDiffGlSh = constructionSh.TransDiff;
3363 0 : TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
3364 : }
3365 : // Beam solar on inside of frame
3366 0 : FrIncSolarIn = (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjIn * TransGl;
3367 : }
3368 : }
3369 : // Beam plus diffuse solar on outside of frame
3370 0 : FrIncSolarOut += DifSolarFaceInc * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum));
3371 0 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) =
3372 0 : FrIncSolarOut * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3373 : // Add diffuse from beam reflected from window outside reveal surfaces
3374 0 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) += currBeamSolarRad *
3375 0 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) *
3376 0 : state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3377 :
3378 : // Beam plus diffuse solar on inside of frame
3379 0 : FrIncSolarIn += DifSolarFaceInc * TransDiffGl * 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum);
3380 0 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = FrIncSolarIn * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3381 : // Add diffuse from beam reflected from window inside reveal surfaces
3382 0 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += currBeamSolarRad *
3383 0 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) *
3384 0 : state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3385 : }
3386 :
3387 : // Divider solar
3388 : // (An exterior shade or blind, when in place, is assumed to completely cover the divider.
3389 : // Dividers are not allowed on windows with between-glass shade/blind so DivProjOut and
3390 : // DivProjIn will be zero in this case.)
3391 0 : if (DivArea > 0.0) { // Solar absorbed by window divider
3392 0 : Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
3393 0 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
3394 : // Suspended (between-glass) divider; account for effect glass on outside of divider
3395 : // (note that outside and inside projection for this type of divider are both zero)
3396 0 : int MatNumGl = thisConstruct.LayerPoint(1); // Outer glass layer material number
3397 0 : auto const *thisMaterial = dynamic_cast<Material::MaterialFen *>(s_mat->materials(MatNumGl));
3398 0 : assert(thisMaterial != nullptr);
3399 0 : Real64 TransGl = thisMaterial->Trans; // Outer glass layer material number, switched construction
3400 0 : Real64 ReflGl = thisMaterial->ReflectSolBeamFront;
3401 0 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
3402 0 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3403 0 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3404 0 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3405 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3406 0 : Real64 MatNumGlSh = constructionSh.LayerPoint(1);
3407 0 : auto const *thisMaterialSh = dynamic_cast<Material::MaterialGlass *>(s_mat->materials(MatNumGlSh));
3408 0 : assert(thisMaterialSh != nullptr);
3409 0 : Real64 TransGlSh = thisMaterialSh->Trans;
3410 0 : Real64 ReflGlSh = thisMaterialSh->ReflectSolBeamFront;
3411 0 : Real64 AbsGlSh = 1.0 - TransGlSh - ReflGlSh;
3412 0 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3413 0 : ReflGl = Window::InterpSw(SwitchFac, ReflGl, ReflGlSh);
3414 0 : AbsGl = Window::InterpSw(SwitchFac, AbsGl, AbsGlSh);
3415 : }
3416 0 : Real64 DividerRefl = 1.0 - DividerAbs; // Window divider solar reflectance
3417 0 : DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
3418 : }
3419 :
3420 0 : Real64 BeamDivHorFaceInc = 0.0; // Beam solar on divider's horizontal outside projection faces (W/m2)
3421 0 : Real64 BeamDivVertFaceInc = 0.0; // Beam solar on divider's vertical outside projection faces (W/m2)
3422 : // Beam incident on horizontal and vertical projection faces of divider if no exterior shading
3423 0 : if (DivProjOut > 0.0 && !DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3424 0 : BeamDivHorFaceInc = currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers *
3425 0 : DivProjOut *
3426 0 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
3427 : FracSunLit / DivArea;
3428 0 : BeamDivVertFaceInc =
3429 0 : currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivProjOut *
3430 0 : (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
3431 : DivArea;
3432 : }
3433 0 : Real64 DivIncSolarOutBm =
3434 : 0.0; // Diffuse solar incident on outside of divider including beam on divider projection (W/m2)
3435 0 : Real64 DivIncSolarOutDif =
3436 : 0.0; // Diffuse solar incident on outside of divider including diffuse on divider projection (W/m2)
3437 0 : Real64 DivIncSolarInBm =
3438 : 0.0; // Diffuse solar incident on inside of divider including beam on divider projection (W/m2)
3439 0 : Real64 DivIncSolarInDif =
3440 : 0.0; // Diffuse solar incident on inside of divider including diffuse on divider projection (W/m2)
3441 0 : if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) &&
3442 0 : !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { // No exterior or between-glass shading
3443 0 : DivIncSolarOutBm = BeamFaceInc + BeamDivHorFaceInc + BeamDivVertFaceInc;
3444 0 : DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3445 0 : if (DivProjIn > 0.0) {
3446 0 : Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
3447 0 : Real64 TransDiffGl = thisConstruct.TransDiff; // Diffuse solar transmittance
3448 0 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3449 0 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3450 0 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3451 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3452 :
3453 0 : Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
3454 : // Outer glass solar trans, refl, absorptance if switched
3455 0 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3456 0 : Real64 TransDiffGlSh = constructionSh.TransDiff;
3457 : // Diffuse solar transmittance, switched construction
3458 0 : TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
3459 : }
3460 : // Beam plus diffuse solar on inside of divider
3461 : // BeamDivHorFaceIncIn - Beam solar on divider's horizontal inside projection faces (W/m2)
3462 : // BeamDivVertFaceIncIn - Beam solar on divider's vertical inside projection faces (W/m2)
3463 : Real64 BeamDivHorFaceIncIn =
3464 0 : currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivProjIn *
3465 0 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
3466 0 : FracSunLit / DivArea;
3467 : Real64 BeamDivVertFaceIncIn =
3468 0 : currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers *
3469 0 : DivProjIn * (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) *
3470 0 : FracSunLit / DivArea;
3471 0 : DivIncSolarInBm = TransGl * (BeamDivHorFaceIncIn + BeamDivVertFaceIncIn);
3472 0 : DivIncSolarInDif = TransDiffGl * DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum);
3473 : }
3474 : } else { // Exterior shade, screen or blind present
3475 :
3476 0 : DivIncSolarOutBm = BeamFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3477 0 : DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3478 0 : DivIncSolarInBm = BeamFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
3479 0 : DivIncSolarInDif = DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
3480 : }
3481 :
3482 0 : if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
3483 : // No exterior or between-glass shade, screen or blind
3484 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = DividerAbs * (DivIncSolarOutBm + DivIncSolarOutDif);
3485 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = DividerAbs * (DivIncSolarInBm + DivIncSolarInDif);
3486 : // Exterior shade, screen or blind
3487 :
3488 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) { // Exterior blind
3489 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3490 :
3491 0 : int profIdxLo = surfShade.blind.profAngIdxLo;
3492 0 : int profIdxHi = surfShade.blind.profAngIdxHi;
3493 0 : Real64 profInterpFac = surfShade.blind.profAngInterpFac;
3494 :
3495 0 : auto const &btarLo = surfShade.blind.TAR.Sol.Ft.Bm[profIdxLo];
3496 0 : auto const &btarHi = surfShade.blind.TAR.Sol.Ft.Bm[profIdxHi];
3497 :
3498 0 : Real64 FrontDiffTrans = surfShade.blind.TAR.Sol.Ft.Df.Tra;
3499 0 : Real64 TBlBmDif = Interp(btarLo.DfTra, btarHi.DfTra, profInterpFac);
3500 :
3501 : // TBlBmBm - Blind beam-beam solar transmittance
3502 0 : Real64 TBlBmBm = surfShade.blind.bmBmTrans;
3503 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3504 0 : DividerAbs * (DivIncSolarOutBm * (TBlBmBm + TBlBmDif) + DivIncSolarOutDif * FrontDiffTrans);
3505 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3506 0 : DividerAbs * (DivIncSolarInBm * (TBlBmBm + TBlBmDif) + DivIncSolarInDif * FrontDiffTrans);
3507 :
3508 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtShade) { // Exterior shade
3509 0 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3510 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3511 0 : auto const *matFen = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(constructionSh.LayerPoint(1)));
3512 0 : assert(matFen != nullptr);
3513 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3514 0 : DividerAbs * matFen->Trans * (DivIncSolarOutBm + DivIncSolarOutDif);
3515 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3516 0 : DividerAbs * matFen->Trans * (DivIncSolarInBm + DivIncSolarInDif);
3517 :
3518 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtScreen) { // Exterior screen
3519 0 : int screenNum = surfWin.screenNum;
3520 0 : auto const *screen = dynamic_cast<Material::MaterialScreen const *>(s_mat->materials(screenNum));
3521 0 : assert(screen != nullptr);
3522 :
3523 0 : auto &surf = state.dataSurface->Surface(SurfNum);
3524 : Real64 phi, theta;
3525 0 : Material::GetRelativePhiTheta(
3526 0 : surf.Tilt * Constant::DegToRad, surf.Azimuth * Constant::DegToRad, state.dataEnvrn->SOLCOS, phi, theta);
3527 : #ifdef PRECALC_INTERP_SCREEN
3528 : int ip1, ip2, it1, it2; // hi/lo phi and theta map indices
3529 : BilinearInterpCoeffs coeffs;
3530 0 : Material::GetPhiThetaIndices(phi, theta, screen->dPhi, screen->dTheta, ip1, ip2, it1, it2);
3531 0 : GetBilinearInterpCoeffs(
3532 0 : phi, theta, ip1 * screen->dPhi, ip2 * screen->dPhi, it1 * screen->dTheta, it2 * screen->dTheta, coeffs);
3533 0 : auto const &b11 = screen->btars[ip1][it1];
3534 0 : auto const &b12 = screen->btars[ip1][it2];
3535 0 : auto const &b21 = screen->btars[ip2][it1];
3536 0 : auto const &b22 = screen->btars[ip2][it2];
3537 0 : Real64 BmDfTrans = BilinearInterp(b11.DfTrans, b12.DfTrans, b21.DfTrans, b22.DfTrans, coeffs);
3538 0 : Real64 BmBmTrans = BilinearInterp(b11.BmTrans, b12.BmTrans, b21.BmTrans, b22.BmTrans, coeffs);
3539 :
3540 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3541 0 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
3542 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3543 0 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
3544 : #else // !PRECALC_INTERP_SCREEN
3545 : Material::ScreenBmTransAbsRef btar;
3546 :
3547 : Material::CalcScreenTransmittance(state, screen, phi, theta, btar);
3548 : Real64 BmDfTrans = btar.DfTrans;
3549 : Real64 BmBmTrans = btar.BmTrans;
3550 :
3551 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3552 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
3553 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3554 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
3555 : #endif // PRECALC_INTERP_SCREEN
3556 : }
3557 : }
3558 : }
3559 : } // Surface(SurfNum)%ExtSolar
3560 : } // end of surface window loop
3561 : } // end of space loop
3562 : } // end of zone loop
3563 71216 : for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
3564 0 : int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
3565 0 : int const ConstrNum = Surface(SurfNum).Construction;
3566 0 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3567 0 : int const TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
3568 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3569 0 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3570 0 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
3571 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3572 0 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) *
3573 0 : (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum)) +
3574 0 : state.dataSurface->SurfWinA(SurfNum, Lay) * currBeamSolar(SurfNum);
3575 0 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3576 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3577 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3578 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3579 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3580 : }
3581 : }
3582 :
3583 : // Average absorbed solar for representative surfaces
3584 71216 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
3585 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3586 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3587 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
3588 0 : int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
3589 0 : int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
3590 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
3591 0 : auto &surface = state.dataSurface->Surface(surfNum);
3592 0 : if (surface.ConstituentSurfaceNums.size() > 1) {
3593 0 : Real64 QoutAtot = 0.0;
3594 0 : Real64 QinAtot = 0.0;
3595 0 : Real64 Atot = 0.0;
3596 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3597 0 : QoutAtot += state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
3598 0 : QinAtot += state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
3599 0 : Atot += state.dataSurface->Surface(constSurfNum).Area;
3600 : }
3601 :
3602 0 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = QoutAtot / Atot;
3603 0 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = QinAtot / Atot;
3604 : }
3605 : }
3606 0 : firstSurf = thisSpace.WindowSurfaceFirst;
3607 0 : lastSurf = thisSpace.WindowSurfaceLast;
3608 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
3609 0 : auto const &surface = state.dataSurface->Surface(surfNum);
3610 0 : if (surface.ExtSolar && surface.ConstituentSurfaceNums.size() > 1) {
3611 : // Absorbed in glazing
3612 : int totalGlassLayers =
3613 0 : state.dataConstruction->Construct(state.dataSurface->SurfActiveConstruction(surfNum)).TotGlassLayers;
3614 0 : for (int layer = 1; layer <= totalGlassLayers; ++layer) {
3615 0 : Real64 QAtot = 0.0;
3616 0 : Real64 Atot = 0.0;
3617 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3618 0 : QAtot +=
3619 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(constSurfNum, layer) * state.dataSurface->Surface(constSurfNum).Area;
3620 0 : Atot += state.dataSurface->Surface(constSurfNum).Area;
3621 : }
3622 :
3623 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, layer) = QAtot / Atot;
3624 : }
3625 :
3626 : // Absorbed by frame and dividers
3627 0 : if (surface.FrameDivider > 0) {
3628 0 : if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
3629 0 : Real64 QoutAtot = 0.0;
3630 0 : Real64 QinAtot = 0.0;
3631 0 : Real64 Atot = 0.0;
3632 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3633 0 : QoutAtot += state.dataSurface->SurfWinFrameQRadOutAbs(constSurfNum) *
3634 0 : state.dataSurface->SurfWinFrameArea(constSurfNum);
3635 0 : QinAtot += state.dataSurface->SurfWinFrameQRadInAbs(constSurfNum) *
3636 0 : state.dataSurface->SurfWinFrameArea(constSurfNum);
3637 0 : Atot += state.dataSurface->SurfWinFrameArea(constSurfNum);
3638 : }
3639 :
3640 0 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = QoutAtot / Atot;
3641 0 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = QinAtot / Atot;
3642 : }
3643 0 : if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
3644 0 : Real64 QoutAtot = 0.0;
3645 0 : Real64 QinAtot = 0.0;
3646 0 : Real64 Atot = 0.0;
3647 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3648 0 : QoutAtot += state.dataSurface->SurfWinDividerQRadOutAbs(constSurfNum) *
3649 0 : state.dataSurface->SurfWinDividerArea(constSurfNum);
3650 0 : QinAtot += state.dataSurface->SurfWinDividerQRadInAbs(constSurfNum) *
3651 0 : state.dataSurface->SurfWinDividerArea(constSurfNum);
3652 0 : Atot += state.dataSurface->SurfWinDividerArea(constSurfNum);
3653 : }
3654 :
3655 0 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = QoutAtot / Atot;
3656 0 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = QinAtot / Atot;
3657 : }
3658 : }
3659 : }
3660 : }
3661 : }
3662 : }
3663 : }
3664 71216 : } // End of sun-up check
3665 249960 : }
3666 :
3667 249958 : void InitIntSolarDistribution(EnergyPlusData &state)
3668 : {
3669 :
3670 : // SUBROUTINE INFORMATION:
3671 : // AUTHOR Anonymous
3672 : // DATE WRITTEN July 1977
3673 : // MODIFIED Oct 1999 (FW) to handle movable shades
3674 : // May 2000 (FW) to handle window frame and dividers
3675 : // May 2001 (FW) to handle window blinds
3676 : // Jan 2002 (FW) mods for between-glass shade/blind
3677 : // May 2006 (RR) to handle exterior window screens
3678 : // RE-ENGINEERED Mar98 (RKS)
3679 :
3680 : // PURPOSE OF THIS SUBROUTINE:
3681 : // This subroutine initializes the arrays associated with solar heat
3682 : // gains for both individual surfaces and for zones.
3683 :
3684 : // METHODOLOGY EMPLOYED:
3685 : // If the sun is down, all of the pertinent arrays are zeroed. If the
3686 : // sun is up, various calculations are made.
3687 :
3688 : // REFERENCES:
3689 : // (I)BLAST legacy routine QSUN
3690 :
3691 : using Dayltg::DistributeTDDAbsorbedSolar;
3692 : using namespace DataWindowEquivalentLayer;
3693 :
3694 249958 : auto &s_mat = state.dataMaterial;
3695 : // COMPUTE TOTAL SHORT-WAVE RADIATION ORIGINATING IN ZONE.
3696 : // Note: If sun is not up, QS is only internal gains
3697 605534 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3698 355576 : Real64 sumSpaceQLTSW = 0.0;
3699 728531 : for (int spaceNum : state.dataViewFactor->EnclSolInfo(enclosureNum).spaceNums) {
3700 372955 : sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
3701 : }
3702 355576 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) = state.dataHeatBal->EnclSolQD(enclosureNum) + sumSpaceQLTSW;
3703 355576 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) = sumSpaceQLTSW;
3704 : }
3705 :
3706 249958 : if (state.dataHeatBalSurf->InterZoneWindow) { // DO INTERZONE DISTRIBUTION.
3707 :
3708 2 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3709 :
3710 1 : if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclosureNum)) {
3711 :
3712 0 : for (int OtherenclosureNum = 1; OtherenclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++OtherenclosureNum) {
3713 :
3714 0 : if ((OtherenclosureNum != enclosureNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(OtherenclosureNum))) {
3715 0 : Real64 sumSpaceQLTSW = 0.0;
3716 0 : for (int spaceNum : state.dataViewFactor->EnclSolInfo(OtherenclosureNum).spaceNums) {
3717 0 : sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
3718 : }
3719 0 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) +=
3720 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
3721 0 : (state.dataHeatBal->EnclSolQD(OtherenclosureNum) + sumSpaceQLTSW);
3722 0 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) +=
3723 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) * sumSpaceQLTSW;
3724 0 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) +=
3725 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
3726 0 : state.dataHeatBal->EnclSolQD(OtherenclosureNum);
3727 0 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclosureNum) =
3728 0 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec;
3729 : }
3730 : }
3731 : }
3732 : }
3733 : }
3734 :
3735 : // Beam and diffuse solar on inside surfaces from interior windows (for reporting)
3736 :
3737 249958 : if (state.dataEnvrn->SunIsUp) {
3738 1136548 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
3739 1015102 : auto const &surface = state.dataSurface->Surface(SurfNum);
3740 : //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
3741 1015102 : if (surface.Class == DataSurfaces::SurfaceClass::Shading) continue;
3742 1015102 : int const enclosureNum = surface.SolarEnclIndex;
3743 1015102 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) =
3744 1015102 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) / state.dataViewFactor->EnclSolInfo(enclosureNum).TotalSurfArea;
3745 1015102 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) =
3746 1015102 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) * (surface.Area + state.dataSurface->SurfWinDividerArea(SurfNum));
3747 1015102 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) =
3748 1015102 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3749 : }
3750 : }
3751 :
3752 : // COMPUTE CONVECTIVE GAINS AND ZONE FLUX DENSITY.
3753 605534 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3754 355576 : auto const &thisSolEnclosure = state.dataViewFactor->EnclSolInfo(enclosureNum);
3755 355576 : if (state.dataHeatBalSurf->InterZoneWindow) {
3756 1 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) *=
3757 1 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
3758 : // CR 8695, VMULT not based on visible
3759 1 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *=
3760 1 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
3761 : } else {
3762 355575 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) *= thisSolEnclosure.solVMULT;
3763 355575 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *= thisSolEnclosure.solVMULT;
3764 : }
3765 : }
3766 :
3767 : // COMPUTE RADIANT GAINS ON SURFACES
3768 586610 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3769 709607 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3770 372955 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
3771 372955 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
3772 372955 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
3773 2358719 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
3774 1985764 : auto const &surface = state.dataSurface->Surface(SurfNum);
3775 1985764 : int const solEnclosureNum = surface.SolarEnclIndex;
3776 1985764 : int const ConstrNum = surface.Construction;
3777 1985764 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3778 :
3779 1985764 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum);
3780 : // TODO - AbsIntSurfVis = InsideAbsorpSolar instead of InsideAbsorpVis?
3781 1985764 : Real64 AbsIntSurfVis = thisConstruct.InsideAbsorpSolar; // Inside opaque surface visible absorptance to fix CR 8695 change to
3782 :
3783 1985764 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsIntSurf;
3784 1985764 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) += state.dataHeatBal->EnclSolQSWRadLights(solEnclosureNum) * AbsIntSurfVis;
3785 :
3786 : // Calculate absorbed solar on outside if movable exterior insulation in place
3787 1985764 : if (state.dataSurface->AnyMovableInsulation) {
3788 0 : auto &movInsul = state.dataSurface->extMovInsuls(SurfNum);
3789 0 : if (movInsul.present) {
3790 0 : Real64 AbsExt = state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum);
3791 0 : auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
3792 0 : state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) =
3793 0 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) * AbsExt / thisMaterial->AbsorpSolar;
3794 : // For transparent insulation, allow some sunlight to get through the movable insulation.
3795 : // The equation below is derived by taking what is transmitted through the layer and applying
3796 : // the fraction that is absorbed plus the back reflected portion (first order reflection only)
3797 : // to the plane between the transparent insulation and the exterior surface face.
3798 0 : auto const *matMovInsul = s_mat->materials(movInsul.matNum);
3799 0 : auto const *matFenMovInsul = dynamic_cast<Material::MaterialFen const *>(matMovInsul);
3800 0 : Real64 transMovInsul = (matFenMovInsul != nullptr) ? matFenMovInsul->Trans : 0.0;
3801 :
3802 0 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
3803 0 : transMovInsul * state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) *
3804 0 : ((thisMaterial->AbsorpSolar / AbsExt) + (1 - thisMaterial->AbsorpSolar));
3805 : }
3806 : }
3807 : // RJH 08/30/07 - Add SurfWinInitialDifSolInAbs, SurfWinInitialDifSolwinAbs, and SurfWinInitialDifSolAbsByShade
3808 : // calced in CalcWinTransDifSolInitialDistribution to SurfOpaqQRadSWInAbs, SurfWinQRadSWwinAbs, and SurfWinIntSWAbsByShade here
3809 1985764 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum);
3810 : } // end of opaque
3811 :
3812 372955 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
3813 372955 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
3814 461519 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { // Window
3815 88564 : auto const &surface = state.dataSurface->Surface(SurfNum);
3816 88564 : auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
3817 88564 : int const radEnclosureNum = surface.RadEnclIndex;
3818 88564 : int const solEnclosureNum = surface.SolarEnclIndex;
3819 88564 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3820 88564 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3821 :
3822 88564 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) {
3823 86195 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
3824 :
3825 86195 : int TotGlassLayers = thisConstruct.TotGlassLayers;
3826 86195 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
3827 :
3828 : // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
3829 86195 : Real64 pulseMultipler = 0.01; // use to create a pulse for the load component report computations, the W/sqft pulse for the zone
3830 86195 : if (!state.dataGlobal->doLoadComponentPulseNow) {
3831 86189 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
3832 86189 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3833 86189 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
3834 : } else {
3835 : // radiant value prior to adjustment for pulse for load component report
3836 6 : Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
3837 : // for the loads component report during the special sizing run increase the radiant portion
3838 : // a small amount to create a "pulse" of heat that is used for the
3839 : // radiant value including adjustment for pulse for load component report
3840 6 : Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
3841 : // ITABSF is the Inside Thermal Absorptance
3842 : // EnclRadThermAbsMult is a multiplier for each zone/enclosure
3843 : // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
3844 6 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
3845 6 : adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
3846 6 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
3847 : }
3848 :
3849 86195 : if (NOT_SHADED(ShadeFlag)) { // No window shading
3850 196685 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
3851 110490 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3852 110490 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
3853 : }
3854 0 : } else if (ConstrNumSh != 0 && ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
3855 : // Interior, exterior or between-glass shade, screen or blind in place
3856 0 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
3857 0 : for (int IGlass = 1; IGlass <= constrSh.TotGlassLayers; ++IGlass) {
3858 0 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
3859 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3860 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBack(IGlass);
3861 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind || ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) {
3862 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3863 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3864 0 : auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxLo];
3865 0 : auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxHi];
3866 : // Glass layer back diffuse solar absorptance when blind in place
3867 0 : Real64 BlAbsDiffBk = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
3868 :
3869 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3870 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * BlAbsDiffBk;
3871 : }
3872 : }
3873 0 : if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
3874 0 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3875 0 : constrSh.ShadeAbsorpThermal *
3876 0 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
3877 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
3878 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3879 0 : Real64 EffBlEmiss = surfShade.effShadeEmi; // Blind emissivity (thermal absorptance) as part of glazing system
3880 0 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3881 0 : EffBlEmiss *
3882 0 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
3883 : }
3884 :
3885 0 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
3886 0 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) =
3887 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBackShade;
3888 0 : } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
3889 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3890 0 : auto const &btarLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
3891 0 : auto const &btarHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
3892 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3893 0 : Real64 AbsDiffBkBl = Interp(btarLo.Sol.Bk.Df.Abs, btarHi.Sol.Bk.Df.Abs, interpFac);
3894 :
3895 0 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsDiffBkBl;
3896 : }
3897 : // Correct for divider shadowing
3898 0 : if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3899 0 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) *= surfWin.glazedFrac;
3900 : }
3901 :
3902 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3903 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh); // What was here before?
3904 0 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
3905 :
3906 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3907 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
3908 0 : Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
3909 0 : thisConstruct.AbsDiffBack(IGlass),
3910 0 : constructionSh.AbsDiffBack(IGlass));
3911 : }
3912 :
3913 : } // End of shading flag check
3914 :
3915 : // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
3916 86195 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0)
3917 3 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) +=
3918 3 : (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) +
3919 3 : (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3920 3 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
3921 3 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
3922 3 : state.dataSurface->SurfWinFrameEmis(SurfNum)) *
3923 3 : (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)); // Window has a frame
3924 86195 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) { // Window has dividers
3925 3 : Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
3926 3 : Real64 DividerSolAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
3927 3 : if (state.dataSurface->SurfWinDividerType(SurfNum) ==
3928 : DataSurfaces::FrameDividerType::Suspended) { // Suspended divider; account for inside glass
3929 0 : Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass layer material number
3930 0 : auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
3931 0 : assert(thisMaterial != nullptr);
3932 0 : Real64 TransGl = thisMaterial->Trans; // Glass layer solar transmittance, reflectance, absorptance
3933 0 : Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
3934 0 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
3935 0 : Real64 DividerSolRefl = 1.0 - DividerSolAbs; // Window divider solar reflectance
3936 0 : DividerSolAbs = AbsGl + TransGl * (DividerSolAbs + DividerSolRefl * AbsGl) / (1.0 - DividerSolRefl * ReflGl);
3937 0 : DividerThermAbs = thisMaterial->AbsorpThermalBack;
3938 : }
3939 : // Correct for interior shade transmittance
3940 3 : if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
3941 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3942 0 : int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers); // Shade layer material number
3943 0 : auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
3944 0 : assert(matSh != nullptr);
3945 0 : DividerSolAbs *= matSh->Trans;
3946 0 : DividerThermAbs *= matSh->TransThermal;
3947 :
3948 3 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
3949 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3950 0 : Real64 SolBackDiffDiffTrans = surfShade.blind.TAR.Sol.Bk.Df.Tra;
3951 0 : Real64 IRBackTrans = surfShade.blind.TAR.IR.Bk.Tra;
3952 :
3953 0 : DividerSolAbs *= SolBackDiffDiffTrans;
3954 0 : DividerThermAbs *= IRBackTrans;
3955 : }
3956 : // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
3957 3 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) +=
3958 3 : (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * DividerSolAbs +
3959 3 : (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3960 3 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
3961 3 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
3962 3 : DividerThermAbs) *
3963 3 : (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
3964 : }
3965 : } else {
3966 : // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
3967 2369 : Real64 pulseMultipler = 0.01; // the W/sqft pulse for the zone
3968 2369 : if (!state.dataGlobal->doLoadComponentPulseNow) {
3969 2369 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
3970 2369 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3971 2369 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
3972 : } else {
3973 : // radiant value prior to adjustment for pulse for load component report
3974 0 : Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
3975 : // for the loads component report during the special sizing run increase the radiant portion
3976 : // a small amount to create a "pulse" of heat that is used for the
3977 : // radiant value including adjustment for pulse for load component report
3978 0 : Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
3979 : // ITABSF is the Inside Thermal Absorptance
3980 : // EnclRadThermAbsMult is a multiplier for each zone/radiant enclosure
3981 : // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
3982 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
3983 0 : adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
3984 0 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
3985 : }
3986 : // Radiations absorbed by the window layers coming from zone side
3987 2369 : int EQLNum = thisConstruct.EQLConsPtr;
3988 8580 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
3989 6211 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) +=
3990 6211 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffBackEQL(Lay);
3991 : }
3992 : // Window frame has not been included for equivalent layer model yet
3993 :
3994 : } // end if for IF ( SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: EQL) THEN
3995 :
3996 88564 : if (surface.ExtBoundCond > 0) { // Interzone surface
3997 : // Short-wave radiation absorbed in panes of corresponding window in adjacent zone
3998 0 : int SurfNumAdjZone = surface.ExtBoundCond; // Surface number in adjacent zone for interzone surfaces
3999 0 : if (state.dataSurface->SurfWinWindowModelType(SurfNumAdjZone) != DataSurfaces::WindowModel::EQL) {
4000 0 : int TotGlassLayers = thisConstruct.TotGlassLayers;
4001 0 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4002 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, IGlass) +=
4003 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
4004 0 : state.dataConstruction->Construct(state.dataSurface->Surface(SurfNumAdjZone).Construction).AbsDiff(IGlass);
4005 : // Note that AbsDiff rather than AbsDiffBack is used in the above since the
4006 : // radiation from the current zone is incident on the outside of the adjacent
4007 : // zone's window.
4008 : }
4009 : } else { // IF (SurfaceWindow(SurfNumAdjZone)%WindowModelType == WindowModel:: EQL) THEN
4010 0 : int const AdjConstrNum = state.dataSurface->Surface(SurfNumAdjZone).Construction;
4011 0 : int const EQLNum = state.dataConstruction->Construct(AdjConstrNum).EQLConsPtr;
4012 0 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4013 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, Lay) +=
4014 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffFrontEQL(Lay);
4015 : // Note that AbsDiffFrontEQL rather than AbsDiffBackEQL is used in the above
4016 : // since the radiation from the current zone is incident on the outside of the
4017 : // adjacent zone's window.
4018 : }
4019 : }
4020 : }
4021 :
4022 88564 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) {
4023 86195 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
4024 86195 : int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
4025 86195 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4026 86195 : if (DataSurfaces::NOT_SHADED(ShadeFlag)) { // No window shading
4027 196685 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4028 110490 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4029 : }
4030 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
4031 0 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4032 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4033 : }
4034 : } else {
4035 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4036 : // Interior, exterior or between-glass shade, screen or blind in place
4037 0 : for (int IGlass = 1; IGlass <= constructionSh.TotGlassLayers; ++IGlass) {
4038 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4039 : }
4040 0 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag) || DataSurfaces::ANY_BLIND(ShadeFlag)) {
4041 0 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum);
4042 : }
4043 : } // End of shading flag check
4044 2369 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
4045 0 : int TotGlassLayers = thisConstruct.TotGlassLayers;
4046 0 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4047 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4048 : }
4049 2369 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
4050 :
4051 : // ConstrNum = Surface(SurfNum)%Construction
4052 2369 : int EQLNum = thisConstruct.EQLConsPtr;
4053 :
4054 8580 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4055 6211 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay);
4056 : }
4057 : }
4058 :
4059 : } // End of window
4060 : }
4061 : }
4062 249958 : Dayltg::DistributeTDDAbsorbedSolar(state);
4063 249958 : }
4064 :
4065 249957 : void ComputeIntThermalAbsorpFactors(EnergyPlusData &state)
4066 : {
4067 :
4068 : // SUBROUTINE INFORMATION:
4069 : // AUTHOR Legacy Code (George Walton)
4070 : // DATE WRITTEN Legacy: Dec 1976
4071 : // MODIFIED Nov. 99, FCW: to take into account movable interior shades and switchable glazing
4072 : // June 01, FCW: to take into account interior blinds.
4073 :
4074 : // PURPOSE OF THIS SUBROUTINE:
4075 : // This routine computes the fractions of long-wave radiation from lights, equipment and people
4076 : // that is absorbed by each zone surface.
4077 :
4078 : // METHODOLOGY EMPLOYED:
4079 : // The fraction is assumed to be proportional to the product of the surface area times its thermal absorptivity.
4080 :
4081 : // REFERENCES:
4082 : // BLAST Routine: CITAF - Compute Interior Thermal Absorption Factors
4083 249957 : auto &s_mat = state.dataMaterial;
4084 :
4085 605532 : for (auto const &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
4086 355575 : if (!thisEnclosure.radReCalc) continue;
4087 20440 : for (int spaceNum : thisEnclosure.spaceNums) {
4088 10245 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4089 10245 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
4090 10245 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
4091 14181 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
4092 3936 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4093 3936 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4094 1 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4095 1 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
4096 : } else {
4097 3935 : int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
4098 3935 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal;
4099 : }
4100 : }
4101 : }
4102 : }
4103 249957 : if (state.dataSurface->AnyMovableSlat) {
4104 0 : for (int SurfNum : state.dataHeatBalSurf->SurfMovSlatsIndexList) {
4105 : // For window with an interior shade or blind, emissivity is a combination of glass and shade/blind emissivity
4106 0 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4107 : // Not sure we need to do this anymore
4108 0 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4109 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4110 0 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
4111 : }
4112 : }
4113 : }
4114 :
4115 605532 : for (auto &thisRadEnclosure : state.dataViewFactor->EnclRadInfo) {
4116 355575 : if (!thisRadEnclosure.radReCalc) continue;
4117 10195 : Real64 SUM1 = 0.0;
4118 69427 : for (int const SurfNum : thisRadEnclosure.SurfacePtr) {
4119 59232 : auto &surf = state.dataSurface->Surface(SurfNum);
4120 59232 : int const ConstrNum = surf.Construction;
4121 59232 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
4122 59232 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4123 59232 : if (ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
4124 59232 : SUM1 += surf.Area * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
4125 : } else { // Switchable glazing
4126 0 : SUM1 += surf.Area * Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
4127 0 : thisConstruct.InsideAbsorpThermal,
4128 0 : state.dataConstruction->Construct(surf.activeShadedConstruction).InsideAbsorpThermal);
4129 : }
4130 :
4131 : // Window frame and divider effects
4132 59232 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0)
4133 1 : SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) *
4134 1 : state.dataSurface->SurfWinFrameEmis(SurfNum);
4135 59232 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
4136 1 : Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
4137 : // Suspended (between-glass) divider; relevant emissivity is inner glass emissivity
4138 1 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended)
4139 0 : DividerThermAbs = thisConstruct.InsideAbsorpThermal;
4140 1 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4141 : // Interior shade or blind in place
4142 0 : int const ConstrNumSh = surf.activeShadedConstruction;
4143 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4144 :
4145 0 : if (state.dataSurface->SurfWinHasShadeOrBlindLayer(SurfNum)) {
4146 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4147 : // Shade layer material number
4148 0 : int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers);
4149 0 : auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
4150 0 : assert(matSh != nullptr);
4151 : // Shade or blind IR transmittance
4152 0 : Real64 TauShIR = matSh->TransThermal;
4153 : // Effective emissivity of shade or blind
4154 0 : Real64 EffShDevEmiss = surfShade.effShadeEmi;
4155 :
4156 0 : if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
4157 0 : TauShIR = surfShade.blind.TAR.IR.Bk.Tra;
4158 : }
4159 0 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (EffShDevEmiss + DividerThermAbs * TauShIR);
4160 : } else {
4161 : // this is for EMS activated shade/blind but the window construction has no shade/blind layer
4162 0 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
4163 : DividerThermAbs;
4164 : }
4165 : } else {
4166 1 : SUM1 +=
4167 1 : state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * DividerThermAbs;
4168 : }
4169 : }
4170 :
4171 : } // End of loop over surfaces in zone/enclosure
4172 10195 : thisRadEnclosure.radThermAbsMult = 1.0 / SUM1;
4173 :
4174 : } // End of loop over enclosures
4175 249957 : }
4176 :
4177 249956 : void ComputeIntSWAbsorpFactors(EnergyPlusData &state)
4178 : {
4179 :
4180 : // SUBROUTINE INFORMATION:
4181 : // AUTHOR Legacy (George Walton)
4182 : // DATE WRITTEN Legacy (December 1980)
4183 : // MODIFIED Nov. 99, FW; now called every time step to account for movable
4184 : // window shades and insulation
4185 : // Mar. 00, FW; change name from ComputeVisLightingAbsorpFactors
4186 : // to ComputeIntSWAbsorpFactors
4187 : // May 00, FW; add window frame and divider effects
4188 : // June 01, FW: account for window blinds
4189 : // Nov 01, FW: account for absorptance of exterior shades and interior or exterior blinds
4190 : // Jan 03, FW: add between-glass shade/blind
4191 : // May 06, RR: account for exterior window screens
4192 :
4193 : // PURPOSE OF THIS SUBROUTINE:
4194 : // Computes VMULT, the inverse of the sum of area*(short-wave absorptance+transmittance) for
4195 : // the surfaces in a zone. VMULT is used to calculate the zone interior diffuse short-wave radiation
4196 : // absorbed by the inside of opaque zone surfaces or by the glass and shade/blind layers of zone windows.
4197 :
4198 : // Sets VCONV to zero (VCONV was formerly used to calculate convective gain due to short-wave
4199 : // radiation absorbed by interior window shades).
4200 :
4201 : // REFERENCES:
4202 : // BLAST Routine - CIVAF - Compute Surface Absorption Factors For Short Wave Radiation
4203 : // From Zone Lights And Diffuse Solar.
4204 :
4205 : // Avoid a division by zero of the user has entered a bunch of surfaces with zero absorptivity on the inside
4206 249956 : Real64 constexpr SmallestAreaAbsProductAllowed(0.01);
4207 :
4208 249956 : auto &s_mat = state.dataMaterial;
4209 :
4210 605530 : for (auto &thisSolEnclosure : state.dataViewFactor->EnclSolInfo) {
4211 355574 : if (!thisSolEnclosure.radReCalc) continue;
4212 10194 : Real64 SUM1 = 0.0; // Intermediate calculation value for solar absorbed and transmitted
4213 :
4214 69425 : for (int const SurfNum : thisSolEnclosure.SurfacePtr) {
4215 59231 : auto &thisSurf = state.dataSurface->Surface(SurfNum);
4216 59231 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
4217 59231 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
4218 59231 : if (thisConstruct.TransDiff <= 0.0) {
4219 : // Opaque surface
4220 55358 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum); // Inside surface short-wave absorptance
4221 55358 : SUM1 += thisSurf.Area * AbsIntSurf;
4222 :
4223 : } else {
4224 : // Window
4225 3873 : if (!state.dataConstruction->Construct(thisSurf.Construction).WindowTypeEQL) {
4226 1566 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4227 :
4228 1566 : Real64 AbsDiffTotWin = 0.0; // Sum of window layer short-wave absorptances
4229 1566 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
4230 1566 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
4231 :
4232 : // Sum of absorptances of glass layers
4233 3201 : for (int Lay = 1; Lay <= thisConstruct.TotGlassLayers; ++Lay) {
4234 1635 : Real64 AbsDiffLayWin = thisConstruct.AbsDiffBack(Lay); // Window layer short-wave absorptance
4235 :
4236 : // Window with shade, screen or blind
4237 1635 : if (ConstrNumSh != 0) {
4238 64 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4239 64 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
4240 0 : AbsDiffLayWin = constrSh.AbsDiffBack(Lay);
4241 64 : } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
4242 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4243 0 : auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxLo];
4244 0 : auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxHi];
4245 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
4246 0 : AbsDiffLayWin = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
4247 : }
4248 : }
4249 :
4250 : // Switchable glazing
4251 1635 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
4252 0 : assert(ConstrNumSh > 0); // Should this be included in the if above
4253 0 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4254 0 : AbsDiffLayWin = Window::InterpSw(SwitchFac, AbsDiffLayWin, constrSh.AbsDiffBack(Lay));
4255 : }
4256 1635 : AbsDiffTotWin += AbsDiffLayWin;
4257 : }
4258 :
4259 1566 : Real64 TransDiffWin = thisConstruct.TransDiff; // Window diffuse short-wave transmittance
4260 1566 : Real64 DiffAbsShade = 0.0; // Diffuse short-wave shade or blind absorptance
4261 :
4262 : // Window with shade, screen or blind
4263 :
4264 1566 : if (ConstrNumSh != 0) {
4265 64 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4266 64 : if (ANY_SHADE_SCREEN(ShadeFlag)) {
4267 0 : TransDiffWin = constrSh.TransDiff;
4268 0 : DiffAbsShade = constrSh.AbsDiffBackShade;
4269 64 : } else if (ANY_BLIND(ShadeFlag)) {
4270 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4271 0 : auto const &btarSlatLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
4272 0 : auto const &btarSlatHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
4273 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
4274 0 : TransDiffWin = Interp(btarSlatLo.Sol.Ft.Df.Tra, btarSlatHi.Sol.Ft.Df.Tra, interpFac);
4275 0 : DiffAbsShade = Interp(btarSlatLo.Sol.Bk.Df.Abs, btarSlatHi.Sol.Bk.Df.Abs, interpFac);
4276 : }
4277 : }
4278 :
4279 : // Switchable glazing
4280 :
4281 1566 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
4282 0 : assert(ConstrNumSh > 0);
4283 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4284 0 : TransDiffWin = Window::InterpSw(SwitchFac, TransDiffWin, constructionSh.TransDiff);
4285 : }
4286 :
4287 1566 : SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin + DiffAbsShade);
4288 :
4289 : // Window frame and divider effects (shade area is glazed area plus divider area)
4290 :
4291 1566 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0)
4292 1 : SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) *
4293 1 : (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum));
4294 1566 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
4295 1 : Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
4296 1 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
4297 : // Suspended (between-glass) divider: account for glass on inside of divider
4298 0 : Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass material number
4299 0 : auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
4300 0 : assert(thisMaterial != nullptr);
4301 0 : Real64 TransGl = thisMaterial->Trans; // Glass layer short-wave transmittance, reflectance, absorptance
4302 0 : Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
4303 0 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
4304 0 : Real64 DividerRefl = 1.0 - DividerAbs; // Window divider short-wave reflectance
4305 0 : DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
4306 : }
4307 1 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4308 0 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (DividerAbs + DiffAbsShade);
4309 : } else {
4310 1 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
4311 : DividerAbs;
4312 : }
4313 : }
4314 : } else { // equivalent layer window
4315 : // In equivalent layer window solid layers (Glazing and shades) are treated equally
4316 : // frames and dividers are not supported
4317 2307 : Real64 AbsDiffTotWin = 0.0;
4318 2307 : Real64 AbsDiffLayWin = 0.0;
4319 2307 : Real64 TransDiffWin = thisConstruct.TransDiff;
4320 8358 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL; ++Lay) {
4321 6051 : AbsDiffLayWin = thisConstruct.AbsDiffBackEQL(Lay);
4322 6051 : AbsDiffTotWin += AbsDiffLayWin;
4323 : }
4324 2307 : SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin);
4325 : }
4326 : } // End of check if opaque surface or window
4327 : } // End of loop over surfaces in zone
4328 :
4329 10194 : if (SUM1 > SmallestAreaAbsProductAllowed) { // Everything is okay, proceed with the regular calculation
4330 10194 : thisSolEnclosure.solVMULT = 1.0 / SUM1;
4331 :
4332 : } else { // the sum of area*solar absorptance for all surfaces in the zone is zero--either the user screwed up
4333 : // or they really want to disallow any solar from being absorbed on the inside surfaces. Fire off a
4334 : // nasty warning message and then assume that no solar is ever absorbed (basically everything goes
4335 : // back out whatever window is there. Note that this also assumes that the shade has no effect.
4336 : // That's probably not correct, but how correct is it to assume that no solar is absorbed anywhere
4337 : // in the zone?
4338 0 : if (thisSolEnclosure.solAbsFirstCalc) {
4339 0 : ShowWarningError(
4340 : state,
4341 0 : format("ComputeIntSWAbsorbFactors: Sum of area times inside solar absorption for all surfaces is zero in Enclosure: {}",
4342 0 : thisSolEnclosure.Name));
4343 0 : thisSolEnclosure.solAbsFirstCalc = false;
4344 : }
4345 0 : thisSolEnclosure.solVMULT = 0.0;
4346 : }
4347 : } // End of enclosure loop
4348 249956 : }
4349 :
4350 4 : void ComputeDifSolExcZonesWIZWindows(EnergyPlusData &state)
4351 : {
4352 :
4353 : // SUBROUTINE INFORMATION:
4354 : // MODIFIED Jun 2007 - Lawrie - Speed enhancements.
4355 : // RE-ENGINEERED Winkelmann, Lawrie
4356 :
4357 : // PURPOSE OF THIS SUBROUTINE:
4358 : // This subroutine computes the diffuse solar exchange factors between enclosures with
4359 : // interzone windows.
4360 :
4361 4 : int const numEnclosures = state.dataViewFactor->NumOfSolarEnclosures;
4362 4 : if (!allocated(state.dataHeatBalSurf->ZoneFractDifShortZtoZ)) {
4363 2 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ.allocate(numEnclosures, numEnclosures);
4364 2 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ.allocate(numEnclosures);
4365 2 : state.dataHeatBalSurfMgr->DiffuseArray.allocate(numEnclosures, numEnclosures);
4366 : }
4367 :
4368 4 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ = false;
4369 4 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ.to_identity();
4370 4 : state.dataHeatBalSurfMgr->DiffuseArray.to_identity();
4371 :
4372 : // IF (.not. ANY(Zone%HasInterZoneWindow)) RETURN ! this caused massive diffs
4373 4 : if (state.dataGlobal->KickOffSimulation || state.dataGlobal->KickOffSizing) return;
4374 : // Compute fraction transmitted in one pass.
4375 :
4376 6 : for (int const SurfNum : state.dataSurface->AllHTWindowSurfaceList) {
4377 4 : auto &surface = state.dataSurface->Surface(SurfNum);
4378 4 : if (surface.ExtBoundCond <= 0) continue;
4379 4 : if (surface.ExtBoundCond == SurfNum) continue;
4380 4 : if (state.dataConstruction->Construct(surface.Construction).TransDiff <= 0.0) continue;
4381 :
4382 4 : int surfEnclNum = surface.SolarEnclIndex;
4383 4 : if (!state.dataViewFactor->EnclSolInfo(surfEnclNum).HasInterZoneWindow) continue;
4384 2 : int MZ = state.dataSurface->Surface(surface.ExtBoundCond).SolarEnclIndex;
4385 4 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(surfEnclNum, MZ) += state.dataConstruction->Construct(surface.Construction).TransDiff *
4386 2 : state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT * surface.Area;
4387 2 : if (state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT != 0.0) state.dataHeatBalSurf->EnclSolRecDifShortFromZ(surfEnclNum) = true;
4388 : }
4389 : // Compute fractions for multiple passes.
4390 :
4391 2 : Array2D<Real64>::size_type l(0u), m(0u), d(0u);
4392 8 : for (int NZ = 1; NZ <= numEnclosures; ++NZ, d += numEnclosures + 1) {
4393 6 : m = NZ - 1;
4394 6 : Real64 D_d(0.0); // Local accumulator
4395 24 : for (int MZ = 1; MZ <= numEnclosures; ++MZ, ++l, m += numEnclosures) {
4396 18 : if (MZ == NZ) continue;
4397 12 : state.dataHeatBalSurfMgr->DiffuseArray[l] =
4398 12 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] /
4399 24 : (1.0 - state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] *
4400 12 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m]); // [ l ] == ( MZ, NZ ), [ m ] == ( NZ, MZ )
4401 12 : D_d += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m] * state.dataHeatBalSurfMgr->DiffuseArray[l];
4402 : }
4403 6 : state.dataHeatBalSurfMgr->DiffuseArray[d] += D_d; // [ d ] == ( NZ, NZ )
4404 : }
4405 :
4406 2 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ = state.dataHeatBalSurfMgr->DiffuseArray;
4407 : // added for CR 7999 & 7869
4408 2 : assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize1() == numEnclosures);
4409 2 : assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize2() == numEnclosures);
4410 8 : for (int NZ = 1; NZ <= numEnclosures; ++NZ) {
4411 19 : for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
4412 15 : if (MZ == NZ) continue;
4413 10 : if (state.dataHeatBalSurf->ZoneFractDifShortZtoZ(MZ, NZ) > 0.0) {
4414 2 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ(NZ) = true;
4415 2 : break;
4416 : }
4417 : }
4418 : }
4419 :
4420 : // Compute fractions for multiple zones.
4421 :
4422 8 : for (int IZ = 1; IZ <= numEnclosures; ++IZ) {
4423 6 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(IZ)) continue;
4424 :
4425 8 : for (int JZ = 1; JZ <= numEnclosures; ++JZ) {
4426 6 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(JZ)) continue;
4427 4 : if (IZ == JZ) continue;
4428 2 : if (state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ) == 0.0) continue;
4429 :
4430 8 : for (int KZ = 1; KZ <= numEnclosures; ++KZ) {
4431 6 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(KZ)) continue;
4432 4 : if (IZ == KZ) continue;
4433 2 : if (JZ == KZ) continue;
4434 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) == 0.0) continue;
4435 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, KZ) +=
4436 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4437 :
4438 0 : for (int LZ = 1; LZ <= numEnclosures; ++LZ) {
4439 0 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(LZ)) continue;
4440 0 : if (IZ == LZ) continue;
4441 0 : if (JZ == LZ) continue;
4442 0 : if (KZ == LZ) continue;
4443 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) == 0.0) continue;
4444 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, LZ) += state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
4445 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) *
4446 0 : state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4447 :
4448 0 : for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
4449 0 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(MZ)) continue;
4450 0 : if (IZ == MZ) continue;
4451 0 : if (JZ == MZ) continue;
4452 0 : if (KZ == MZ) continue;
4453 0 : if (LZ == MZ) continue;
4454 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) == 0.0) continue;
4455 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, MZ) +=
4456 0 : state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) * state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
4457 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4458 : } // MZ Loop
4459 :
4460 : } // LZ Loop
4461 :
4462 : } // KZ Loop
4463 :
4464 : } // JZ Loop
4465 :
4466 : } // IZ Loop
4467 : } // ComputeDifSolExcZoneWIZWindows()
4468 :
4469 116073 : void InitEMSControlledSurfaceProperties(EnergyPlusData &state)
4470 : {
4471 :
4472 : // SUBROUTINE INFORMATION:
4473 : // AUTHOR B. Griffith
4474 : // DATE WRITTEN April 2011
4475 :
4476 : // PURPOSE OF THIS SUBROUTINE:
4477 : // initialize material and construction surface properties if being overridden by EMS
4478 :
4479 : // METHODOLOGY EMPLOYED:
4480 : // update solar, thermal and visible absorptance values when actuated by EMS
4481 :
4482 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4483 : int TotLayers; // count of material layers in a construction
4484 : int InsideMaterNum; // integer pointer for inside face's material layer
4485 : int OutsideMaterNum; // integer pointer for outside face's material layer
4486 :
4487 116073 : auto &s_mat = state.dataMaterial;
4488 :
4489 116073 : state.dataGlobal->AnySurfPropOverridesInModel = false;
4490 : // first determine if anything needs to be done, once yes, then always init
4491 736781 : for (auto const *mat : s_mat->materials) {
4492 620708 : if (mat->group != Material::Group::Regular) continue;
4493 :
4494 613277 : if ((mat->AbsorpSolarEMSOverrideOn) || (mat->AbsorpThermalEMSOverrideOn) || (mat->AbsorpVisibleEMSOverrideOn)) {
4495 0 : state.dataGlobal->AnySurfPropOverridesInModel = true;
4496 0 : break;
4497 : }
4498 : }
4499 :
4500 116073 : if (!state.dataGlobal->AnySurfPropOverridesInModel) return; // quick return if nothing has ever needed to be done
4501 :
4502 : // first, loop over materials
4503 : // why is this a second loop?
4504 0 : for (auto *mat : s_mat->materials) {
4505 0 : if (mat->group != Material::Group::Regular) continue;
4506 :
4507 0 : mat->AbsorpSolar = mat->AbsorpSolarEMSOverrideOn ? max(min(mat->AbsorpSolarEMSOverride, 0.9999), 0.0001) : mat->AbsorpSolarInput;
4508 0 : mat->AbsorpThermal = mat->AbsorpThermalEMSOverrideOn ? max(min(mat->AbsorpThermalEMSOverride, 0.9999), 0.0001) : mat->AbsorpThermalInput;
4509 0 : mat->AbsorpVisible = mat->AbsorpVisibleEMSOverrideOn ? max(min(mat->AbsorpVisibleEMSOverride, 0.9999), 0.0001) : mat->AbsorpVisibleInput;
4510 : } // loop over materials
4511 :
4512 : // second, loop over constructions
4513 0 : for (auto &thisConstruct : state.dataConstruction->Construct) {
4514 0 : if (thisConstruct.TypeIsWindow) continue; // only override opaque constructions
4515 0 : TotLayers = thisConstruct.TotLayers;
4516 0 : if (TotLayers == 0) continue; // error condition
4517 0 : InsideMaterNum = thisConstruct.LayerPoint(TotLayers);
4518 0 : if (InsideMaterNum != 0) {
4519 0 : auto const *mat = s_mat->materials(InsideMaterNum);
4520 0 : thisConstruct.InsideAbsorpVis = mat->AbsorpVisible;
4521 0 : thisConstruct.InsideAbsorpSolar = mat->AbsorpSolar;
4522 0 : thisConstruct.InsideAbsorpThermal = mat->AbsorpThermal;
4523 : }
4524 :
4525 0 : OutsideMaterNum = thisConstruct.LayerPoint(1);
4526 0 : if (OutsideMaterNum != 0) {
4527 0 : auto const *mat = s_mat->materials(OutsideMaterNum);
4528 0 : thisConstruct.OutsideAbsorpVis = mat->AbsorpVisible;
4529 0 : thisConstruct.OutsideAbsorpSolar = mat->AbsorpSolar;
4530 0 : thisConstruct.OutsideAbsorpThermal = mat->AbsorpThermal;
4531 : }
4532 : } // for (ConstrNum)
4533 : } // InitEMSControlledSurfaceProperties()
4534 :
4535 116073 : void InitEMSControlledConstructions(EnergyPlusData &state)
4536 : {
4537 :
4538 : // SUBROUTINE INFORMATION:
4539 : // AUTHOR B. Griffith
4540 : // DATE WRITTEN Jan 2012
4541 :
4542 : // PURPOSE OF THIS SUBROUTINE:
4543 : // change construction on surface if overridden by EMS
4544 :
4545 116073 : state.dataGlobal->AnyConstrOverridesInModel = false;
4546 854204 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4547 745241 : if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum)) {
4548 7110 : state.dataGlobal->AnyConstrOverridesInModel = true;
4549 7110 : break;
4550 : }
4551 : }
4552 116073 : if (!state.dataGlobal->AnyConstrOverridesInModel) return;
4553 :
4554 45714 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4555 38604 : auto &surface = state.dataSurface->Surface(SurfNum);
4556 :
4557 38604 : if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum) && (state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum) > 0)) {
4558 :
4559 7110 : if (state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
4560 7110 : .TypeIsWindow) { // okay, always allow windows
4561 1352 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
4562 1352 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
4563 : }
4564 :
4565 14216 : if ((state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) &&
4566 7106 : (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum))) {
4567 :
4568 7106 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4569 7106 : state.dataConstruction->Construct(surface.Construction).IsUsed = true;
4570 7106 : state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4571 :
4572 : } else { // have not checked yet or is not okay, so see if we need to warn about incompatible
4573 4 : if (!state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) {
4574 : // check if constructions appear compatible
4575 :
4576 4 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
4577 0 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
4578 : // compare old construction to new construction and see if terms match
4579 : // set as okay and turn false if find a big problem
4580 4 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4581 : true;
4582 4 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4583 : true;
4584 4 : if (state.dataConstruction->Construct(surface.Construction).NumHistories !=
4585 4 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories) {
4586 : // throw warning, but allow
4587 0 : ShowWarningError(state,
4588 : "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
4589 : "CTF timescales are being used.");
4590 0 : ShowContinueError(state,
4591 0 : format("Construction named = {} has CTF timesteps = {}",
4592 0 : state.dataConstruction->Construct(surface.Construction).Name,
4593 0 : state.dataConstruction->Construct(surface.Construction).NumHistories));
4594 0 : ShowContinueError(
4595 : state,
4596 0 : format("While construction named = {} has CTF timesteps = {}",
4597 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4598 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories));
4599 0 : ShowContinueError(
4600 : state,
4601 0 : format("Transient heat transfer modeling may not be valid for surface name = {}, and the simulation continues",
4602 0 : surface.Name));
4603 : }
4604 4 : if (state.dataConstruction->Construct(surface.Construction).NumCTFTerms !=
4605 4 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms) {
4606 : // throw warning, but allow
4607 4 : ShowWarningError(state,
4608 : "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
4609 : "CTF terms are being used.");
4610 4 : ShowContinueError(state,
4611 4 : format("Construction named = {} has number of CTF terms = {}",
4612 2 : state.dataConstruction->Construct(surface.Construction).Name,
4613 2 : state.dataConstruction->Construct(surface.Construction).NumCTFTerms));
4614 4 : ShowContinueError(
4615 : state,
4616 4 : format("While construction named = {} has number of CTF terms = {}",
4617 2 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4618 2 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms));
4619 4 : ShowContinueError(state,
4620 4 : format("The actuator is allowed but the transient heat transfer modeling may not be valid for surface "
4621 : "name = {}, and the simulation continues",
4622 2 : surface.Name));
4623 : }
4624 :
4625 4 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
4626 0 : if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
4627 : // throw warning, and do not allow
4628 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4629 0 : ShowContinueError(state,
4630 0 : format("Construction named = {} has internal source/sink",
4631 0 : state.dataConstruction->Construct(surface.Construction).Name));
4632 0 : ShowContinueError(
4633 : state,
4634 0 : format("While construction named = {} is not an internal source/sink construction",
4635 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
4636 0 : ShowContinueError(
4637 : state,
4638 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4639 0 : surface.Name));
4640 :
4641 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4642 0 : SurfNum) = false;
4643 : }
4644 : }
4645 :
4646 8 : if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4647 : SurfNum)) {
4648 4 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4649 : }
4650 :
4651 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
4652 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4653 : true;
4654 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4655 : true;
4656 0 : if (state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes !=
4657 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).TotNodes) {
4658 : // throw warning, and do not allow
4659 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4660 0 : ShowContinueError(state,
4661 0 : format("Construction named = {} has number of finite difference nodes ={}",
4662 0 : state.dataConstruction->Construct(surface.Construction).Name,
4663 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes));
4664 0 : ShowContinueError(
4665 : state,
4666 0 : format("While construction named = {}has number of finite difference nodes ={}",
4667 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4668 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
4669 0 : .TotNodes));
4670 0 : ShowContinueError(
4671 : state,
4672 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4673 0 : surface.Name));
4674 :
4675 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4676 : false;
4677 : }
4678 :
4679 0 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
4680 0 : if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
4681 : // throw warning, and do not allow
4682 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4683 0 : ShowContinueError(state,
4684 0 : format("Construction named = {} has internal source/sink",
4685 0 : state.dataConstruction->Construct(surface.Construction).Name));
4686 0 : ShowContinueError(
4687 : state,
4688 0 : format("While construction named = {} is not an internal source/sink construction",
4689 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
4690 0 : ShowContinueError(
4691 : state,
4692 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4693 0 : surface.Name));
4694 :
4695 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4696 0 : SurfNum) = false;
4697 : }
4698 : }
4699 :
4700 0 : if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4701 : SurfNum)) {
4702 0 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4703 : }
4704 :
4705 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { // don't allow
4706 0 : ShowSevereError(state,
4707 : "InitEMSControlledConstructions: EMS Construction State Actuator not available with Heat transfer "
4708 : "algorithm CombinedHeatAndMoistureFiniteElement.");
4709 0 : ShowContinueError(
4710 : state,
4711 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4712 0 : surface.Name));
4713 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4714 : true;
4715 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4716 : false;
4717 :
4718 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) { // don't allow
4719 0 : ShowSevereError(state,
4720 : "InitEMSControlledConstructions: EMS Construction State Actuator not available for Surfaces with "
4721 : "Foundation Outside Boundary Condition.");
4722 0 : ShowContinueError(
4723 : state,
4724 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4725 0 : surface.Name));
4726 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4727 : true;
4728 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4729 : false;
4730 : }
4731 :
4732 : } else {
4733 : // do nothing, has been checked and is not okay with single warning already issued.
4734 : }
4735 : }
4736 : } else {
4737 31494 : surface.Construction = surface.ConstructionStoredInputValue;
4738 31494 : state.dataSurface->SurfActiveConstruction(SurfNum) = surface.ConstructionStoredInputValue;
4739 : }
4740 : } // for (SurfNum)
4741 : } // InitEMSControlledConstructions()
4742 :
4743 : // End Initialization Section of the Module
4744 : //******************************************************************************
4745 :
4746 : // Begin Algorithm Section of the Module
4747 : //******************************************************************************
4748 :
4749 : // Beginning of Record Keeping subroutines for the HB Module
4750 : // *****************************************************************************
4751 :
4752 249967 : void UpdateIntermediateSurfaceHeatBalanceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
4753 : {
4754 249967 : int firstZone = 1;
4755 249967 : int lastZone = state.dataGlobal->NumOfZones;
4756 :
4757 249967 : if (present(ZoneToResimulate)) {
4758 8 : firstZone = ZoneToResimulate;
4759 8 : lastZone = ZoneToResimulate;
4760 : }
4761 :
4762 586629 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4763 709651 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4764 372989 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4765 372989 : int const firstSurf = thisSpace.WindowSurfaceFirst;
4766 372989 : int const lastSurf = thisSpace.WindowSurfaceLast;
4767 461551 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4768 88562 : if (state.dataSurface->Surface(surfNum).ExtSolar) { // WindowManager's definition of ZoneWinHeatGain/Loss
4769 88560 : state.dataHeatBal->ZoneWinHeatGain(zoneNum) += state.dataSurface->SurfWinHeatGain(surfNum);
4770 : }
4771 : }
4772 : // Update zone window heat gain reports (these intermediate values are also used for Sensible Heat Gain Summary in GatherHeatGainReport)
4773 372989 : if (state.dataHeatBal->ZoneWinHeatGain(zoneNum) >= 0.0) {
4774 341668 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = state.dataHeatBal->ZoneWinHeatGain(zoneNum);
4775 341668 : state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) =
4776 341668 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
4777 : } else {
4778 31321 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = -state.dataHeatBal->ZoneWinHeatGain(zoneNum);
4779 31321 : state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) =
4780 31321 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
4781 : }
4782 : }
4783 : }
4784 :
4785 249967 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
4786 0 : UpdateNonRepresentativeSurfaceResults(state, ZoneToResimulate);
4787 : }
4788 :
4789 : // Opaque or window surfaces (Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.)
4790 586629 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4791 709651 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4792 372989 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4793 372989 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
4794 372989 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
4795 2447326 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4796 2074337 : state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) =
4797 2074337 : -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
4798 2074337 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
4799 : }
4800 : }
4801 : }
4802 : // Opaque surfaces
4803 586629 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4804 709651 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4805 372989 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4806 372989 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
4807 372989 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
4808 2358768 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4809 1985779 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) =
4810 1985779 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum);
4811 : }
4812 : }
4813 : }
4814 : // Inside face conduction calculation for Kiva surfaces
4815 249968 : for (int surfNum : state.dataSurface->AllHTKivaSurfaceList) {
4816 1 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) =
4817 1 : -(state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
4818 1 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
4819 1 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum));
4820 : }
4821 249967 : }
4822 :
4823 0 : void UpdateNonRepresentativeSurfaceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
4824 : {
4825 0 : int firstZone = 1;
4826 0 : int lastZone = state.dataGlobal->NumOfZones;
4827 :
4828 0 : if (present(ZoneToResimulate)) {
4829 0 : firstZone = ZoneToResimulate;
4830 0 : lastZone = ZoneToResimulate;
4831 : }
4832 :
4833 0 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4834 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4835 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4836 : // Heat transfer surfaces
4837 0 : int firstSurf = thisSpace.HTSurfaceFirst;
4838 0 : int lastSurf = thisSpace.HTSurfaceLast;
4839 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4840 0 : auto const &surface = state.dataSurface->Surface(surfNum);
4841 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
4842 :
4843 0 : if (surfNum != repSurfNum) {
4844 : #if 0
4845 : // Check for divergence
4846 : Real64 surfConv = -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
4847 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
4848 : Real64 repSurfConv = -state.dataHeatBalSurf->SurfHConvInt(repSurfNum) *
4849 : (state.dataHeatBalSurf->SurfTempIn(repSurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum));
4850 : Real64 diff = surfConv - repSurfConv;
4851 : if (std::abs(diff) > 3.0 && state.dataSurface->Surface(repSurfNum).ConstituentSurfaceNums.size() == 2) {
4852 : ShowWarningError(state, format("Difference in representative surface convection {:.3R} W/m2", diff));
4853 : ShowContinueErrorTimeStamp(state, "");
4854 : ShowContinueError(state, format(" Original Surface: {}", surface.Name));
4855 : ShowContinueError(state, format(" Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(surfNum)));
4856 : ShowContinueError(state,
4857 : format(" Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(surfNum)));
4858 : ShowContinueError(state,
4859 : format(" Sunlit fraction: {:.3R}",
4860 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum)));
4861 : ShowContinueError(state, format(" Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum)));
4862 : ShowContinueError(state,
4863 : format(" Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(surfNum)));
4864 : ShowContinueError(state, format(" Representative Surface: {}", state.dataSurface->Surface(repSurfNum).Name));
4865 : ShowContinueError(state, format(" Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(repSurfNum)));
4866 : ShowContinueError(state,
4867 : format(" Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(repSurfNum)));
4868 : ShowContinueError(state,
4869 : format(" Sunlit fraction: {:.3R}",
4870 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, repSurfNum)));
4871 : ShowContinueError(state,
4872 : format(" Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum)));
4873 : ShowContinueError(
4874 : state, format(" Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(repSurfNum)));
4875 : }
4876 : #endif
4877 :
4878 : // Surface Heat Balance Arrays
4879 0 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempIn(repSurfNum);
4880 0 : state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(repSurfNum);
4881 0 : state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBal->SurfTempEffBulkAir(repSurfNum);
4882 0 : state.dataHeatBalSurf->SurfHConvInt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(repSurfNum);
4883 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(repSurfNum);
4884 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(repSurfNum);
4885 0 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(repSurfNum);
4886 :
4887 0 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(repSurfNum);
4888 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvExt(repSurfNum);
4889 0 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(repSurfNum);
4890 0 : state.dataHeatBalSurf->SurfHAirExt(surfNum) = state.dataHeatBalSurf->SurfHAirExt(repSurfNum);
4891 0 : state.dataHeatBalSurf->SurfHSkyExt(surfNum) = state.dataHeatBalSurf->SurfHSkyExt(repSurfNum);
4892 0 : state.dataHeatBalSurf->SurfHGrdExt(surfNum) = state.dataHeatBalSurf->SurfHGrdExt(repSurfNum);
4893 :
4894 0 : state.dataSurface->SurfTAirRef(surfNum) = state.dataSurface->SurfTAirRef(repSurfNum);
4895 0 : if (state.dataSurface->SurfTAirRef(surfNum) != DataSurfaces::RefAirTemp::Invalid) {
4896 0 : state.dataSurface->SurfTAirRefRpt(surfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(surfNum)];
4897 : }
4898 :
4899 0 : state.dataSurface->surfExtConv(surfNum).hfModelEq = state.dataSurface->surfExtConv(repSurfNum).hfModelEq;
4900 0 : state.dataSurface->surfExtConv(surfNum).hnModelEq = state.dataSurface->surfExtConv(repSurfNum).hnModelEq;
4901 :
4902 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
4903 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(repSurfNum);
4904 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) =
4905 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(repSurfNum);
4906 :
4907 : // Internal (non reporting variables)
4908 0 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(repSurfNum);
4909 0 : state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum);
4910 : }
4911 : }
4912 :
4913 : // Opaque surfaces
4914 0 : firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
4915 0 : lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
4916 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4917 0 : auto const &surface = state.dataSurface->Surface(surfNum);
4918 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
4919 :
4920 0 : if (surfNum != repSurfNum) {
4921 : // Surface Heat Balance Arrays
4922 0 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(repSurfNum);
4923 0 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum);
4924 0 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(repSurfNum);
4925 : }
4926 : }
4927 :
4928 : // Window surfaces
4929 0 : firstSurf = thisSpace.WindowSurfaceFirst;
4930 0 : lastSurf = thisSpace.WindowSurfaceLast;
4931 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4932 0 : auto const &surface = state.dataSurface->Surface(surfNum);
4933 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
4934 :
4935 0 : if (surfNum != repSurfNum) {
4936 0 : Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
4937 :
4938 : // Glazing
4939 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
4940 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
4941 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
4942 :
4943 : // Frame
4944 0 : Real64 frameHeatGain = 0.0;
4945 0 : if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
4946 0 : Real64 frameAreaRatio = state.dataSurface->SurfWinFrameArea(surfNum) / state.dataSurface->SurfWinFrameArea(repSurfNum);
4947 0 : state.dataSurface->SurfWinFrameHeatGain(surfNum) = state.dataSurface->SurfWinFrameHeatGain(repSurfNum) * frameAreaRatio;
4948 0 : state.dataSurface->SurfWinFrameHeatLoss(surfNum) = state.dataSurface->SurfWinFrameHeatLoss(repSurfNum) * frameAreaRatio;
4949 0 : state.dataSurface->SurfWinFrameTempIn(surfNum) = state.dataSurface->SurfWinFrameTempIn(repSurfNum);
4950 0 : state.dataSurface->SurfWinFrameTempSurfOut(surfNum) = state.dataSurface->SurfWinFrameTempSurfOut(repSurfNum);
4951 0 : frameHeatGain = state.dataSurface->SurfWinFrameHeatGain(surfNum) - state.dataSurface->SurfWinFrameHeatLoss(surfNum);
4952 : }
4953 :
4954 : // Divider
4955 0 : Real64 dividerHeatGain = 0.0;
4956 0 : if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
4957 0 : Real64 dividerAreaRatio = state.dataSurface->SurfWinDividerArea(surfNum) / state.dataSurface->SurfWinDividerArea(repSurfNum);
4958 0 : state.dataSurface->SurfWinDividerHeatGain(surfNum) = state.dataSurface->SurfWinDividerHeatGain(repSurfNum) * dividerAreaRatio;
4959 0 : state.dataSurface->SurfWinDividerHeatLoss(surfNum) = state.dataSurface->SurfWinDividerHeatLoss(repSurfNum) * dividerAreaRatio;
4960 0 : state.dataSurface->SurfWinDividerTempIn(surfNum) = state.dataSurface->SurfWinDividerTempIn(repSurfNum);
4961 0 : state.dataSurface->SurfWinDividerTempSurfOut(surfNum) = state.dataSurface->SurfWinDividerTempSurfOut(repSurfNum);
4962 0 : dividerHeatGain = state.dataSurface->SurfWinDividerHeatGain(surfNum) - state.dataSurface->SurfWinDividerHeatLoss(surfNum);
4963 : }
4964 :
4965 0 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = frameHeatGain + dividerHeatGain;
4966 :
4967 : // Whole window
4968 0 : state.dataSurface->SurfWinHeatGain(surfNum) = (state.dataSurface->SurfWinHeatGain(repSurfNum) -
4969 0 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(repSurfNum) * areaRatio) +
4970 0 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum);
4971 : }
4972 : }
4973 : }
4974 : }
4975 0 : }
4976 :
4977 249945 : void UpdateFinalSurfaceHeatBalance(EnergyPlusData &state)
4978 : {
4979 :
4980 : // SUBROUTINE INFORMATION:
4981 : // AUTHOR Rick Strand
4982 : // DATE WRITTEN December 2000
4983 :
4984 : // PURPOSE OF THIS SUBROUTINE:
4985 : // If a radiant system is present and was on for part of the time step,
4986 : // then we probably need to make yet another pass through the heat balance.
4987 : // This is necessary because the heat source/sink to the surface that is
4988 : // the radiant system may have varied during the system time steps.
4989 :
4990 : // METHODOLOGY EMPLOYED:
4991 : // First, determine whether or not the radiant system was running. If
4992 : // any of the Qsource terms are non-zero, then it was running. Then,
4993 : // update the current source terms with the "average" value calculated
4994 : // by the radiant system algorithm. This requires the "USE" of the
4995 : // radiant algorithm module. Finally, using this source value, redo
4996 : // the inside and outside heat balances.
4997 :
4998 : bool LowTempRadSysOn; // .TRUE. if a low temperature radiant system is running
4999 : bool HighTempRadSysOn; // .TRUE. if a high temperature radiant system is running
5000 : bool HWBaseboardSysOn; // .TRUE. if a water baseboard heater is running
5001 : bool SteamBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
5002 : bool ElecBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
5003 : bool CoolingPanelSysOn; // true if a simple cooling panel is running
5004 : bool SwimmingPoolOn; // true if a pool is present (running)
5005 :
5006 249945 : LowTempRadiantSystem::UpdateRadSysSourceValAvg(state, LowTempRadSysOn);
5007 249945 : HighTempRadiantSystem::UpdateHTRadSourceValAvg(state, HighTempRadSysOn);
5008 249945 : HWBaseboardRadiator::UpdateBBRadSourceValAvg(state, HWBaseboardSysOn);
5009 249945 : SteamBaseboardRadiator::UpdateBBSteamRadSourceValAvg(state, SteamBaseboardSysOn);
5010 249945 : ElectricBaseboardRadiator::UpdateBBElecRadSourceValAvg(state, ElecBaseboardSysOn);
5011 249945 : CoolingPanelSimple::UpdateCoolingPanelSourceValAvg(state, CoolingPanelSysOn);
5012 249945 : SwimmingPool::UpdatePoolSourceValAvg(state, SwimmingPoolOn);
5013 :
5014 249945 : if (LowTempRadSysOn || HighTempRadSysOn || HWBaseboardSysOn || SteamBaseboardSysOn || ElecBaseboardSysOn || CoolingPanelSysOn || SwimmingPoolOn) {
5015 : // Solve the zone heat balance 'Detailed' solution
5016 : // Call the outside and inside surface heat balances
5017 4 : CalcHeatBalanceOutsideSurf(state);
5018 4 : CalcHeatBalanceInsideSurf(state);
5019 : }
5020 249945 : }
5021 :
5022 200977 : void UpdateThermalHistories(EnergyPlusData &state)
5023 : {
5024 :
5025 : // SUBROUTINE INFORMATION:
5026 : // AUTHOR Russ Taylor
5027 : // DATE WRITTEN June 1990
5028 : // RE-ENGINEERED Mar98 (RKS)
5029 :
5030 : // PURPOSE OF THIS SUBROUTINE:
5031 : // This subroutine updates and shifts the thermal and flux histories.
5032 :
5033 : // METHODOLOGY EMPLOYED:
5034 : // If a surface runs on the user selected subhourly time step, then the
5035 : // history terms for the temperatures and fluxes must simply be updated
5036 : // and shifted. However, if the surface runs at a different (longer) time
5037 : // step, then the "master" history series is used for the interpolated
5038 : // update scheme.
5039 :
5040 : // REFERENCES:
5041 : // (I)BLAST legacy routine UTHRMH
5042 : // Taylor et.al., Impact of Simultaneous Simulation of Buildings and
5043 : // Mechanical Systems in Heat Balance Based Energy Analysis Programs
5044 : // on System Response and Control, Building Simulation '91, IBPSA, Nice, France.
5045 :
5046 200977 : if (state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag) {
5047 103 : state.dataHeatBalSurfMgr->QExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5048 103 : state.dataHeatBalSurfMgr->QInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5049 103 : state.dataHeatBalSurfMgr->TempInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5050 103 : state.dataHeatBalSurfMgr->TempExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5051 103 : state.dataHeatBalSurfMgr->SumTime.dimension(state.dataSurface->TotSurfaces, 0.0);
5052 103 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5053 1 : state.dataHeatBalSurfMgr->Qsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
5054 1 : state.dataHeatBalSurfMgr->Tsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
5055 1 : state.dataHeatBalSurfMgr->Tuser1.dimension(state.dataSurface->TotSurfaces, 0.0);
5056 : }
5057 103 : state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag = false;
5058 : }
5059 :
5060 488650 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5061 611649 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5062 323976 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5063 323976 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5064 323976 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5065 2015835 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5066 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5067 1691859 : auto const &surface = state.dataSurface->Surface(SurfNum);
5068 :
5069 1691859 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5070 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
5071 0 : continue;
5072 :
5073 1691859 : int const ConstrNum = surface.Construction;
5074 1691859 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5075 :
5076 1691859 : if (construct.NumCTFTerms == 0) continue; // Skip surfaces with no history terms
5077 :
5078 : // Sign convention for the various terms in the following two equations
5079 : // is based on the form of the Conduction Transfer Function equation
5080 : // given by:
5081 : // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + (Sum of)(V Qsrc)
5082 : // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + (Sum of)(W Qsrc)
5083 : // In both equations, flux is positive from outside to inside. The V and W terms are for radiant systems only.
5084 :
5085 : // Set current inside flux:
5086 1691859 : Real64 const SurfOutsideTempCurr = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
5087 1691859 : Real64 SurfInsideFluxHistCurr = SurfOutsideTempCurr * construct.CTFCross[0] -
5088 1691859 : state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFInside[0] +
5089 1691859 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum); // Heat source/sink term for radiant systems
5090 : // Only HT opaq surfaces are evaluated, previous if (surface.Class == SurfaceClass::Floor || surface.Class == SurfaceClass::Wall ||
5091 : // surface.Class == SurfaceClass::IntMass || surface.Class == SurfaceClass::Roof || surface.Class == SurfaceClass::Door) checks are
5092 : // redundant.
5093 1691859 : if (construct.SourceSinkPresent) {
5094 2 : SurfInsideFluxHistCurr += state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceIn[0];
5095 : }
5096 1691859 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr;
5097 1691859 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting
5098 1691859 : state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr;
5099 :
5100 : // Update the temperature at the source/sink location (if one is present)
5101 1691859 : if (construct.SourceSinkPresent) {
5102 2 : state.dataHeatBalSurf->SurfTempSource(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1) =
5103 2 : SurfOutsideTempCurr * construct.CTFTSourceOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTSourceIn[0] +
5104 2 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTSourceQ[0] +
5105 2 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
5106 2 : state.dataHeatBalSurf->SurfTempUserLoc(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1) =
5107 2 : SurfOutsideTempCurr * construct.CTFTUserOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTUserIn[0] +
5108 2 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTUserSource[0] +
5109 2 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum);
5110 : }
5111 :
5112 : // Set current outside flux:
5113 1691859 : if (construct.SourceSinkPresent) {
5114 2 : state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) =
5115 2 : SurfOutsideTempCurr * construct.CTFOutside[0] - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
5116 2 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceOut[0] +
5117 2 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); // Heat source/sink term for radiant systems
5118 : } else {
5119 3383714 : state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = SurfOutsideTempCurr * construct.CTFOutside[0] -
5120 1691857 : state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
5121 1691857 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum);
5122 : }
5123 : // switch sign for balance at outside face
5124 1691859 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = -state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
5125 1691859 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(SurfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum);
5126 : }
5127 : }
5128 : } // ...end of loop over all (heat transfer) surfaces...
5129 :
5130 200977 : if (state.dataHeatBal->SimpleCTFOnly && !state.dataGlobal->AnyConstrOverridesInModel) {
5131 : // Temporarily save the rvalue references of the last term arrays
5132 193863 : Array1D<Real64> insideTemp(std::move(state.dataHeatBalSurf->SurfInsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
5133 193863 : Array1D<Real64> outsideTemp(std::move(state.dataHeatBalSurf->SurfOutsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
5134 193863 : Array1D<Real64> insideFlux(std::move(state.dataHeatBalSurf->SurfInsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
5135 193863 : Array1D<Real64> outsideFlux(std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
5136 : // Shifting its internal pointer to data to the new object; Using the (Array1D && a) overload of the "=" operator
5137 1325627 : for (int HistTermNum = state.dataHeatBal->MaxCTFTerms + 1; HistTermNum >= 3; --HistTermNum) {
5138 1131764 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum - 1));
5139 1131764 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum - 1));
5140 1131764 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum - 1));
5141 1131764 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum - 1));
5142 : }
5143 : // Reuse the pointers of the last term arrays for the second term arrays
5144 193863 : state.dataHeatBalSurf->SurfInsideTempHist(2) = std::move(insideTemp);
5145 193863 : state.dataHeatBalSurf->SurfOutsideTempHist(2) = std::move(outsideTemp);
5146 193863 : state.dataHeatBalSurf->SurfInsideFluxHist(2) = std::move(insideFlux);
5147 193863 : state.dataHeatBalSurf->SurfOutsideFluxHist(2) = std::move(outsideFlux);
5148 : // 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)
5149 193863 : state.dataHeatBalSurf->SurfInsideTempHist(2) = state.dataHeatBalSurf->SurfInsideTempHist(1);
5150 193863 : state.dataHeatBalSurf->SurfOutsideTempHist(2) = state.dataHeatBalSurf->SurfOutsideTempHist(1);
5151 193863 : state.dataHeatBalSurf->SurfInsideFluxHist(2) = state.dataHeatBalSurf->SurfInsideFluxHist(1);
5152 193863 : state.dataHeatBalSurf->SurfOutsideFluxHist(2) = state.dataHeatBalSurf->SurfOutsideFluxHist(1);
5153 193863 : return;
5154 193863 : }
5155 :
5156 14230 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5157 14232 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5158 7116 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5159 7116 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5160 7116 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5161 44374 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5162 37258 : auto const &surface = state.dataSurface->Surface(SurfNum);
5163 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5164 37258 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5165 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
5166 0 : continue;
5167 37258 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5168 37258 : state.dataHeatBalSurfMgr->TempExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
5169 37258 : state.dataHeatBalSurfMgr->TempInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
5170 37258 : state.dataHeatBalSurfMgr->QExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
5171 37258 : state.dataHeatBalSurfMgr->QInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum);
5172 : }
5173 : }
5174 : }
5175 :
5176 : } // ...end of loop over all (heat transfer) surfaces...
5177 7114 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5178 4 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5179 4 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5180 2 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5181 2 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5182 2 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5183 4 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5184 2 : auto const &surface = state.dataSurface->Surface(SurfNum);
5185 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5186 2 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5187 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
5188 0 : continue;
5189 2 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5190 2 : state.dataHeatBalSurfMgr->Tsrc1(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1);
5191 2 : state.dataHeatBalSurfMgr->Tuser1(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1);
5192 2 : state.dataHeatBalSurfMgr->Qsrc1(SurfNum) = state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1);
5193 : }
5194 : }
5195 : }
5196 : } // ...end of loop over all (heat transfer) surfaces...
5197 : }
5198 :
5199 : // SHIFT TEMPERATURE AND FLUX HISTORIES:
5200 : // SHIFT AIR TEMP AND FLUX SHIFT VALUES WHEN AT BOTTOM OF ARRAY SPACE.
5201 14230 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5202 14232 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5203 7116 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5204 7116 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5205 7116 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5206 44374 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5207 37258 : auto const &surface = state.dataSurface->Surface(SurfNum);
5208 :
5209 37258 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5210 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
5211 0 : continue;
5212 :
5213 37258 : int const ConstrNum = surface.Construction;
5214 37258 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5215 :
5216 37258 : ++state.dataHeatBalSurf->SurfCurrNumHist(SurfNum);
5217 37258 : state.dataHeatBalSurfMgr->SumTime(SurfNum) = double(state.dataHeatBalSurf->SurfCurrNumHist(SurfNum)) * state.dataGlobal->TimeStepZone;
5218 :
5219 37258 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == construct.NumHistories) {
5220 37258 : state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
5221 :
5222 37258 : if (construct.NumCTFTerms > 1) {
5223 7126 : int const numCTFTerms(construct.NumCTFTerms);
5224 35612 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
5225 28486 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum) =
5226 28486 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
5227 28486 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum) =
5228 28486 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
5229 28486 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum) =
5230 28486 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5231 28486 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum) =
5232 28486 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5233 28486 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) =
5234 28486 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
5235 28486 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) =
5236 28486 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
5237 28486 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) =
5238 28486 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5239 28486 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) =
5240 28486 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5241 : }
5242 : }
5243 :
5244 37258 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempExt1(SurfNum);
5245 37258 : state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempInt1(SurfNum);
5246 37258 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QExt1(SurfNum);
5247 37258 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QInt1(SurfNum);
5248 :
5249 37258 : state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum);
5250 37258 : state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum);
5251 37258 : state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum);
5252 37258 : state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum);
5253 : } else {
5254 0 : Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
5255 0 : if (construct.NumCTFTerms > 1) {
5256 0 : int const numCTFTerms(construct.NumCTFTerms);
5257 0 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
5258 : // TH(SideNum, TermNum, SurfNum) = (THM(SideNum, TermNum, SurfNum) -
5259 : // (THM(SideNum, TermNum, SurfNum) - THM(SideNum, TermNum - 1, SurfNum)) * sum_steps;
5260 0 : Real64 const THM_Out_1(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum));
5261 0 : Real64 const THM_In_1(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum));
5262 0 : Real64 const THM_Out_2(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum));
5263 0 : Real64 const THM_In_2(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum));
5264 0 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = THM_Out_1 - (THM_Out_1 - THM_Out_2) * sum_steps;
5265 0 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = THM_In_1 - (THM_In_1 - THM_In_2) * sum_steps;
5266 :
5267 0 : Real64 const QHM_Out_1(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum));
5268 0 : Real64 const QHM_In_1(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum));
5269 0 : Real64 const QHM_Out_2(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum));
5270 0 : Real64 const QHM_In_2(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum));
5271 0 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = QHM_Out_1 - (QHM_Out_1 - QHM_Out_2) * sum_steps;
5272 0 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = QHM_In_1 - (QHM_In_1 - QHM_In_2) * sum_steps;
5273 : }
5274 : }
5275 : // TH( 1, 2, SurfNum ) = THM( 1, 2, SurfNum ) - ( THM( 1, 2, SurfNum ) - TempExt1( SurfNum ) ) * sum_steps;
5276 0 : state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) =
5277 0 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) -
5278 0 : (state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempExt1(SurfNum)) * sum_steps;
5279 0 : state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) =
5280 0 : state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) -
5281 0 : (state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempInt1(SurfNum)) * sum_steps;
5282 0 : state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) =
5283 0 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) -
5284 0 : (state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QExt1(SurfNum)) * sum_steps;
5285 0 : state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) =
5286 0 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) -
5287 0 : (state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QInt1(SurfNum)) * sum_steps;
5288 : }
5289 : }
5290 : }
5291 : } // ...end of loop over all (heat transfer) surfaces
5292 :
5293 7114 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5294 4 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5295 4 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5296 2 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5297 2 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5298 2 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5299 4 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5300 2 : auto const &surface = state.dataSurface->Surface(SurfNum);
5301 2 : int const ConstrNum = surface.Construction;
5302 2 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5303 2 : if (!construct.SourceSinkPresent) continue;
5304 2 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5305 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
5306 0 : continue;
5307 :
5308 2 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5309 2 : if (construct.NumCTFTerms > 1) {
5310 2 : int const numCTFTerms = construct.NumCTFTerms;
5311 2 : int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
5312 2 : int m1 = m + 1;
5313 4 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing
5314 : // SurfTsrcHist( SurfNum, HistTerm ) = SurfTsrcHistM( SurfNum, HHistTerm ) = SurfTsrcHistM( SurfNum, HistTermNum - 1
5315 : // ); SurfQsrcHist( SurfNum, HistTerm ) = SurfQsrcHistM( SurfNum, HHistTerm ) = SurfQsrcHistM( SurfNum, HistTermNum -
5316 : // 1 );
5317 2 : state.dataHeatBalSurf->SurfTsrcHist[m1] = state.dataHeatBalSurf->SurfTsrcHistM[m1] =
5318 2 : state.dataHeatBalSurf->SurfTsrcHistM[m];
5319 2 : state.dataHeatBalSurf->SurfQsrcHist[m1] = state.dataHeatBalSurf->SurfQsrcHistM[m1] =
5320 2 : state.dataHeatBalSurf->SurfQsrcHistM[m];
5321 2 : state.dataHeatBalSurf->SurfTuserHist[m1] = state.dataHeatBalSurf->SurfTuserHistM[m1] =
5322 2 : state.dataHeatBalSurf->SurfTuserHistM[m];
5323 : }
5324 : }
5325 2 : state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tsrc1(SurfNum);
5326 2 : state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tuser1(SurfNum);
5327 2 : state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Qsrc1(SurfNum);
5328 2 : state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2);
5329 2 : state.dataHeatBalSurf->SurfTuserHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2);
5330 2 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2);
5331 : } else {
5332 0 : Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
5333 :
5334 0 : if (construct.NumCTFTerms > 1) {
5335 0 : int const numCTFTerms = construct.NumCTFTerms;
5336 0 : int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
5337 0 : int m1 = m + 1;
5338 0 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing [ l ] == ()
5339 : // Real64 const SurfTsrcHistM_elem( SurfTsrcHistM( SurfNum, HistTermNum ) );
5340 : // SurfTsrcHist( SurfNum, HistTermNum ) = SurfTsrcHistM_elem - ( SurfTsrcHistM_elem - SurfTsrcHistM( SurfNum,
5341 : // HistTermNum
5342 : // - 1 ) ) * sum_steps; Real64 const QsrcHistM_elem( SurfQsrcHistM( SurfNum, HistTermNum ) ); SurfQsrcHist( SurfNum,
5343 : // HistTermNum ) = QsrcHistM_elem - ( QsrcHistM_elem - SurfQsrcHistM( SurfNum, HistTermNum - 1 ) ) * sum_steps;
5344 0 : Real64 const TsrcHistM_m1(state.dataHeatBalSurf->SurfTsrcHistM[m1]);
5345 0 : state.dataHeatBalSurf->SurfTsrcHist[m1] =
5346 0 : TsrcHistM_m1 - (TsrcHistM_m1 - state.dataHeatBalSurf->SurfTsrcHistM[m]) * sum_steps;
5347 0 : Real64 const QsrcHistM_m1(state.dataHeatBalSurf->SurfQsrcHistM[m1]);
5348 0 : state.dataHeatBalSurf->SurfQsrcHist[m1] =
5349 0 : QsrcHistM_m1 - (QsrcHistM_m1 - state.dataHeatBalSurf->SurfQsrcHistM[m]) * sum_steps;
5350 0 : Real64 const TuserHistM_m1(state.dataHeatBalSurf->SurfTuserHistM[m1]);
5351 0 : state.dataHeatBalSurf->SurfTuserHist[m1] =
5352 0 : TuserHistM_m1 - (TuserHistM_m1 - state.dataHeatBalSurf->SurfTuserHistM[m]) * sum_steps;
5353 : }
5354 : }
5355 : // Tuned Linear indexing
5356 : // SurfTsrcHist( SurfNum, 2 ) = SurfTsrcHistM( SurfNum, 2 ) - ( SurfTsrcHistM( SurfNum, 2 ) - Tsrc1( SurfNum ) ) * sum_steps;
5357 : // SurfQsrcHist( SurfNum, 2 ) = SurfQsrcHistM( SurfNum, 2 ) - ( SurfQsrcHistM( SurfNum, 2 ) - Qsrc1( SurfNum ) ) * sum_steps;
5358 0 : int const l2 = state.dataHeatBalSurf->SurfTsrcHist.index(SurfNum, 2);
5359 0 : state.dataHeatBalSurf->SurfTsrcHist[l2] =
5360 0 : state.dataHeatBalSurf->SurfTsrcHistM[l2] -
5361 0 : (state.dataHeatBalSurf->SurfTsrcHistM[l2] - state.dataHeatBalSurfMgr->Tsrc1(SurfNum)) * sum_steps;
5362 0 : state.dataHeatBalSurf->SurfQsrcHist[l2] =
5363 0 : state.dataHeatBalSurf->SurfQsrcHistM[l2] -
5364 0 : (state.dataHeatBalSurf->SurfQsrcHistM[l2] - state.dataHeatBalSurfMgr->Qsrc1(SurfNum)) * sum_steps;
5365 0 : state.dataHeatBalSurf->SurfTuserHist[l2] =
5366 0 : state.dataHeatBalSurf->SurfTuserHistM[l2] -
5367 0 : (state.dataHeatBalSurf->SurfTuserHistM[l2] - state.dataHeatBalSurfMgr->Tuser1(SurfNum)) * sum_steps;
5368 : }
5369 : }
5370 : }
5371 : } // ...end of loop over all (heat transfer) surfaces...
5372 : } // ...end of AnyInternalHeatSourceInInput
5373 : }
5374 :
5375 249966 : void CalculateZoneMRT(EnergyPlusData &state,
5376 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
5377 : {
5378 :
5379 : // SUBROUTINE INFORMATION:
5380 : // AUTHOR Rick Strand
5381 : // DATE WRITTEN November 2000
5382 :
5383 : // PURPOSE OF THIS SUBROUTINE:
5384 : // Calculates the current zone and enclosure MRT for thermal comfort and radiation
5385 : // calculation purposes.
5386 :
5387 249966 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5388 109 : state.dataHeatBalSurfMgr->SurfaceAE.allocate(state.dataSurface->TotSurfaces);
5389 109 : state.dataHeatBalSurfMgr->ZoneAESum.allocate(state.dataGlobal->NumOfZones);
5390 109 : state.dataHeatBalSurfMgr->SurfaceAE = 0.0;
5391 109 : state.dataHeatBalSurfMgr->ZoneAESum = 0.0;
5392 250 : for (auto &encl : state.dataViewFactor->EnclRadInfo) {
5393 141 : encl.sumAE = 0.0;
5394 : }
5395 904 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
5396 795 : auto const &surface = state.dataSurface->Surface(SurfNum);
5397 795 : if (surface.HeatTransSurf) {
5398 779 : auto &thisSurfAE = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum);
5399 779 : thisSurfAE = surface.Area * state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal;
5400 779 : int ZoneNum = surface.Zone;
5401 779 : if (ZoneNum > 0) state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) += thisSurfAE;
5402 779 : if (surface.RadEnclIndex > 0) state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).sumAE += thisSurfAE;
5403 : }
5404 : }
5405 : }
5406 :
5407 : // Zero sumAET for applicable enclosures
5408 249966 : if (present(ZoneToResimulate)) {
5409 32 : for (int spaceNum : state.dataHeatBal->Zone(ZoneToResimulate).spaceIndexes) {
5410 24 : int enclNum = state.dataHeatBal->space(spaceNum).radiantEnclosureNum;
5411 24 : state.dataViewFactor->EnclRadInfo(enclNum).sumAET = 0.0;
5412 24 : state.dataViewFactor->EnclRadInfo(enclNum).reCalcMRT = true;
5413 : }
5414 : } else {
5415 605542 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
5416 355584 : thisEnclosure.reCalcMRT = true;
5417 : }
5418 : }
5419 586633 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5420 336667 : if (present(ZoneToResimulate) && (ZoneNum != ZoneToResimulate)) continue;
5421 336667 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
5422 336667 : if (state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) > 0.01) {
5423 336664 : Real64 zoneSumAET = 0.0;
5424 709655 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
5425 372991 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5426 2447340 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
5427 2074349 : Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) * state.dataHeatBalSurf->SurfTempIn(SurfNum);
5428 2074349 : zoneSumAET += surfAET;
5429 2074349 : state.dataViewFactor->EnclRadInfo(state.dataSurface->Surface(SurfNum).RadEnclIndex).sumAET += surfAET;
5430 : }
5431 : }
5432 336664 : thisZoneHB.MRT = zoneSumAET / state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum);
5433 : } else {
5434 3 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5435 6 : ShowWarningError(
5436 : state,
5437 6 : format("Zone areas*inside surface emissivities are summing to zero, for Zone=\"{}\"", state.dataHeatBal->Zone(ZoneNum).Name));
5438 9 : ShowContinueError(state, "As a result, MRT will be set to MAT for that zone");
5439 : }
5440 3 : thisZoneHB.MRT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
5441 : }
5442 : }
5443 : // Calculate MRT for applicable enclosures
5444 605566 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
5445 355600 : if (!thisEnclosure.reCalcMRT) continue;
5446 355600 : if (thisEnclosure.sumAE > 0.01) {
5447 355598 : thisEnclosure.sumAET = 0.0;
5448 2429919 : for (int surfNum : thisEnclosure.SurfacePtr) {
5449 2074321 : Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum);
5450 2074321 : thisEnclosure.sumAET += surfAET;
5451 : }
5452 355598 : thisEnclosure.MRT = thisEnclosure.sumAET / thisEnclosure.sumAE;
5453 : } else {
5454 2 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5455 4 : ShowWarningError(state,
5456 4 : format("Enclosure areas*inside surface emissivities are summing to zero, for Enclosure=\"{}\"", thisEnclosure.Name));
5457 6 : ShowContinueError(state, "As a result, MRT will be set to the volume weighted average MAT for that enclosure");
5458 : }
5459 2 : Real64 sumMATVol = 0.0;
5460 2 : Real64 sumVol = 0.0;
5461 2 : Real64 sumMAT = 0.0;
5462 5 : for (auto &spaceNum : thisEnclosure.spaceNums) {
5463 3 : Real64 spaceVolume = state.dataHeatBal->space(spaceNum).Volume;
5464 3 : Real64 spaceMAT = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT;
5465 3 : sumVol += spaceVolume;
5466 3 : sumMATVol += spaceMAT * spaceVolume;
5467 3 : sumMAT += spaceMAT;
5468 : }
5469 2 : if (sumVol > 0.01) {
5470 2 : thisEnclosure.MRT = sumMATVol / sumVol;
5471 : } else {
5472 0 : thisEnclosure.MRT = sumMAT / (int)thisEnclosure.spaceNums.size();
5473 : }
5474 : }
5475 : // Set space MRTs
5476 728594 : for (int spaceNum : thisEnclosure.spaceNums) {
5477 372994 : state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MRT = thisEnclosure.MRT;
5478 : }
5479 : }
5480 :
5481 249966 : state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime = false;
5482 249966 : }
5483 :
5484 : // End of Record Keeping subroutines for the HB Module
5485 : // *****************************************************************************
5486 :
5487 : // Beginning of Reporting subroutines for the HB Module
5488 : // *****************************************************************************
5489 :
5490 249953 : void CalcThermalResilience(EnergyPlusData &state)
5491 : {
5492 : // This function calculate timestep-wise heat index and humidex.
5493 :
5494 : // The computation of the heat index is a refinement of a result obtained by multiple regression analysis
5495 : // carried out by Lans P. Rothfusz and described in a 1990 National Weather Service (NWS)
5496 : // Technical Attachment (SR 90-23).
5497 : // Reference: https://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
5498 :
5499 : // The current formula for determining the humidex was developed by J. M. Masterton and F. A. Richardson of
5500 : // Canada's Atmospheric Environment Service in 1979.
5501 : // Reference: Masterson, J., and F. Richardson, 1979: Humidex, a method of quantifying human
5502 : // discomfort due to excessive heat and humidity CLI 1-79, Environment Canada, Atmospheric Environment Service
5503 : // using OutputProcessor::ReqRepVars;
5504 249953 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
5505 242 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5506 262 : SetupOutputVariable(state,
5507 : "Zone Heat Index",
5508 : Constant::Units::C,
5509 131 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex,
5510 : OutputProcessor::TimeStepType::Zone,
5511 : OutputProcessor::StoreType::Average,
5512 131 : state.dataHeatBal->Zone(ZoneNum).Name);
5513 262 : SetupOutputVariable(state,
5514 : "Zone Humidity Index",
5515 : Constant::Units::None,
5516 131 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex,
5517 : OutputProcessor::TimeStepType::Zone,
5518 : OutputProcessor::StoreType::Average,
5519 131 : state.dataHeatBal->Zone(ZoneNum).Name);
5520 : }
5521 580 : for (auto const *reqVar : state.dataOutputProcessor->reqVars) {
5522 469 : if (reqVar->name == "Zone Heat Index") {
5523 0 : state.dataHeatBalSurfMgr->reportVarHeatIndex = true;
5524 469 : } else if (reqVar->name == "Zone Humidity Index") {
5525 0 : state.dataHeatBalSurfMgr->reportVarHumidex = true;
5526 : }
5527 : }
5528 : }
5529 :
5530 : // Calculate Heat Index and Humidex.
5531 : // The heat index equation set is fit to Fahrenheit units, so the zone air temperature values are first convert to F,
5532 : // then heat index is calculated and converted back to C.
5533 249953 : if (state.dataHeatBalSurfMgr->reportVarHeatIndex || state.dataOutRptTab->displayThermalResilienceSummary) {
5534 145262 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5535 75319 : Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5536 75319 : Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
5537 75319 : Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress) * 100.0;
5538 75319 : Real64 const ZoneTF = ZoneT * (9.0 / 5.0) + 32.0;
5539 75319 : if (state.dataHeatBal->heatIndexMethod == DataHeatBalance::HeatIndexMethod::Simplified) {
5540 75319 : Real64 constexpr c1 = -42.379;
5541 75319 : Real64 constexpr c2 = 2.04901523;
5542 75319 : Real64 constexpr c3 = 10.14333127;
5543 75319 : Real64 constexpr c4 = -.22475541;
5544 75319 : Real64 constexpr c5 = -.00683783;
5545 75319 : Real64 constexpr c6 = -.05481717;
5546 75319 : Real64 constexpr c7 = .00122874;
5547 75319 : Real64 constexpr c8 = .00085282;
5548 75319 : Real64 constexpr c9 = -.00000199;
5549 : Real64 HI;
5550 :
5551 75319 : if (ZoneTF < 80) {
5552 40740 : HI = 0.5 * (ZoneTF + 61.0 + (ZoneTF - 68.0) * 1.2 + (ZoneRH * 0.094));
5553 : } else {
5554 34579 : HI = c1 + c2 * ZoneTF + c3 * ZoneRH + c4 * ZoneTF * ZoneRH + c5 * ZoneTF * ZoneTF + c6 * ZoneRH * ZoneRH +
5555 34579 : c7 * ZoneTF * ZoneTF * ZoneRH + c8 * ZoneTF * ZoneRH * ZoneRH + c9 * ZoneTF * ZoneTF * ZoneRH * ZoneRH;
5556 34579 : if (ZoneRH < 13 && ZoneTF < 112) {
5557 450 : HI -= (13 - ZoneRH) / 4 * std::sqrt((17 - abs(ZoneTF - 95)) / 17);
5558 34129 : } else if (ZoneRH > 85 && ZoneTF < 87) {
5559 86 : HI += (ZoneRH - 85) / 10 * (87 - ZoneTF) / 5;
5560 : }
5561 : }
5562 75319 : HI = (HI - 32.0) * (5.0 / 9.0);
5563 75319 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex = HI;
5564 : } else {
5565 : // calculate extended heat index
5566 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex =
5567 0 : ExtendedHI::heatindex(state, ZoneT + Constant::Kelvin, ZoneRH / 100.0) - Constant::Kelvin;
5568 : }
5569 : }
5570 : }
5571 249953 : if (state.dataHeatBalSurfMgr->reportVarHumidex || state.dataOutRptTab->displayThermalResilienceSummary) {
5572 145262 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5573 75319 : Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
5574 75319 : Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5575 75319 : Real64 const TDewPointK = Psychrometrics::PsyTdpFnWPb(state, ZoneW, state.dataEnvrn->OutBaroPress) + Constant::Kelvin;
5576 75319 : Real64 const e = 6.11 * std::exp(5417.7530 * ((1 / 273.16) - (1 / TDewPointK)));
5577 75319 : Real64 const h = 5.0 / 9.0 * (e - 10.0);
5578 75319 : Real64 const Humidex = ZoneT + h;
5579 75319 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex = Humidex;
5580 : }
5581 : }
5582 249953 : }
5583 :
5584 69975 : void ReportThermalResilience(EnergyPlusData &state)
5585 : {
5586 :
5587 69975 : Array1D_bool reportPeriodFlags;
5588 69975 : if (state.dataWeather->TotReportPers > 0) {
5589 20 : reportPeriodFlags.dimension(state.dataWeather->TotThermalReportPers, false);
5590 20 : General::findReportPeriodIdx(state, state.dataWeather->ThermalReportPeriodInput, state.dataWeather->TotThermalReportPers, reportPeriodFlags);
5591 : }
5592 :
5593 69975 : auto &ort = state.dataOutRptTab;
5594 70015 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5595 40 : if (reportPeriodFlags(i)) {
5596 18 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
5597 18 : state.dataWeather->ThermalReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
5598 : }
5599 : }
5600 :
5601 69975 : if (state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime) {
5602 40 : int constexpr HINoBins = 5; // Heat Index range - number of bins
5603 40 : int constexpr HumidexNoBins = 5; // Humidex range - number of bins
5604 40 : int constexpr SETNoBins = 5; // SET report column numbers
5605 40 : int constexpr ColdHourOfSafetyNoBins = 5; // Cold Stress Hour of Safety number of columns
5606 40 : int constexpr HeatHourOfSafetyNoBins = 5; // Heat Stress Hour of Safety number of columns
5607 40 : int constexpr UnmetDegreeHourNoBins = 6; // Unmet Degree Hour number of columns
5608 40 : int constexpr DiscomfortWtExceedHourNoBins = 4; // Unmet Degree Hour number of columns
5609 :
5610 40 : if (state.dataHeatBal->TotPeople == 0) state.dataHeatBalSurfMgr->hasPierceSET = false;
5611 54 : for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
5612 14 : if (!state.dataHeatBal->People(iPeople).Pierce) {
5613 12 : state.dataHeatBalSurfMgr->hasPierceSET = false;
5614 : }
5615 : }
5616 86 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5617 : // the whole period
5618 : // user specified reporting period
5619 48 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5620 2 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5621 2 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5622 2 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5623 2 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5624 2 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5625 2 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5626 2 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
5627 2 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
5628 2 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
5629 : }
5630 2 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(ColdHourOfSafetyNoBins, 0.0);
5631 2 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(HeatHourOfSafetyNoBins, 0.0);
5632 2 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, i).assign(UnmetDegreeHourNoBins, 0.0);
5633 2 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
5634 2 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
5635 : }
5636 46 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod = 0.0;
5637 46 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod = 0.0;
5638 46 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod = 0.0;
5639 46 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod = 0.0;
5640 : }
5641 40 : state.dataHeatBalSurfMgr->lowSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
5642 40 : state.dataHeatBalSurfMgr->highSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
5643 40 : state.dataHeatBalSurfMgr->lowSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
5644 40 : state.dataHeatBalSurfMgr->highSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
5645 40 : state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime = false;
5646 : }
5647 :
5648 : // Count hours only during weather simulation periods
5649 69975 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
5650 : // use default value if there are no user inputs
5651 40 : Real64 ColdTempThresh = 15.56;
5652 40 : Real64 HeatTempThresh = 30.0;
5653 : // Trace current time step Zone Pierce SET; NaN if no occupant or SET not calculated
5654 : // Record last time step SET to trace SET unmet duration;
5655 :
5656 40 : Real64 valueNotInit = -999.0;
5657 40 : Real64 nearThreshold = 1.0;
5658 80 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5659 40 : state.dataHeatBal->Resilience(ZoneNum).PierceSET = valueNotInit;
5660 40 : state.dataHeatBal->Resilience(ZoneNum).PMV = valueNotInit;
5661 : }
5662 80 : for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
5663 40 : int ZoneNum = state.dataHeatBal->People(iPeople).ZonePtr;
5664 40 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc =
5665 40 : state.dataHeatBal->People(iPeople).NumberOfPeople * state.dataHeatBal->People(iPeople).sched->getCurrentVal();
5666 40 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
5667 40 : if (state.dataHeatBal->People(iPeople).Pierce) {
5668 40 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = state.dataThermalComforts->ThermalComfortData(iPeople).PierceSET;
5669 : } else {
5670 0 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = -1;
5671 : }
5672 :
5673 40 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
5674 40 : Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5675 40 : ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
5676 40 : bool &CrossedColdThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedColdThresh;
5677 40 : if (Temperature > ColdTempThresh) { // safe
5678 36 : if (!CrossedColdThresh) {
5679 : // compute the number of hours before threshold is reached
5680 36 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
5681 : }
5682 : } else { // danger
5683 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5684 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
5685 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
5686 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5687 : // first time crossing threshold
5688 4 : if (!CrossedColdThresh) {
5689 : // compute the time when the zone crosses the threshold temperature
5690 : int encodedMonDayHrMin;
5691 2 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5692 2 : state.dataEnvrn->Month,
5693 2 : state.dataEnvrn->DayOfMonth,
5694 2 : state.dataGlobal->HourOfDay,
5695 2 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5696 : // fixme: not sure how to aggregate by zone
5697 2 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[1] = encodedMonDayHrMin;
5698 2 : CrossedColdThresh = true;
5699 : }
5700 : }
5701 40 : HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
5702 40 : bool &CrossedHeatThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedHeatThresh;
5703 40 : if (Temperature < HeatTempThresh) { // safe
5704 16 : if (!CrossedHeatThresh) {
5705 : // compute the number of hours before threshold is reached
5706 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
5707 : }
5708 : } else { // danger
5709 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5710 24 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
5711 24 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
5712 24 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5713 : // first time crossing threshold
5714 24 : if (!CrossedHeatThresh) {
5715 : // compute the time when the zone crosses the threshold temperature
5716 : int encodedMonDayHrMin;
5717 2 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5718 2 : state.dataEnvrn->Month,
5719 2 : state.dataEnvrn->DayOfMonth,
5720 2 : state.dataGlobal->HourOfDay,
5721 2 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5722 2 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[1] = encodedMonDayHrMin;
5723 2 : CrossedHeatThresh = true;
5724 : }
5725 : }
5726 :
5727 40 : Real64 VeryHotPMVThresh = 3.0;
5728 40 : Real64 WarmPMVThresh = 0.7;
5729 40 : Real64 CoolPMVThresh = -0.7;
5730 40 : Real64 VeryColdPMVThresh = -3.0;
5731 40 : Real64 PMV = state.dataThermalComforts->ThermalComfortData(iPeople).FangerPMV;
5732 40 : if (PMV < VeryColdPMVThresh) {
5733 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[0] +=
5734 14 : (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5735 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[0] +=
5736 14 : (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5737 : }
5738 40 : if (PMV < CoolPMVThresh) {
5739 20 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[1] +=
5740 20 : (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5741 20 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[1] +=
5742 20 : (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5743 : }
5744 40 : if (PMV > WarmPMVThresh) {
5745 16 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[2] +=
5746 16 : (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
5747 16 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[2] +=
5748 16 : (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5749 : }
5750 40 : if (PMV > VeryHotPMVThresh) {
5751 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[3] +=
5752 0 : (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
5753 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[3] +=
5754 0 : (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5755 : }
5756 :
5757 : // check whether PierceSET changed for people in a zone
5758 40 : if (state.dataHeatBal->Resilience(ZoneNum).PierceSET < valueNotInit + nearThreshold) {
5759 40 : state.dataHeatBal->Resilience(ZoneNum).PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
5760 : } else {
5761 0 : if (state.dataHeatBal->Resilience(ZoneNum).PierceSET != state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET) {
5762 0 : ShowRecurringWarningErrorAtEnd(state,
5763 0 : fmt::format("Zone {} has multiple people objects with different PierceSet.", ZoneNum),
5764 0 : state.dataHeatBalFanSys->PierceSETerrorIndex);
5765 : }
5766 : }
5767 :
5768 : // check whether PierceSET, PMV, etc. changed for different people in a zone
5769 40 : if (state.dataHeatBal->Resilience(ZoneNum).PMV < valueNotInit + nearThreshold) {
5770 40 : state.dataHeatBal->Resilience(ZoneNum).PMV = PMV;
5771 : } else {
5772 0 : if (state.dataHeatBal->Resilience(ZoneNum).PMV != PMV) {
5773 0 : ShowRecurringWarningErrorAtEnd(state,
5774 0 : fmt::format("Zone {} has multiple people objects with different PMV.", ZoneNum),
5775 0 : state.dataHeatBalFanSys->PMVerrorIndex);
5776 : }
5777 : }
5778 :
5779 80 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5780 40 : if (reportPeriodFlags(i)) {
5781 18 : int ReportPeriodIdx = i;
5782 18 : ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
5783 18 : bool &CrossedColdThreshRepPeriod = state.dataHeatBalFanSys->CrossedColdThreshRepPeriod(ZoneNum, ReportPeriodIdx);
5784 18 : if (Temperature > ColdTempThresh) { // safe
5785 16 : if (!CrossedColdThreshRepPeriod) {
5786 : // compute the number of hours before threshold is reached
5787 16 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
5788 : }
5789 : } else { // danger
5790 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5791 2 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
5792 2 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
5793 2 : NumOcc * state.dataGlobal->TimeStepZone;
5794 2 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
5795 2 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5796 : // first time crossing threshold
5797 2 : if (!CrossedColdThreshRepPeriod) {
5798 : // compute the time when the zone crosses the threshold temperature
5799 : int encodedMonDayHrMin;
5800 1 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5801 1 : state.dataEnvrn->Month,
5802 1 : state.dataEnvrn->DayOfMonth,
5803 1 : state.dataGlobal->HourOfDay,
5804 1 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5805 : // fixme: not sure how to aggregate by zone
5806 1 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
5807 1 : CrossedColdThreshRepPeriod = true;
5808 : }
5809 : }
5810 18 : HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
5811 18 : bool &CrossedHeatThreshRepPeriod = state.dataHeatBalFanSys->CrossedHeatThreshRepPeriod(ZoneNum, ReportPeriodIdx);
5812 18 : if (Temperature < HeatTempThresh) { // safe
5813 8 : if (!CrossedHeatThreshRepPeriod) {
5814 : // compute the number of hours before threshold is reached
5815 3 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
5816 : }
5817 : } else { // danger
5818 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5819 10 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
5820 10 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
5821 10 : NumOcc * state.dataGlobal->TimeStepZone;
5822 10 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
5823 10 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5824 : // first time crossing threshold
5825 10 : if (!CrossedHeatThreshRepPeriod) {
5826 : // compute the time when the zone crosses the threshold temperature
5827 : int encodedMonDayHrMin;
5828 2 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5829 2 : state.dataEnvrn->Month,
5830 2 : state.dataEnvrn->DayOfMonth,
5831 2 : state.dataGlobal->HourOfDay,
5832 2 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5833 2 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
5834 2 : CrossedHeatThreshRepPeriod = true;
5835 : }
5836 : }
5837 :
5838 18 : if (PMV < VeryColdPMVThresh) {
5839 7 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
5840 7 : (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5841 7 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
5842 7 : (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5843 : }
5844 18 : if (PMV < CoolPMVThresh) {
5845 10 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
5846 10 : (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5847 10 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
5848 10 : (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5849 : }
5850 18 : if (PMV > WarmPMVThresh) {
5851 8 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
5852 8 : (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
5853 8 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
5854 8 : (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5855 : }
5856 18 : if (PMV > VeryHotPMVThresh) {
5857 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
5858 0 : (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
5859 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
5860 0 : (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5861 : }
5862 : }
5863 : }
5864 : }
5865 80 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5866 40 : Real64 HI = state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex;
5867 40 : Real64 Humidex = state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex;
5868 :
5869 40 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
5870 40 : if (HI <= 26.7) {
5871 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[0] += state.dataGlobal->TimeStepZone;
5872 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
5873 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5874 36 : } else if (HI > 26.7 && HI <= 32.2) {
5875 2 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[1] += state.dataGlobal->TimeStepZone;
5876 2 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
5877 2 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5878 34 : } else if (HI > 32.2 && HI <= 39.4) {
5879 34 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[2] += state.dataGlobal->TimeStepZone;
5880 34 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
5881 34 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5882 0 : } else if (HI > 39.4 && HI <= 51.7) {
5883 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[3] += state.dataGlobal->TimeStepZone;
5884 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
5885 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5886 : } else {
5887 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[4] += state.dataGlobal->TimeStepZone;
5888 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
5889 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5890 : }
5891 :
5892 40 : if (Humidex <= 29) {
5893 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[0] += state.dataGlobal->TimeStepZone;
5894 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
5895 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5896 36 : } else if (Humidex > 29 && Humidex <= 40) {
5897 36 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[1] += state.dataGlobal->TimeStepZone;
5898 36 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
5899 36 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5900 0 : } else if (Humidex > 40 && Humidex <= 45) {
5901 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[2] += state.dataGlobal->TimeStepZone;
5902 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
5903 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5904 0 : } else if (Humidex > 45 && Humidex <= 50) {
5905 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[3] += state.dataGlobal->TimeStepZone;
5906 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
5907 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5908 : } else {
5909 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[4] += state.dataGlobal->TimeStepZone;
5910 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
5911 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5912 : }
5913 :
5914 40 : Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5915 40 : auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
5916 40 : Real64 CoolingSetpoint = zoneTstatSetpt.setptHi;
5917 40 : Real64 HeatingSetpoint = zoneTstatSetpt.setptLo;
5918 :
5919 40 : if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
5920 30 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[0] += (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
5921 30 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[1] +=
5922 30 : NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
5923 30 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[2] +=
5924 30 : (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
5925 : }
5926 40 : if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
5927 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[3] += (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
5928 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[4] +=
5929 4 : NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
5930 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[5] +=
5931 4 : (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
5932 : }
5933 :
5934 40 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
5935 : int encodedMonDayHrMin;
5936 40 : Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
5937 40 : Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
5938 :
5939 40 : if (PierceSET <= 12.2) {
5940 22 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[0] += (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
5941 22 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[1] += (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
5942 22 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[2] += (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5943 : // Reset duration when last step is out of range.
5944 22 : if (PierceSETLast == -1 || PierceSETLast > 12.2) {
5945 4 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5946 4 : state.dataEnvrn->Month,
5947 4 : state.dataEnvrn->DayOfMonth,
5948 4 : state.dataGlobal->HourOfDay,
5949 4 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5950 4 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
5951 4 : state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
5952 : }
5953 : // Keep the longest duration record.
5954 22 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
5955 36 : if (state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] &&
5956 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
5957 12 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] = state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1];
5958 12 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[4] = state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1];
5959 : }
5960 18 : } else if (PierceSET > 30) {
5961 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[0] += (PierceSET - 30) * state.dataGlobal->TimeStepZone;
5962 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[1] += (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
5963 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[2] += (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5964 14 : if (PierceSETLast == -1 || PierceSETLast <= 30) {
5965 4 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5966 4 : state.dataEnvrn->Month,
5967 4 : state.dataEnvrn->DayOfMonth,
5968 4 : state.dataGlobal->HourOfDay,
5969 4 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5970 4 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
5971 4 : state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
5972 : }
5973 14 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
5974 28 : if (state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] &&
5975 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
5976 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] = state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1];
5977 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[4] = state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1];
5978 : }
5979 : }
5980 :
5981 40 : if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
5982 12 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
5983 12 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
5984 : }
5985 : }
5986 :
5987 80 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5988 40 : if (reportPeriodFlags(i)) {
5989 18 : int ReportPeriodIdx = i;
5990 :
5991 18 : if (HI <= 26.7) {
5992 2 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
5993 2 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
5994 2 : NumOcc * state.dataGlobal->TimeStepZone;
5995 2 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
5996 2 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5997 16 : } else if (HI > 26.7 && HI <= 32.2) {
5998 1 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
5999 1 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6000 1 : NumOcc * state.dataGlobal->TimeStepZone;
6001 1 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6002 1 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6003 15 : } else if (HI > 32.2 && HI <= 39.4) {
6004 15 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6005 15 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6006 15 : NumOcc * state.dataGlobal->TimeStepZone;
6007 15 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6008 15 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6009 0 : } else if (HI > 39.4 && HI <= 51.7) {
6010 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6011 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6012 0 : NumOcc * state.dataGlobal->TimeStepZone;
6013 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6014 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6015 : } else {
6016 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
6017 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6018 0 : NumOcc * state.dataGlobal->TimeStepZone;
6019 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6020 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6021 : }
6022 :
6023 18 : if (Humidex <= 29) {
6024 2 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6025 2 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6026 2 : NumOcc * state.dataGlobal->TimeStepZone;
6027 2 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6028 2 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6029 16 : } else if (Humidex > 29 && Humidex <= 40) {
6030 16 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6031 16 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6032 16 : NumOcc * state.dataGlobal->TimeStepZone;
6033 16 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6034 16 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6035 0 : } else if (Humidex > 40 && Humidex <= 45) {
6036 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6037 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6038 0 : NumOcc * state.dataGlobal->TimeStepZone;
6039 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6040 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6041 0 : } else if (Humidex > 45 && Humidex <= 50) {
6042 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6043 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6044 0 : NumOcc * state.dataGlobal->TimeStepZone;
6045 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6046 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6047 : } else {
6048 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
6049 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6050 0 : NumOcc * state.dataGlobal->TimeStepZone;
6051 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6052 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6053 : }
6054 :
6055 18 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
6056 : int encodedMonDayHrMin;
6057 18 : Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
6058 18 : Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
6059 18 : if (PierceSET <= 12.2) {
6060 11 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6061 11 : (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
6062 11 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6063 11 : (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
6064 11 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6065 11 : (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6066 : // Reset duration when last step is out of range
6067 11 : if (PierceSETLast == -1 || PierceSETLast > 12.2) {
6068 2 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6069 2 : state.dataEnvrn->Month,
6070 2 : state.dataEnvrn->DayOfMonth,
6071 2 : state.dataGlobal->HourOfDay,
6072 2 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6073 2 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6074 2 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6075 9 : } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
6076 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6077 0 : state.dataEnvrn->Month,
6078 0 : state.dataEnvrn->DayOfMonth,
6079 0 : state.dataGlobal->HourOfDay,
6080 0 : state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
6081 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6082 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6083 : }
6084 : // Keep the longest duration record.
6085 11 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
6086 11 : if (state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
6087 21 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
6088 10 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6089 9 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
6090 9 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
6091 9 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
6092 9 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
6093 : }
6094 7 : } else if (PierceSET > 30) {
6095 7 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6096 7 : (PierceSET - 30) * state.dataGlobal->TimeStepZone;
6097 7 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6098 7 : (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
6099 7 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6100 7 : (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6101 : // Reset duration when last step is out of range.
6102 7 : if (PierceSETLast == -1 || PierceSETLast <= 30) {
6103 2 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6104 2 : state.dataEnvrn->Month,
6105 2 : state.dataEnvrn->DayOfMonth,
6106 2 : state.dataGlobal->HourOfDay,
6107 2 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6108 2 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6109 2 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6110 5 : } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
6111 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6112 0 : state.dataEnvrn->Month,
6113 0 : state.dataEnvrn->DayOfMonth,
6114 0 : state.dataGlobal->HourOfDay,
6115 0 : state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
6116 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6117 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6118 : }
6119 7 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
6120 7 : if (state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
6121 14 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
6122 7 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6123 3 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
6124 3 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
6125 3 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
6126 3 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
6127 : }
6128 : }
6129 18 : if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
6130 6 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6131 6 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6132 : }
6133 : }
6134 :
6135 18 : if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
6136 13 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6137 13 : (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6138 13 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6139 13 : NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6140 13 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6141 13 : (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6142 : }
6143 18 : if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
6144 2 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6145 2 : (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6146 2 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6147 2 : NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6148 2 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[5] +=
6149 2 : (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6150 : }
6151 : }
6152 : }
6153 : } // loop over zones
6154 : }
6155 69975 : }
6156 :
6157 55 : void ReportCO2Resilience(EnergyPlusData &state)
6158 : {
6159 55 : if (state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime) {
6160 40 : int NoBins = 3;
6161 86 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6162 48 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6163 2 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6164 2 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6165 2 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6166 : }
6167 : }
6168 40 : state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime = false;
6169 40 : if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
6170 38 : if (state.dataOutRptTab->displayCO2ResilienceSummaryExplicitly) {
6171 0 : ShowWarningError(state,
6172 : "Writing Annual CO2 Resilience Summary - CO2 Level Hours reports: "
6173 : "Zone Air CO2 Concentration output is required, "
6174 : "but no ZoneAirContaminantBalance object is defined.");
6175 : }
6176 38 : state.dataOutRptTab->displayCO2ResilienceSummary = false;
6177 38 : return;
6178 : }
6179 : }
6180 :
6181 17 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
6182 34 : for (auto const &people : state.dataHeatBal->People) {
6183 17 : state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
6184 : }
6185 :
6186 17 : Array1D_bool reportPeriodFlags;
6187 17 : if (state.dataWeather->TotReportPers > 0) {
6188 16 : reportPeriodFlags.dimension(state.dataWeather->TotCO2ReportPers, false);
6189 16 : General::findReportPeriodIdx(state, state.dataWeather->CO2ReportPeriodInput, state.dataWeather->TotCO2ReportPers, reportPeriodFlags);
6190 : }
6191 :
6192 17 : auto &ort = state.dataOutRptTab;
6193 49 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6194 32 : if (reportPeriodFlags(i)) {
6195 16 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
6196 16 : state.dataWeather->CO2ReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
6197 : }
6198 : }
6199 :
6200 34 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6201 17 : Real64 ZoneAirCO2 = state.dataContaminantBalance->ZoneAirCO2Avg(ZoneNum);
6202 :
6203 17 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6204 17 : if (ZoneAirCO2 <= 1000) {
6205 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[0] += state.dataGlobal->TimeStepZone;
6206 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6207 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6208 13 : } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
6209 12 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[1] += state.dataGlobal->TimeStepZone;
6210 12 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6211 12 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6212 : } else {
6213 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[2] += state.dataGlobal->TimeStepZone;
6214 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6215 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6216 : }
6217 49 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6218 32 : if (reportPeriodFlags(i)) {
6219 16 : int ReportPeriodIdx = i;
6220 16 : if (ZoneAirCO2 <= 1000) {
6221 4 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6222 4 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6223 4 : NumOcc * state.dataGlobal->TimeStepZone;
6224 4 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6225 4 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6226 12 : } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
6227 11 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6228 11 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6229 11 : NumOcc * state.dataGlobal->TimeStepZone;
6230 11 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6231 11 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6232 : } else {
6233 1 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6234 1 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6235 1 : NumOcc * state.dataGlobal->TimeStepZone;
6236 1 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6237 1 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6238 : }
6239 : }
6240 : }
6241 : }
6242 17 : } // loop over zones
6243 : }
6244 :
6245 55 : void ReportVisualResilience(EnergyPlusData &state)
6246 : {
6247 55 : if (state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime) {
6248 40 : int NoBins = 4;
6249 86 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6250 48 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6251 2 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6252 2 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6253 2 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6254 : }
6255 : }
6256 40 : state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime = false;
6257 40 : if ((int)state.dataDayltg->daylightControl.size() == 0) {
6258 38 : if (state.dataOutRptTab->displayVisualResilienceSummaryExplicitly) {
6259 0 : ShowWarningError(state,
6260 : "Writing Annual Visual Resilience Summary - Lighting Level Hours reports: "
6261 : "Zone Average Daylighting Reference Point Illuminance output is required, "
6262 : "but no Daylighting Control Object is defined.");
6263 : }
6264 38 : state.dataOutRptTab->displayVisualResilienceSummary = false;
6265 38 : return;
6266 : }
6267 : }
6268 :
6269 17 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
6270 34 : for (auto const &people : state.dataHeatBal->People) {
6271 17 : state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
6272 : }
6273 : // Accumulate across daylighting controls first
6274 34 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6275 17 : state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum = 0.0;
6276 : }
6277 34 : for (int daylightCtrlNum = 1; daylightCtrlNum <= (int)state.dataDayltg->daylightControl.size(); ++daylightCtrlNum) {
6278 17 : auto &thisDaylightControl = state.dataDayltg->daylightControl(daylightCtrlNum);
6279 17 : if (thisDaylightControl.PowerReductionFactor > 0) {
6280 34 : for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
6281 17 : state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum += thisDaylightControl.refPts(refPt).illumSetPoint;
6282 : }
6283 : } else {
6284 0 : for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
6285 0 : state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum +=
6286 0 : thisDaylightControl.refPts(refPt).lums[(int)DataSurfaces::Lum::Illum];
6287 : }
6288 : }
6289 : }
6290 :
6291 17 : Array1D_bool reportPeriodFlags;
6292 17 : if (state.dataWeather->TotReportPers > 0) {
6293 16 : reportPeriodFlags.dimension(state.dataWeather->TotVisualReportPers, false);
6294 32 : General::findReportPeriodIdx(
6295 16 : state, state.dataWeather->VisualReportPeriodInput, state.dataWeather->TotVisualReportPers, reportPeriodFlags);
6296 : }
6297 :
6298 17 : auto &ort = state.dataOutRptTab;
6299 49 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6300 32 : if (reportPeriodFlags(i)) {
6301 16 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
6302 16 : state.dataWeather->VisualReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
6303 : }
6304 : }
6305 :
6306 34 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6307 17 : if (state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts == 0) continue;
6308 : // Now divide by total reference points to get average
6309 17 : Real64 avgZoneIllum = state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum / state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts;
6310 :
6311 17 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6312 17 : if (avgZoneIllum <= 100) {
6313 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[0] += state.dataGlobal->TimeStepZone;
6314 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6315 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6316 11 : } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
6317 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[1] += state.dataGlobal->TimeStepZone;
6318 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6319 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6320 7 : } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
6321 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[2] += state.dataGlobal->TimeStepZone;
6322 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6323 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6324 : } else {
6325 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[3] += state.dataGlobal->TimeStepZone;
6326 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
6327 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6328 : }
6329 49 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6330 32 : if (reportPeriodFlags(i)) {
6331 16 : int ReportPeriodIdx = i;
6332 16 : if (avgZoneIllum <= 100) {
6333 6 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6334 6 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6335 6 : NumOcc * state.dataGlobal->TimeStepZone;
6336 6 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6337 6 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6338 10 : } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
6339 4 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6340 4 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6341 4 : NumOcc * state.dataGlobal->TimeStepZone;
6342 4 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6343 4 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6344 6 : } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
6345 0 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6346 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6347 0 : NumOcc * state.dataGlobal->TimeStepZone;
6348 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6349 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6350 : } else {
6351 6 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6352 6 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6353 6 : NumOcc * state.dataGlobal->TimeStepZone;
6354 6 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6355 6 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6356 : }
6357 : }
6358 : }
6359 : }
6360 17 : } // loop over zones
6361 : }
6362 :
6363 249948 : void ReportSurfaceHeatBalance(EnergyPlusData &state)
6364 : {
6365 :
6366 : // SUBROUTINE INFORMATION:
6367 : // AUTHOR Linda Lawrie
6368 : // DATE WRITTEN Oct 2000
6369 :
6370 : // PURPOSE OF THIS SUBROUTINE:
6371 : // This subroutine puts the reporting part of the HBSurface Module in one area.
6372 :
6373 249948 : SolarShading::ReportSurfaceShading(state);
6374 :
6375 249948 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
6376 0 : ReportNonRepresentativeSurfaceResults(state);
6377 : }
6378 :
6379 : // Set derived surface output variables and other record keeping - after iterations are complete - all HT surfaces
6380 :
6381 : // Opaque or window surfaces
6382 586590 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6383 709587 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6384 372945 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6385 372945 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
6386 372945 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
6387 2447200 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6388 2074255 : auto const &surface = state.dataSurface->Surface(surfNum);
6389 : // Inside Face Convection - sign convention is positive means energy going into inside face from the air.
6390 2074255 : state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) = surface.Area * state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum);
6391 2074255 : state.dataHeatBalSurf->SurfQConvInRep(surfNum) =
6392 2074255 : state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6393 :
6394 2074255 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
6395 2074255 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(surfNum) =
6396 2074255 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6397 :
6398 2074255 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) * surface.Area;
6399 2074255 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(surfNum) =
6400 2074255 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6401 :
6402 2074255 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) * surface.Area;
6403 2074255 : state.dataHeatBalSurf->SurfQRadHVACInRep(surfNum) =
6404 2074255 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6405 :
6406 2074255 : state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) * surface.Area;
6407 :
6408 2074255 : state.dataHeatBalSurf->SurfQConvOutReport(surfNum) =
6409 2074255 : state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6410 :
6411 2074255 : state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) * surface.Area;
6412 2074255 : state.dataHeatBalSurf->SurfQRadOutReport(surfNum) =
6413 2074255 : state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6414 :
6415 : // Calculate surface heat emission to the air, positive values indicates heat transfer from surface to the outside
6416 2074255 : state.dataHeatBalSurf->SurfQAirExtReport(surfNum) =
6417 2074255 : surface.Area * state.dataHeatBalSurf->SurfHAirExt(surfNum) *
6418 2074255 : (state.dataHeatBalSurf->SurfTempOut(surfNum) - state.dataSurface->SurfOutDryBulbTemp(surfNum));
6419 :
6420 : // Subtract since SurfQdotConvOutRep's convention is opposite (positive values indicate heat transfer from the outside to the surface)
6421 2074255 : state.dataHeatBalSurf->SurfQHeatEmiReport(surfNum) =
6422 2074255 : state.dataHeatBalSurf->SurfQAirExtReport(surfNum) - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum);
6423 : }
6424 : }
6425 : }
6426 :
6427 249948 : if (state.dataOutRptTab->displayHeatEmissionsSummary) {
6428 69935 : state.dataHeatBalSurf->SumSurfaceHeatEmission = 0.0;
6429 508457 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
6430 438522 : if (state.dataSurface->Surface(SurfNum).ExtBoundCond == DataSurfaces::ExternalEnvironment) {
6431 350203 : state.dataHeatBalSurf->SumSurfaceHeatEmission +=
6432 350203 : state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
6433 : }
6434 : }
6435 : }
6436 :
6437 : // Window surfaces
6438 586590 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6439 709587 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6440 372945 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6441 372945 : int const firstSurf = thisSpace.WindowSurfaceFirst;
6442 372945 : int const lastSurf = thisSpace.WindowSurfaceLast;
6443 461506 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6444 88561 : auto const &surface = state.dataSurface->Surface(surfNum);
6445 88561 : state.dataHeatBal->SurfWinInitialDifSolInTransReport(surfNum) =
6446 88561 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum) * surface.Area;
6447 :
6448 : // Absorbed short wave radiation
6449 : int TotGlassLayers;
6450 88561 : int const constrNum = state.dataSurface->SurfActiveConstruction(surfNum);
6451 88561 : auto const &thisConstruct = state.dataConstruction->Construct(constrNum);
6452 88561 : int const constrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(surfNum);
6453 88561 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(surfNum);
6454 88561 : if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::EQL) {
6455 2367 : TotGlassLayers = state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL;
6456 86194 : } else if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::BSDF) {
6457 0 : TotGlassLayers = thisConstruct.TotSolidLayers;
6458 86194 : } else if (DataSurfaces::NOT_SHADED(ShadeFlag) || ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
6459 86194 : TotGlassLayers = thisConstruct.TotGlassLayers;
6460 : } else {
6461 : // Interior, exterior or between-glass shade, screen or blind in place
6462 0 : TotGlassLayers = state.dataConstruction->Construct(constrNumSh).TotGlassLayers;
6463 : }
6464 88561 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) = 0.0;
6465 88561 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = 0.0;
6466 88561 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = 0.0;
6467 205255 : for (int lay = 1; lay <= TotGlassLayers; ++lay) {
6468 : // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
6469 116694 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) +=
6470 116694 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(surfNum, lay) * surface.Area;
6471 : // Total Shortwave Radiation Absorbed on Inside of Surface[W]
6472 116694 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
6473 : // Total Shortwave Absorbed:All solid Layers[W]
6474 116694 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
6475 : }
6476 :
6477 : // Window heat gain/loss
6478 88561 : if (state.dataSurface->SurfWinHeatGain(surfNum) >= 0.0) {
6479 32908 : state.dataSurface->SurfWinHeatGainRep(surfNum) = state.dataSurface->SurfWinHeatGain(surfNum);
6480 32908 : state.dataSurface->SurfWinHeatGainRepEnergy(surfNum) =
6481 32908 : state.dataSurface->SurfWinHeatGainRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6482 : } else {
6483 55653 : state.dataSurface->SurfWinHeatLossRep(surfNum) = -state.dataSurface->SurfWinHeatGain(surfNum);
6484 55653 : state.dataSurface->SurfWinHeatLossRepEnergy(surfNum) =
6485 55653 : state.dataSurface->SurfWinHeatLossRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6486 : }
6487 88561 : state.dataSurface->SurfWinHeatTransferRepEnergy(surfNum) =
6488 88561 : state.dataSurface->SurfWinHeatGain(surfNum) * state.dataGlobal->TimeStepZoneSec;
6489 88561 : if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
6490 0 : int pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
6491 0 : state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatGain = state.dataSurface->SurfWinHeatGainRep(surfNum);
6492 0 : state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatLoss = state.dataSurface->SurfWinHeatLossRep(surfNum);
6493 : }
6494 : }
6495 : }
6496 : }
6497 :
6498 249948 : if (state.dataSurface->AnyMovableInsulation) ReportIntMovInsInsideSurfTemp(state);
6499 :
6500 : // Opaque heat transfer surfaces
6501 586590 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6502 709587 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6503 372945 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6504 372945 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6505 372945 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6506 2358639 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6507 1985694 : auto const &surface = state.dataSurface->Surface(surfNum);
6508 :
6509 1985694 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) * surface.Area;
6510 1985694 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(surfNum) =
6511 1985694 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) * state.dataGlobal->TimeStepZoneSec;
6512 :
6513 1985694 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) * surface.Area;
6514 1985694 : state.dataHeatBalSurf->SurfQRadSolarInRep(surfNum) =
6515 1985694 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6516 :
6517 1985694 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) * surface.Area;
6518 1985694 : state.dataHeatBalSurf->SurfQRadLightsInRep(surfNum) =
6519 1985694 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6520 :
6521 : // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
6522 1985694 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(surfNum) * surface.Area;
6523 : // Total Shortwave Radiation Absorbed on Inside of Surface[W]
6524 1985694 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) * surface.Area;
6525 :
6526 : // inside face conduction updates
6527 1985694 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) * surface.Area;
6528 1985694 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(surfNum) =
6529 1985694 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6530 1985694 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = 0.0;
6531 1985694 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = 0.0;
6532 1985694 : if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) >= 0.0) {
6533 843293 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6534 : } else {
6535 1142401 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6536 : }
6537 :
6538 : // outside face conduction updates
6539 1985694 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum);
6540 1985694 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(surfNum) =
6541 1985694 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6542 1985694 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = 0.0;
6543 1985694 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = 0.0;
6544 1985694 : if (state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) >= 0.0) {
6545 1325016 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6546 : } else {
6547 660678 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6548 : }
6549 : }
6550 2358639 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6551 : // do average surface conduction updates
6552 :
6553 1985694 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) =
6554 1985694 : (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)) / 2.0;
6555 1985694 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(surfNum) =
6556 1985694 : (state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)) / 2.0;
6557 1985694 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(surfNum) =
6558 1985694 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6559 1985694 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = 0.0;
6560 1985694 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = 0.0;
6561 1985694 : if (state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) >= 0.0) {
6562 807690 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
6563 : } else {
6564 1178004 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
6565 : }
6566 :
6567 : // do surface storage rate updates
6568 1985694 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux(surfNum) =
6569 1985694 : -(state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum));
6570 1985694 : state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) =
6571 1985694 : -(state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum));
6572 1985694 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(surfNum) =
6573 1985694 : state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6574 1985694 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = 0.0;
6575 1985694 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = 0.0;
6576 1985694 : if (state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) >= 0.0) {
6577 1048369 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
6578 : } else {
6579 937325 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
6580 : }
6581 : }
6582 : }
6583 : }
6584 :
6585 249948 : if (state.dataGlobal->ZoneSizingCalc && state.dataGlobal->CompLoadReportIsReq) {
6586 : // This is by surface, so it works for both space and zone component loads
6587 14868 : int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
6588 14868 : auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
6589 43206 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6590 56676 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6591 28338 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6592 28338 : int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6593 28338 : int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6594 171426 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6595 143088 : surfCLDayTS.surf[surfNum - 1].lightSWRadSeq = state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum);
6596 143088 : surfCLDayTS.surf[surfNum - 1].feneSolarRadSeq = state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum);
6597 : }
6598 28338 : firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
6599 28338 : lastSurf = thisSpace.OpaqOrWinSurfaceLast;
6600 178212 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6601 149874 : auto const &surface = state.dataSurface->Surface(surfNum);
6602 149874 : if (!state.dataGlobal->WarmupFlag) {
6603 20640 : if (state.dataGlobal->isPulseZoneSizing) {
6604 10320 : surfCLDayTS.surf[surfNum - 1].loadConvectedWithPulse = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
6605 : } else {
6606 10320 : surfCLDayTS.surf[surfNum - 1].loadConvectedNormal = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
6607 10320 : surfCLDayTS.surf[surfNum - 1].netSurfRadSeq = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
6608 : }
6609 : }
6610 : }
6611 : }
6612 : }
6613 : }
6614 :
6615 249948 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
6616 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6617 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6618 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6619 0 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6620 0 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6621 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6622 0 : state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6623 0 : state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6624 : }
6625 0 : if (state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) >= 0.0) {
6626 0 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
6627 0 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) =
6628 0 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6629 : } else {
6630 0 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
6631 0 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) =
6632 0 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6633 : }
6634 :
6635 0 : if (state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) >= 0.0) {
6636 0 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
6637 0 : state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) =
6638 0 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6639 : } else {
6640 0 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
6641 0 : state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) =
6642 0 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6643 : }
6644 : }
6645 : }
6646 : }
6647 249948 : }
6648 :
6649 0 : void ReportNonRepresentativeSurfaceResults(EnergyPlusData &state)
6650 : {
6651 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6652 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6653 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6654 : // Heat transfer surfaces
6655 0 : int firstSurf = thisSpace.HTSurfaceFirst;
6656 0 : int lastSurf = thisSpace.HTSurfaceLast;
6657 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6658 0 : auto const &surface = state.dataSurface->Surface(surfNum);
6659 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
6660 0 : if (surfNum != repSurfNum) {
6661 0 : state.dataSurface->surfIntConv(surfNum).convClassRpt = state.dataSurface->surfIntConv(repSurfNum).convClassRpt;
6662 0 : state.dataSurface->surfExtConv(surfNum).convClassRpt = state.dataSurface->surfExtConv(repSurfNum).convClassRpt;
6663 : }
6664 : }
6665 :
6666 : // Windows
6667 0 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
6668 0 : firstSurf = thisSpace.WindowSurfaceFirst;
6669 0 : lastSurf = thisSpace.WindowSurfaceLast;
6670 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6671 0 : auto const &surface = state.dataSurface->Surface(surfNum);
6672 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
6673 0 : if (surfNum != repSurfNum) {
6674 0 : Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
6675 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
6676 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
6677 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
6678 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
6679 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
6680 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(repSurfNum) * areaRatio;
6681 : }
6682 : }
6683 : }
6684 : }
6685 : }
6686 0 : }
6687 :
6688 1 : void ReportIntMovInsInsideSurfTemp(EnergyPlusData &state)
6689 : {
6690 1 : state.dataHeatBalSurf->SurfTempInMovInsRep = state.dataHeatBalSurf->SurfTempIn;
6691 3 : for (int SurfNum : state.dataSurface->intMovInsulSurfNums) {
6692 2 : if (state.dataSurface->intMovInsuls(SurfNum).present) {
6693 1 : state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
6694 : }
6695 : }
6696 1 : }
6697 : // End of Reporting subroutines for the HB Module
6698 : // *****************************************************************************
6699 :
6700 : // *****************************************************************************
6701 : // *****************************************************************************
6702 : // *****************************************************************************
6703 : // *****************************************************************************
6704 :
6705 : // Formerly EXTERNAL SUBROUTINES (heavily related to HeatBalanceSurfaceManager) now moved into namespace
6706 :
6707 249962 : void CalcHeatBalanceOutsideSurf(EnergyPlusData &state,
6708 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
6709 : {
6710 :
6711 : // SUBROUTINE INFORMATION:
6712 : // AUTHOR George Walton
6713 : // DATE WRITTEN December 1979
6714 : // MODIFIED Jun 1990 (RDT for new CTF arrays);
6715 : // Aug 2000 (RJL for MTF moisture calculations)
6716 : // Sep 2000 (RKS for new radiant exchange algorithm)
6717 : // Dec 2000 (RKS for radiant system model addition)
6718 : // Apr 2002 (COP removed denominator from OSC calculation
6719 : // Jul 2008 (P.Biddulph include calls to HAMT)
6720 : // Jul 2011, M.J. Witte and C.O. Pedersen, add new fields to OSC for last T, max and min
6721 : // Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
6722 : // RE-ENGINEERED Mar 1998 (RKS)
6723 :
6724 : // PURPOSE OF THIS SUBROUTINE:
6725 : // This subroutine performs a heat balance on the outside face of each
6726 : // surface in the building.
6727 :
6728 : // METHODOLOGY EMPLOYED:
6729 : // Various boundary conditions are set and additional parameters are set-
6730 : // up. Then, the proper heat balance equation is selected based on the
6731 : // presence of movable insulation, thermal mass of the surface construction,
6732 : // and convection model being used.
6733 :
6734 : // REFERENCES:
6735 : // (I)BLAST legacy routine HBOUT
6736 : // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
6737 :
6738 : // // Using/Aliasing
6739 : // using namespace DataEnvironment;
6740 : // using namespace DataHeatBalance;
6741 : // using namespace DataHeatBalSurface;
6742 : // using namespace DataSurfaces;
6743 : // using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
6744 : // using namespace Psychrometrics;
6745 : // using EcoRoofManager::CalcEcoRoof;
6746 : //
6747 : // // Locals
6748 : // // SUBROUTINE ARGUMENT DEFINITIONS:
6749 : //
6750 : //>>>>>>> origin/develop
6751 : // SUBROUTINE PARAMETER DEFINITIONS:
6752 249962 : constexpr std::string_view RoutineNameGroundTemp("CalcHeatBalanceOutsideSurf:GroundTemp");
6753 249962 : constexpr std::string_view RoutineNameGroundTempFC("CalcHeatBalanceOutsideSurf:GroundTempFC");
6754 249962 : constexpr std::string_view RoutineNameOtherSideCoefNoCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefNoCalcExt");
6755 249962 : constexpr std::string_view RoutineNameOtherSideCoefCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefCalcExt");
6756 249962 : constexpr std::string_view RoutineNameOSCM("CalcHeatBalanceOutsideSurf:OSCM");
6757 249962 : constexpr std::string_view RoutineNameExtEnvWetSurf("CalcHeatBalanceOutsideSurf:extEnvWetSurf");
6758 249962 : constexpr std::string_view RoutineNameExtEnvDrySurf("CalcHeatBalanceOutsideSurf:extEnvDrySurf");
6759 249962 : constexpr std::string_view RoutineNameNoWind("CalcHeatBalanceOutsideSurf:nowind");
6760 249962 : constexpr std::string_view RoutineNameOther("CalcHeatBalanceOutsideSurf:interior/other");
6761 249962 : constexpr std::string_view RoutineNameIZPart("CalcHeatBalanceOutsideSurf:IZPart");
6762 249962 : constexpr std::string_view HBSurfManGroundHAMT("HBSurfMan:Ground:HAMT");
6763 249962 : constexpr std::string_view HBSurfManRainHAMT("HBSurfMan:Rain:HAMT");
6764 249962 : constexpr std::string_view HBSurfManDrySurfCondFD("HBSurfMan:DrySurf:CondFD");
6765 249962 : constexpr std::string_view Outside("Outside");
6766 :
6767 249962 : auto &s_mat = state.dataMaterial;
6768 :
6769 249962 : bool MovInsulErrorFlag = false; // Movable Insulation error flag
6770 :
6771 : // set ground surfaces average temperature
6772 249962 : GetGroundSurfacesTemperatureAverage(state);
6773 :
6774 : // set surrounding surfaces average temperature
6775 249962 : GetSurroundingSurfacesTemperatureAverage(state);
6776 :
6777 249962 : auto &Surface = state.dataSurface->Surface;
6778 :
6779 249962 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
6780 0 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
6781 : // Need to transfer any source/sink for a surface to the local array. Note that
6782 : // the local array is flux (W/m2) while the QRadSysSource is heat transfer (W).
6783 : // This must be done at this location so that this is always updated correctly.
6784 0 : if (Surface(SurfNum).Area > 0.0)
6785 0 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) =
6786 0 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
6787 :
6788 : // next we add source (actually a sink) from any integrated PV
6789 0 : if (Surface(SurfNum).Area > 0.0)
6790 0 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +=
6791 0 : state.dataHeatBalFanSys->QPVSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
6792 : }
6793 : }
6794 :
6795 249962 : if (present(ZoneToResimulate)) {
6796 16 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
6797 8 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, ZoneToResimulate, Outside);
6798 : } else {
6799 499908 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
6800 249954 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, Outside);
6801 : }
6802 :
6803 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
6804 249963 : for (int surfNum : state.dataSurface->allOutsideSourceSurfaceList) {
6805 1 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) = Surface(surfNum).outsideHeatSourceTermSched->getCurrentVal();
6806 : }
6807 586618 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
6808 709639 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6809 372983 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
6810 2447306 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
6811 2074323 : if (Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) continue;
6812 1985763 : if (present(ZoneToResimulate)) {
6813 32 : if ((zoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) {
6814 0 : continue; // skip surfaces that are not associated with this zone
6815 : }
6816 : }
6817 : // Interior windows in partitions use "normal" heat balance calculations
6818 : // For rest, Outside surface temp of windows not needed in Window5 calculation approach.
6819 : // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
6820 :
6821 : // Initializations for this surface
6822 1985763 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
6823 1985763 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
6824 1985763 : Real64 HMovInsul = 0.0; // "Convection" coefficient of movable insulation
6825 1985763 : Real64 HSky = 0.0; // "Convection" coefficient from sky to surface
6826 1985763 : Real64 HGround = 0.0; // "Convection" coefficient from ground to surface
6827 1985763 : Real64 HAir = 0.0; // "Convection" coefficient from air to surface (radiation)
6828 1985763 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
6829 1985763 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
6830 1985763 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
6831 1985763 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
6832 1985763 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = 0.0;
6833 :
6834 : // Calculate the current outside surface temperature TH(SurfNum,1,1) for the
6835 : // various different boundary conditions
6836 1985763 : switch (Surface(SurfNum).ExtBoundCond) {
6837 121849 : case DataSurfaces::Ground: { // Surface in contact with ground
6838 121849 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
6839 121849 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
6840 :
6841 : // Set the only radiant system heat balance coefficient that is non-zero for this case
6842 121849 : if (thisConstruct.SourceSinkPresent)
6843 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
6844 :
6845 : // start HAMT
6846 121849 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
6847 : // Set variables used in the HAMT moisture balance
6848 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
6849 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
6850 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
6851 0 : state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0, HBSurfManGroundHAMT);
6852 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
6853 :
6854 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
6855 0 : state.dataMstBal->HConvExtFD(SurfNum) /
6856 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
6857 : state,
6858 0 : state.dataEnvrn->OutBaroPress,
6859 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
6860 : Psychrometrics::PsyWFnTdbRhPb(state,
6861 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
6862 : 1.0,
6863 0 : state.dataEnvrn->OutBaroPress,
6864 0 : RoutineNameGroundTemp)) +
6865 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
6866 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
6867 :
6868 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
6869 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
6870 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
6871 : }
6872 : // end HAMT
6873 :
6874 121849 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
6875 : // Set variables used in the FD moisture balance
6876 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
6877 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
6878 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
6879 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0);
6880 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
6881 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
6882 0 : state.dataMstBal->HConvExtFD(SurfNum) /
6883 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
6884 : state,
6885 0 : state.dataEnvrn->OutBaroPress,
6886 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
6887 : Psychrometrics::PsyWFnTdbRhPb(state,
6888 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
6889 : 1.0,
6890 0 : state.dataEnvrn->OutBaroPress,
6891 0 : RoutineNameGroundTemp)) +
6892 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
6893 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
6894 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
6895 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
6896 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
6897 : }
6898 : // Added for FCfactor grounds
6899 121849 : } break;
6900 0 : case DataSurfaces::GroundFCfactorMethod: { // Surface in contact with ground
6901 0 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
6902 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
6903 :
6904 : // Set the only radiant system heat balance coefficient that is non-zero for this case
6905 0 : if (thisConstruct.SourceSinkPresent)
6906 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
6907 :
6908 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
6909 : // Set variables used in the HAMT moisture balance
6910 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
6911 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
6912 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
6913 0 : state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0, HBSurfManGroundHAMT);
6914 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
6915 :
6916 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
6917 0 : state.dataMstBal->HConvExtFD(SurfNum) /
6918 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
6919 : state,
6920 0 : state.dataEnvrn->OutBaroPress,
6921 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
6922 : Psychrometrics::PsyWFnTdbRhPb(state,
6923 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
6924 : 1.0,
6925 0 : state.dataEnvrn->OutBaroPress,
6926 0 : RoutineNameGroundTempFC)) +
6927 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
6928 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
6929 :
6930 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
6931 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
6932 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
6933 : }
6934 :
6935 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
6936 : // Set variables used in the FD moisture balance
6937 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
6938 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
6939 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
6940 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0);
6941 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
6942 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
6943 0 : state.dataMstBal->HConvExtFD(SurfNum) /
6944 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
6945 : state,
6946 0 : state.dataEnvrn->OutBaroPress,
6947 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
6948 : Psychrometrics::PsyWFnTdbRhPb(state,
6949 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
6950 : 1.0,
6951 0 : state.dataEnvrn->OutBaroPress,
6952 0 : RoutineNameGroundTempFC)) +
6953 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
6954 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
6955 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
6956 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
6957 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
6958 : }
6959 0 : } break;
6960 0 : case DataSurfaces::OtherSideCoefNoCalcExt: {
6961 : // Use Other Side Coefficients to determine the surface film coefficient and
6962 : // the exterior boundary condition temperature
6963 :
6964 0 : int OPtr = Surface(SurfNum).OSCPtr;
6965 : // Set surface temp from previous timestep
6966 0 : if (state.dataGlobal->BeginTimeStepFlag) {
6967 0 : state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
6968 : }
6969 :
6970 0 : if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
6971 0 : state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
6972 : }
6973 :
6974 : // Allow for modification of TemperatureCoefficient with unitary sine wave.
6975 : Real64 ConstantTempCoef; // Temperature Coefficient as input or modified using sine wave COP mod
6976 0 : if (state.dataSurface->OSC(OPtr).SinusoidalConstTempCoef) { // Sine wave C4
6977 0 : ConstantTempCoef = std::sin(2 * Constant::Pi * state.dataGlobal->CurrentTime / state.dataSurface->OSC(OPtr).SinusoidPeriod);
6978 : } else {
6979 0 : ConstantTempCoef = state.dataSurface->OSC(OPtr).ConstTempCoef;
6980 : }
6981 :
6982 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
6983 0 : (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
6984 0 : state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
6985 0 : ConstantTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
6986 0 : state.dataSurface->OSC(OPtr).GroundTempCoef *
6987 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
6988 0 : state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
6989 0 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
6990 0 : state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
6991 :
6992 : // Enforce max/min limits if applicable
6993 0 : if (state.dataSurface->OSC(OPtr).MinLimitPresent)
6994 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
6995 0 : max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
6996 0 : if (state.dataSurface->OSC(OPtr).MaxLimitPresent)
6997 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
6998 0 : min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
6999 :
7000 0 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataSurface->OSC(OPtr).OSCTempCalc;
7001 :
7002 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7003 0 : if (thisConstruct.SourceSinkPresent)
7004 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7005 :
7006 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7007 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7008 : // Set variables used in the FD moisture balance and HAMT
7009 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7010 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7011 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7012 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7013 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7014 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7015 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7016 0 : state.dataEnvrn->OutBaroPress,
7017 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7018 : Psychrometrics::PsyWFnTdbRhPb(state,
7019 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7020 : 1.0,
7021 0 : state.dataEnvrn->OutBaroPress,
7022 0 : RoutineNameOtherSideCoefNoCalcExt)) +
7023 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7024 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7025 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7026 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7027 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7028 : }
7029 : // This ends the calculations for this surface and goes on to the next SurfNum
7030 0 : } break;
7031 0 : case DataSurfaces::OtherSideCoefCalcExt: { // A surface with other side coefficients that define the outside environment
7032 : // First, set up the outside convection coefficient and the exterior temperature
7033 : // boundary condition for the surface
7034 0 : int OPtr = Surface(SurfNum).OSCPtr;
7035 : // Set surface temp from previous timestep
7036 0 : if (state.dataGlobal->BeginTimeStepFlag) {
7037 0 : state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7038 : }
7039 :
7040 0 : if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
7041 0 : state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
7042 : }
7043 :
7044 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSC(OPtr).SurfFilmCoef;
7045 :
7046 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7047 0 : (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
7048 0 : state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7049 0 : state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
7050 0 : state.dataSurface->OSC(OPtr).GroundTempCoef *
7051 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
7052 0 : state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
7053 0 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7054 0 : state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
7055 :
7056 : // Enforce max/min limits if applicable
7057 0 : if (state.dataSurface->OSC(OPtr).MinLimitPresent)
7058 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7059 0 : max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7060 0 : if (state.dataSurface->OSC(OPtr).MaxLimitPresent)
7061 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7062 0 : min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7063 :
7064 0 : Real64 TempExt = state.dataSurface->OSC(OPtr).OSCTempCalc;
7065 :
7066 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7067 0 : if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent)
7068 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7069 :
7070 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7071 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7072 : // Set variables used in the FD moisture balance and HAMT
7073 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7074 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7075 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7076 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7077 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7078 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7079 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7080 0 : state.dataEnvrn->OutBaroPress,
7081 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7082 : Psychrometrics::PsyWFnTdbRhPb(state,
7083 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7084 : 1.0,
7085 0 : state.dataEnvrn->OutBaroPress,
7086 0 : RoutineNameOtherSideCoefCalcExt)) +
7087 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7088 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7089 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7090 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7091 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7092 : }
7093 :
7094 : // Call the outside surface temp calculation and pass the necessary terms
7095 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7096 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7097 0 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7098 0 : if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7099 : }
7100 : // This ends the calculations for this surface and goes on to the next SurfNum
7101 0 : } break;
7102 0 : case DataSurfaces::OtherSideCondModeledExt: { // A surface with other side conditions determined from separate, dynamic component
7103 : // modeling that defines the "outside environment"
7104 : // First, set up the outside convection coefficient and the exterior temperature
7105 : // boundary condition for the surface
7106 0 : int OPtr = Surface(SurfNum).OSCMPtr;
7107 : // EMS overrides
7108 0 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTConv)
7109 0 : state.dataSurface->OSCM(OPtr).TConv = state.dataSurface->OSCM(OPtr).EMSOverrideTConvValue;
7110 0 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHConv)
7111 0 : state.dataSurface->OSCM(OPtr).HConv = state.dataSurface->OSCM(OPtr).EMSOverrideHConvValue;
7112 0 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTRad)
7113 0 : state.dataSurface->OSCM(OPtr).TRad = state.dataSurface->OSCM(OPtr).EMSOverrideTRadValue;
7114 0 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHrad)
7115 0 : state.dataSurface->OSCM(OPtr).HRad = state.dataSurface->OSCM(OPtr).EMSOverrideHradValue;
7116 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSCM(OPtr).HConv;
7117 :
7118 0 : Real64 TempExt = state.dataSurface->OSCM(OPtr).TConv;
7119 :
7120 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7121 0 : if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent)
7122 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7123 :
7124 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7125 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7126 : // Set variables used in the FD moisture balance and HAMT
7127 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7128 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7129 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7130 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7131 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7132 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7133 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7134 : state,
7135 0 : state.dataEnvrn->OutBaroPress,
7136 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7137 : Psychrometrics::PsyWFnTdbRhPb(
7138 0 : state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOSCM)) +
7139 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7140 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7141 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataSurface->OSCM(OPtr).HRad; // CR 8046, use sky term for surface to baffle IR
7142 0 : state.dataMstBal->HGrndFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
7143 0 : state.dataMstBal->HAirFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
7144 : }
7145 :
7146 : // Call the outside surface temp calculation and pass the necessary terms
7147 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7148 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7149 :
7150 0 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
7151 0 : CalcExteriorVentedCavity(state, SurfNum);
7152 : }
7153 :
7154 0 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7155 0 : if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7156 :
7157 0 : } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7158 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7159 0 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
7160 0 : CalcExteriorVentedCavity(state, SurfNum);
7161 : }
7162 : }
7163 : // This ends the calculations for this surface and goes on to the next SurfNum
7164 0 : } break;
7165 1298612 : case DataSurfaces::ExternalEnvironment: {
7166 : // checking the EcoRoof presented in the external environment
7167 : // recompute each load by calling ecoroof
7168 :
7169 : Real64 TempExt;
7170 :
7171 1298612 : if (state.dataSurface->SurfExtEcoRoof(SurfNum)) {
7172 0 : EcoRoofManager::CalcEcoRoof(state, SurfNum, ConstrNum, TempExt);
7173 0 : continue;
7174 : }
7175 : // Roughness index of the exterior surface
7176 1298612 : Material::SurfaceRoughness RoughSurf = state.dataHeatBalSurf->SurfRoughnessExt(SurfNum);
7177 : // Thermal absorptance of the exterior surface
7178 1298612 : Real64 AbsThermSurf = state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum);
7179 1298612 : HMovInsul = 0;
7180 : // Check for outside movable insulation
7181 1298612 : if (state.dataSurface->AnyMovableInsulation && state.dataSurface->extMovInsuls(SurfNum).present) {
7182 0 : HMovInsul = state.dataSurface->extMovInsuls(SurfNum).H;
7183 : }
7184 :
7185 : // Check for exposure to wind (exterior environment)
7186 1298612 : if (Surface(SurfNum).ExtWind) {
7187 :
7188 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine)
7189 1212250 : Convect::InitExtConvCoeff(state,
7190 : SurfNum,
7191 : HMovInsul,
7192 : RoughSurf,
7193 : AbsThermSurf,
7194 1212250 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7195 1212250 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7196 1212250 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7197 1212250 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7198 1212250 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7199 1212250 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7200 :
7201 1212250 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside surface gets wet
7202 :
7203 0 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum == 0) { // Reset SurfHcExt because of wetness
7204 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0;
7205 : } else { // User set
7206 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
7207 : }
7208 :
7209 0 : TempExt = state.dataSurface->SurfOutWetBulbTemp(SurfNum);
7210 :
7211 : // start HAMT
7212 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7213 : // Set variables used in the HAMT moisture balance
7214 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7215 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) =
7216 0 : Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManRainHAMT);
7217 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7218 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7219 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7220 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7221 0 : state.dataEnvrn->OutBaroPress,
7222 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7223 : Psychrometrics::PsyWFnTdbRhPb(state,
7224 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7225 : 1.0,
7226 0 : state.dataEnvrn->OutBaroPress,
7227 0 : RoutineNameExtEnvWetSurf)) +
7228 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7229 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7230 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7231 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7232 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7233 : }
7234 : // end HAMT
7235 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7236 : // Set variables used in the FD moisture balance
7237 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7238 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) =
7239 0 : Psychrometrics::PsyRhovFnTdbRhLBnd0C(state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0);
7240 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7241 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7242 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7243 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7244 0 : state.dataEnvrn->OutBaroPress,
7245 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7246 : Psychrometrics::PsyWFnTdbRhPb(state,
7247 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7248 : 1.0,
7249 0 : state.dataEnvrn->OutBaroPress,
7250 0 : RoutineNameExtEnvWetSurf)) +
7251 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7252 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7253 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7254 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7255 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7256 : }
7257 :
7258 : } else { // Surface is dry, use the normal correlation
7259 :
7260 1212250 : TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
7261 :
7262 2179640 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7263 967390 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7264 : // Set variables used in the FD moisture balance and HAMT
7265 244860 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7266 244860 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7267 244860 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7268 244860 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7269 244860 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7270 244860 : state.dataMstBal->HConvExtFD(SurfNum) /
7271 489720 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7272 244860 : state.dataEnvrn->OutBaroPress,
7273 244860 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7274 : Psychrometrics::PsyWFnTdbRhPb(state,
7275 244860 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7276 : 1.0,
7277 244860 : state.dataEnvrn->OutBaroPress,
7278 244860 : RoutineNameExtEnvDrySurf)) +
7279 489720 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7280 244860 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7281 : // check for saturation conditions of air
7282 : // Local temporary saturated vapor density for checking
7283 : Real64 RhoVaporSat =
7284 244860 : Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManDrySurfCondFD);
7285 244860 : if (state.dataMstBal->RhoVaporAirOut(SurfNum) > RhoVaporSat) state.dataMstBal->RhoVaporAirOut(SurfNum) = RhoVaporSat;
7286 244860 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7287 244860 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7288 244860 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7289 : }
7290 : }
7291 :
7292 : } else { // No wind
7293 :
7294 : // Calculate exterior heat transfer coefficients for windspeed = 0
7295 86362 : Convect::InitExtConvCoeff(state,
7296 : SurfNum,
7297 : HMovInsul,
7298 : RoughSurf,
7299 : AbsThermSurf,
7300 86362 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7301 86362 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7302 86362 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7303 86362 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7304 86362 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7305 86362 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7306 :
7307 86362 : TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
7308 :
7309 172724 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7310 86362 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7311 : // Set variables used in the FD moisture balance and HAMT
7312 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7313 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7314 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7315 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7316 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7317 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7318 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7319 0 : state.dataEnvrn->OutBaroPress,
7320 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7321 : Psychrometrics::PsyWFnTdbRhPb(state,
7322 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7323 : 1.0,
7324 0 : state.dataEnvrn->OutBaroPress,
7325 0 : RoutineNameNoWind)) +
7326 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7327 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7328 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7329 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7330 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7331 : }
7332 : }
7333 : // Calculate LWR from surrounding surfaces if defined for an exterior surface
7334 1298612 : if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
7335 6 : int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
7336 : // Absolute temperature of the outside surface of an exterior surface
7337 6 : Real64 TSurf = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) + Constant::Kelvin;
7338 14 : for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface;
7339 : SrdSurfNum++) {
7340 : // View factor of a surrounding surface
7341 8 : Real64 SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor;
7342 : // Absolute temperature of a surrounding surface
7343 : Real64 SrdSurfTempAbs =
7344 8 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() +
7345 8 : Constant::Kelvin;
7346 8 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) +=
7347 8 : Constant::StefanBoltzmann * AbsThermSurf * SrdSurfViewFac * (pow_4(SrdSurfTempAbs) - pow_4(TSurf));
7348 : }
7349 : }
7350 :
7351 1298612 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7352 1543472 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD ||
7353 244860 : Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
7354 1053752 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7355 1053752 : if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7356 : }
7357 1298612 : } break;
7358 :
7359 0 : case DataSurfaces::KivaFoundation: {
7360 0 : auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
7361 0 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness;
7362 0 : Real64 AbsThermSurf = thisMaterial->AbsorpThermal;
7363 :
7364 : // Set Kiva exterior convection algorithms
7365 0 : Convect::InitExtConvCoeff(state,
7366 : SurfNum,
7367 : HMovInsul,
7368 : RoughSurf,
7369 : AbsThermSurf,
7370 0 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7371 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7372 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7373 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7374 0 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7375 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7376 0 : } break;
7377 :
7378 565302 : default: { // for interior or other zone surfaces
7379 :
7380 565302 : if (Surface(SurfNum).ExtBoundCond == SurfNum) { // Regular partition/internal mass
7381 :
7382 402090 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
7383 :
7384 : // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
7385 :
7386 755208 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7387 353118 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7388 : // Set variables used in the FD moisture balance HAMT
7389 48972 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
7390 48972 : state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(SurfNum);
7391 48972 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
7392 48972 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7393 48972 : state.dataMstBal->HConvExtFD(SurfNum) /
7394 97944 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7395 : state,
7396 48972 : state.dataEnvrn->OutBaroPress,
7397 48972 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7398 : Psychrometrics::PsyWFnTdbRhPb(
7399 48972 : state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOther)) +
7400 97944 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7401 48972 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7402 48972 : state.dataMstBal->HSkyFD(SurfNum) = 0.0;
7403 48972 : state.dataMstBal->HGrndFD(SurfNum) = 0.0;
7404 48972 : state.dataMstBal->HAirFD(SurfNum) = 0.0;
7405 : }
7406 :
7407 : } else { // Interzone partition
7408 :
7409 163212 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
7410 163212 : state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
7411 :
7412 : // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
7413 :
7414 326424 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7415 163212 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7416 : // Set variables used in the FD moisture balance and HAMT
7417 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
7418 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(Surface(SurfNum).ExtBoundCond);
7419 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(Surface(SurfNum).ExtBoundCond);
7420 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7421 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7422 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7423 0 : state.dataEnvrn->OutBaroPress,
7424 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7425 : Psychrometrics::PsyWFnTdbRhPb(state,
7426 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7427 : 1.0,
7428 0 : state.dataEnvrn->OutBaroPress,
7429 0 : RoutineNameIZPart)) +
7430 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7431 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7432 0 : state.dataMstBal->HSkyFD(SurfNum) = 0.0;
7433 0 : state.dataMstBal->HGrndFD(SurfNum) = 0.0;
7434 0 : state.dataMstBal->HAirFD(SurfNum) = 0.0;
7435 : }
7436 : }
7437 : // This ends the calculations for this surface and goes on to the next SurfNum
7438 565302 : } break;
7439 : }
7440 :
7441 1985763 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = GetQdotConvOutPerArea(state, SurfNum);
7442 : }
7443 : }
7444 : } // ...end of DO loop over all surface (actually heat transfer surfaces)
7445 249962 : }
7446 :
7447 1985765 : Real64 GetQdotConvOutPerArea(EnergyPlusData &state, int const SurfNum)
7448 : {
7449 1985765 : auto const &surface = state.dataSurface->Surface(SurfNum);
7450 1985765 : int OPtr = surface.OSCMPtr;
7451 1985765 : if (surface.OSCMPtr > 0) { // Optr is set above in this case, use OSCM boundary data
7452 0 : return -state.dataSurface->OSCM(OPtr).HConv * (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->OSCM(OPtr).TConv);
7453 : } else {
7454 1985765 : if (state.dataEnvrn->IsRain) {
7455 1 : return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
7456 1 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutWetBulbTemp(SurfNum));
7457 : } else {
7458 1985764 : return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
7459 1985764 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutDryBulbTemp(SurfNum));
7460 : }
7461 : }
7462 : }
7463 :
7464 249963 : void CalcHeatBalanceInsideSurf(EnergyPlusData &state,
7465 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
7466 : {
7467 249963 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime) {
7468 107 : if (state.dataHeatBal->AnyEMPD) {
7469 0 : state.dataHeatBalSurf->MinIterations = DataHeatBalSurface::MinEMPDIterations;
7470 : }
7471 107 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
7472 0 : SetupOutputVariable(state,
7473 : "Surface Inside Face Heat Balance Calculation Iteration Count",
7474 : Constant::Units::None,
7475 0 : state.dataHeatBal->InsideSurfIterations,
7476 : OutputProcessor::TimeStepType::Zone,
7477 : OutputProcessor::StoreType::Sum,
7478 : "Simulation");
7479 : }
7480 : // Precompute whether CTF temperature limits will be needed
7481 107 : state.dataHeatBalSurf->Zone_has_mixed_HT_models.resize(state.dataGlobal->NumOfZones + 1, false);
7482 235 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
7483 274 : for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
7484 146 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
7485 901 : for (int iSurf = thisSpace.HTSurfaceFirst, eSurf = thisSpace.HTSurfaceLast; iSurf <= eSurf; ++iSurf) {
7486 758 : DataSurfaces::HeatTransferModel const alg = state.dataSurface->Surface(iSurf).HeatTransferAlgorithm;
7487 758 : if ((alg == DataSurfaces::HeatTransferModel::CondFD) || (alg == DataSurfaces::HeatTransferModel::HAMT) ||
7488 : (alg == DataSurfaces::HeatTransferModel::Kiva)) {
7489 3 : state.dataHeatBalSurf->Zone_has_mixed_HT_models[iZone] = true;
7490 3 : break;
7491 : }
7492 : }
7493 : }
7494 : }
7495 107 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime = false;
7496 : }
7497 :
7498 249963 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag) {
7499 483 : state.dataHeatBalSurf->SurfTempInsOld = 23.0;
7500 483 : state.dataHeatBalSurfMgr->RefAirTemp = 23.0;
7501 483 : state.dataHeatBal->SurfTempEffBulkAir = 23.0;
7502 483 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount = 0;
7503 483 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = false;
7504 :
7505 : // Initialize Kiva instances ground temperatures
7506 483 : if (state.dataHeatBal->AnyKiva) {
7507 0 : state.dataSurfaceGeometry->kivaManager.initKivaInstances(state);
7508 : }
7509 : }
7510 249963 : if (!state.dataGlobal->BeginEnvrnFlag) {
7511 249480 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = true;
7512 : }
7513 :
7514 249963 : sumSurfQdotRadHVAC(state);
7515 :
7516 : // Pass correct list of surfaces to CalcHeatBalanceInsideSurf2
7517 249963 : bool const PartialResimulate(present(ZoneToResimulate));
7518 :
7519 249963 : if (!PartialResimulate) {
7520 249955 : if (state.dataHeatBal->AllCTF) {
7521 200983 : CalcHeatBalanceInsideSurf2CTFOnly(state, 1, state.dataGlobal->NumOfZones, state.dataSurface->AllIZSurfaceList);
7522 : } else {
7523 97944 : CalcHeatBalanceInsideSurf2(state,
7524 48972 : state.dataSurface->AllHTSurfaceList,
7525 48972 : state.dataSurface->AllIZSurfaceList,
7526 48972 : state.dataSurface->AllHTNonWindowSurfaceList,
7527 48972 : state.dataSurface->AllHTWindowSurfaceList);
7528 : }
7529 : } else {
7530 8 : auto const &zoneHTSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTSurfaceList;
7531 8 : auto const &zoneIZSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneIZSurfaceList;
7532 8 : auto const &zoneHTNonWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTNonWindowSurfaceList;
7533 8 : auto const &zoneHTWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTWindowSurfaceList;
7534 : // Cannot use CalcHeatBalanceInsideSurf2CTFOnly because resimulated zone includes adjacent interzone surfaces
7535 8 : CalcHeatBalanceInsideSurf2(state, zoneHTSurfList, zoneIZSurfList, zoneHTNonWindowSurfList, zoneHTWindowSurfList, ZoneToResimulate);
7536 : }
7537 249963 : CalculateZoneMRT(state, ZoneToResimulate); // Update here so that the proper value of MRT is available to radiant systems
7538 249963 : UpdateIntermediateSurfaceHeatBalanceResults(state, ZoneToResimulate);
7539 249963 : }
7540 :
7541 48980 : void CalcHeatBalanceInsideSurf2(EnergyPlusData &state,
7542 : const std::vector<int> &HTSurfs, // Heat transfer surfaces to simulate (opaque and windows)
7543 : const std::vector<int> &IZSurfs, // Interzone heat transfer surfaces to simulate
7544 : const std::vector<int> &HTNonWindowSurfs, // Non-window heat transfer surfaces to simulate
7545 : const std::vector<int> &HTWindowSurfs, // Window heat transfer surfaces to simulate
7546 : ObjexxFCL::Optional_int_const ZoneToResimulate)
7547 : {
7548 : // SUBROUTINE INFORMATION:
7549 : // AUTHOR George Walton
7550 : // DATE WRITTEN December 1979
7551 : // MODIFIED Jun 1990 (RDT for new CTF arrays)
7552 : // Dec 1999 (FCW for window calculation)
7553 : // May 2000 (FCW for window frame and dividers)
7554 : // Aug 2000 (RJL for MTF moisture calculations)
7555 : // Sep 2000 (RKS for new radiant exchange algorithm)
7556 : // Dec 2000 (RKS for radiant system model addition)
7557 : // Jul 2003 (CC) set the reference temperatures for inside surface heat balance
7558 : // depending on convection algorithms and/or air models used
7559 : // May 2006 (RR account for exterior window screen)
7560 : // Jul 2008 (P. Biddulph include calls to HAMT)
7561 : // Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
7562 : // RE-ENGINEERED Mar 1998 (RKS)
7563 :
7564 : // PURPOSE OF THIS SUBROUTINE:
7565 : // This subroutine performs a heat balance on the inside face of each
7566 : // surface in the building.
7567 :
7568 : // METHODOLOGY EMPLOYED:
7569 : // Various boundary conditions are set and additional parameters are set-
7570 : // up. Then, the proper heat balance equation is selected based on whether
7571 : // the surface is a partition or not and on whether or not movable
7572 : // insulation is present on the inside face.
7573 :
7574 : // REFERENCES:
7575 : // (I)BLAST legacy routine HBSRF
7576 :
7577 48980 : constexpr std::string_view rhoAirZone("RhoAirZone");
7578 48980 : constexpr std::string_view wsurf("Wsurf");
7579 48980 : constexpr std::string_view HBSurfManInsideSurf("HB,SurfMan:InsideSurf");
7580 48980 : constexpr std::string_view Inside("Inside");
7581 :
7582 : Real64 TempSurfOutTmp; // Local Temporary Surface temperature for the outside surface face
7583 : Real64 SurfTempInSat; // Local temporary surface dew point temperature
7584 :
7585 : Real64 Wsurf; // Moisture ratio for HAMT
7586 : Real64 RhoAirZone; // Zone moisture density for HAMT
7587 : int OtherSideZoneNum; // Zone Number index for other side of an interzone partition HAMT
7588 :
7589 48980 : auto &s_mat = state.dataMaterial;
7590 : // determine reference air temperatures
7591 342844 : for (int SurfNum : HTSurfs) {
7592 :
7593 : // These conditions are not used in every SurfNum loop here so we don't use them to skip surfaces
7594 293864 : if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome)
7595 0 : continue; // Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.
7596 293864 : Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum);
7597 293864 : state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) = RefAirTemp;
7598 293864 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataHeatBalSurfMgr->RefAirTemp(SurfNum);
7599 : }
7600 :
7601 : // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
7602 : // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
7603 : // CalcWindowHeatBalance.
7604 : // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
7605 48980 : for (int surfNum : HTWindowSurfs) {
7606 0 : state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
7607 0 : state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
7608 0 : state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
7609 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
7610 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
7611 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
7612 0 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
7613 0 : state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
7614 0 : state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
7615 0 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
7616 0 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
7617 0 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
7618 0 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
7619 : }
7620 :
7621 48980 : state.dataHeatBal->InsideSurfIterations = 0;
7622 :
7623 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
7624 48980 : for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
7625 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
7626 0 : state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
7627 : }
7628 :
7629 : // Calculate Kiva instances
7630 48980 : if (state.dataHeatBal->AnyKiva) {
7631 0 : if (((state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::HOURLY &&
7632 0 : state.dataGlobal->TimeStep == 1) ||
7633 0 : state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::TIMESTEP) &&
7634 0 : !state.dataGlobal->WarmupFlag) {
7635 0 : state.dataSurfaceGeometry->kivaManager.calcKivaInstances(state);
7636 : }
7637 : }
7638 :
7639 48980 : bool Converged = false; // .TRUE. if inside heat balance has converged
7640 148861 : while (!Converged) { // Start of main inside heat balance DO loop...
7641 :
7642 99881 : state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
7643 :
7644 99881 : if (state.dataHeatBal->AnyKiva) {
7645 0 : for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
7646 0 : state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = kivaSurf.second.results.Trad - Constant::Kelvin;
7647 : }
7648 : }
7649 :
7650 199762 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
7651 99881 : state.dataHeatBalSurf->SurfTempIn,
7652 99881 : state.dataHeatBal->InsideSurfIterations,
7653 99881 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
7654 : ZoneToResimulate,
7655 : Inside); // Update the radiation balance
7656 :
7657 99881 : if (state.dataHeatBal->AnyKiva) {
7658 0 : for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
7659 0 : state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = state.dataHeatBalSurf->SurfTempInsOld(kivaSurf.first);
7660 : }
7661 : }
7662 :
7663 : // Every 30 iterations, recalculate the inside convection coefficients in case
7664 : // there has been a significant drift in the surface temperatures predicted.
7665 : // This is not fool-proof and it basically means that the outside surface
7666 : // heat balance is in error (potentially) once HConvIn is re-evaluated.
7667 : // The choice of 30 is not significant--just want to do this a couple of
7668 : // times before the iteration limit is hit.
7669 150782 : if ((state.dataHeatBal->InsideSurfIterations > 0) &&
7670 50901 : (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
7671 16 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
7672 : }
7673 :
7674 99881 : if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
7675 0 : for (int SurfNum : HTSurfs) {
7676 0 : auto const &surface = state.dataSurface->Surface(SurfNum);
7677 0 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)
7678 0 : continue; // Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.
7679 :
7680 : // Calculate the inside surface moisture quantities
7681 : // calculate the inside surface moisture transfer conditions
7682 : // check for saturation conditions of air
7683 0 : if ((surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) ||
7684 0 : (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)) {
7685 0 : int ZoneNum = surface.Zone;
7686 0 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
7687 0 : Real64 const ZoneAirHumRat_zone(max(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRat, 1.0e-5));
7688 0 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
7689 :
7690 0 : state.dataMstBal->RhoVaporAirIn(SurfNum) =
7691 0 : min(Psychrometrics::PsyRhovFnTdbWPb_fast(MAT_zone, ZoneAirHumRat_zone, state.dataEnvrn->OutBaroPress),
7692 : Psychrometrics::PsyRhovFnTdbRh(state, MAT_zone, 1.0, HBSurfManInsideSurf));
7693 0 : state.dataMstBal->HMassConvInFD(SurfNum) =
7694 0 : HConvIn_surf / (Psychrometrics::PsyRhoAirFnPbTdbW_fast(state, state.dataEnvrn->OutBaroPress, MAT_zone, ZoneAirHumRat_zone) *
7695 0 : Psychrometrics::PsyCpAirFnW_fast(ZoneAirHumRat_zone));
7696 : }
7697 : }
7698 : }
7699 :
7700 699129 : for (int SurfNum : HTNonWindowSurfs) {
7701 : // Perform heat balance on the inside face of the surface ...
7702 : // The following are possibilities here:
7703 : // (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
7704 : // (b) the surface is a partition, in which case the temperature of both sides are the same
7705 : // (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
7706 : // (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
7707 : // (e) standard opaque surface with movable insulation, special two-part equation
7708 : // In the surface calculation there are the following Algorithm types for opaque surfaces that
7709 : // do not have movable insulation:
7710 : // (a) the regular CTF calc (SolutionAlgo = UseCTF)
7711 : // (b) the EMPD calc (Solutionalgo = UseEMPD)
7712 : // (c) the CondFD calc (SolutionAlgo = UseCondFD)
7713 : // (d) the HAMT calc (solutionalgo = UseHAMT).
7714 :
7715 599248 : auto const &surface = state.dataSurface->Surface(SurfNum);
7716 599248 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
7717 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
7718 0 : if (SurfNum != repSurfNum) continue;
7719 : }
7720 599248 : int const ZoneNum = surface.Zone;
7721 599248 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7722 599248 : int const ConstrNum = surface.Construction;
7723 599248 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
7724 599248 : Real64 const MAT_zone = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
7725 599248 : Real64 const HConvIn_surf = state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
7726 :
7727 599248 : if (surface.ExtBoundCond == SurfNum) {
7728 : // CR6869 -- let Window HB take care of it IF (Surface(SurfNum)%ExtBoundCond == SurfNum) THEN
7729 : // Surface is adiabatic
7730 99862 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7731 99862 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
7732 :
7733 0 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7734 0 : MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
7735 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
7736 : }
7737 : // Pre-calculate a few terms
7738 : Real64 const TempTerm(
7739 0 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
7740 0 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
7741 0 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
7742 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
7743 0 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
7744 0 : Real64 const TempDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
7745 : // Calculate the current inside surface temperature
7746 0 : if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
7747 0 : ((state.dataSurface->SurfIsPool(SurfNum)) &&
7748 0 : (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
7749 0 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
7750 0 : if (construct.SourceSinkPresent) {
7751 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7752 0 : (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
7753 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
7754 : TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
7755 : // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
7756 : // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
7757 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
7758 : // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
7759 : // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
7760 : // same temp) | Convection and damping term | Radiation from AFN ducts
7761 : } else {
7762 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7763 0 : (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
7764 : TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
7765 : // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
7766 : // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
7767 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
7768 : // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
7769 : // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
7770 : // same temp) | Convection and damping term | Radiation from AFN ducts
7771 : }
7772 : } else { // this is a pool and it has been simulated this time step
7773 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7774 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
7775 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) /
7776 0 : (construct.CTFInside[0] - construct.CTFCross[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
7777 : DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms (see
7778 : // non-pool equation for details) | Iterative damping term (for stability) |
7779 : // Conduction term (both partition sides same temp) | Pool and damping term
7780 : }
7781 0 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7782 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
7783 0 : state.dataMstBalEMPD->HeatFluxLatent(SurfNum) * TempDiv; // Conduction term (both partition sides same temp) |
7784 : // Conduction term (both partition sides same temp) |
7785 : // Convection and damping term
7786 0 : if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
7787 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
7788 : }
7789 : }
7790 : // if any mixed heat transfer models in zone, apply limits to CTF result
7791 0 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum])
7792 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7793 0 : max(DataHeatBalSurface::MinSurfaceTempLimit,
7794 0 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
7795 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
7796 :
7797 0 : if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
7798 :
7799 : // Radiant system does not need the damping coefficient terms (hopefully) // Partitions are assumed to be symmetric
7800 0 : Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf));
7801 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
7802 0 : TempTerm * RadSysDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW
7803 : // radiation from internal sources | Convection from surface to zone air | Radiant flux from
7804 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant
7805 : // flux from a steam baseboard heater | Radiant flux from an electric baseboard heater | Net
7806 : // radiant exchange with other zone surfaces | Cond term (both partition sides same temp) | Cond
7807 : // term (both partition sides same temp) | Convection and damping term
7808 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
7809 : 0.0; // The outside temp is assumed to be equal to the inside temp for a partition
7810 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
7811 0 : construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both partition sides same temp) | Cond
7812 : // term (both partition sides same temp) | Convection and damping term
7813 : }
7814 :
7815 99862 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7816 0 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7817 :
7818 99862 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)
7819 0 : HeatBalanceHAMTManager::ManageHeatBalHAMT(state,
7820 : SurfNum,
7821 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
7822 : TempSurfOutTmp); // HAMT
7823 :
7824 99862 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7825 199724 : HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
7826 99862 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
7827 : }
7828 :
7829 99862 : TH11 = TempSurfOutTmp;
7830 : }
7831 :
7832 99862 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
7833 :
7834 : } else { // Standard surface or interzone surface
7835 499386 : bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataSurface->intMovInsuls(SurfNum).present;
7836 499386 : if (!movableInsulPresent) { // No movable insulation present, normal heat balance equation
7837 :
7838 499386 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7839 499310 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
7840 :
7841 76 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7842 0 : MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
7843 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
7844 : }
7845 : // Pre-calculate a few terms
7846 : Real64 const TempTerm(
7847 76 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
7848 76 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
7849 76 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
7850 76 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
7851 76 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
7852 76 : Real64 const TempDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
7853 : // Calculate the current inside surface temperature
7854 76 : if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
7855 0 : ((state.dataSurface->SurfIsPool(SurfNum)) &&
7856 0 : (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
7857 0 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
7858 76 : if (construct.SourceSinkPresent) {
7859 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7860 0 : (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
7861 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
7862 0 : construct.CTFCross[0] * TH11) *
7863 : TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
7864 : // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
7865 : // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
7866 : // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
7867 : // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
7868 : // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
7869 : // outside surface | Coefficient for conduction (current time) | Convection and damping term |
7870 : // Radiation from AFN ducts
7871 : } else {
7872 76 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7873 76 : (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
7874 76 : construct.CTFCross[0] * TH11) *
7875 : TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
7876 : // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
7877 : // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
7878 : // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
7879 : // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
7880 : // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
7881 : // outside surface | Coefficient for conduction (current time) | Convection and damping term |
7882 : // Radiation from AFN ducts
7883 : }
7884 : } else { // surface is a pool and the pool has been simulated this time step
7885 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7886 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
7887 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) /
7888 0 : (construct.CTFInside[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
7889 : DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms
7890 : // (see non-pool equation for details) | Iterative damping term (for
7891 : // stability) | Current conduction from | the outside surface |
7892 : // Coefficient for conduction (current time) | Pool and damping term
7893 : }
7894 76 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7895 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
7896 0 : state.dataMstBalEMPD->HeatFluxLatent(SurfNum) *
7897 : TempDiv; // Coefficient for conduction (current time) | Convection and damping term
7898 0 : if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
7899 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
7900 : }
7901 : }
7902 : // if any mixed heat transfer models in zone, apply limits to CTF result
7903 76 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum])
7904 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = max(
7905 : DataHeatBalSurface::MinSurfaceTempLimit,
7906 0 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
7907 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
7908 :
7909 76 : if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
7910 :
7911 : // Radiant system does not need the damping coefficient terms (hopefully)
7912 0 : Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf));
7913 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
7914 0 : TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
7915 : // radiation from internal sources | Convection from surface to zone air | Radiant flux
7916 : // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
7917 : // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
7918 : // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
7919 : // sides same temp) | Convection and damping term
7920 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
7921 0 : construct.CTFCross[0] * RadSysDiv; // Outside temp=inside temp for a partition |
7922 : // Cond term (both partition sides same temp) |
7923 : // Convection and damping term
7924 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
7925 0 : construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both
7926 : // partition sides same temp) | Convection and
7927 : // damping term
7928 :
7929 0 : if (surface.ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
7930 : // The inside coefficients of one side are equal to the outside coefficients of the other side. But,
7931 : // the inside coefficients are set up once the heat balance equation for that side has been calculated.
7932 : // For both sides to actually have been set, we have to wait until we get to the second side in the surface
7933 : // derived type. At that point, both inside coefficient sets have been evaluated.
7934 0 : if (surface.ExtBoundCond < SurfNum) { // Both of the inside coefficients have now been set
7935 0 : int OtherSideSurfNum = surface.ExtBoundCond;
7936 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
7937 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
7938 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
7939 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
7940 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
7941 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
7942 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
7943 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
7944 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) =
7945 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
7946 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) =
7947 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
7948 : }
7949 : }
7950 : }
7951 :
7952 499386 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7953 0 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7954 :
7955 499310 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7956 0 : if (surface.ExtBoundCond > 0) {
7957 : // HAMT get the correct other side zone zone air temperature --
7958 0 : int OtherSideSurfNum = surface.ExtBoundCond;
7959 : // ZoneNum = surface.Zone;
7960 0 : OtherSideZoneNum = state.dataSurface->Surface(OtherSideSurfNum).Zone;
7961 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7962 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(OtherSideZoneNum).MAT;
7963 : }
7964 0 : HeatBalanceHAMTManager::ManageHeatBalHAMT(state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
7965 : }
7966 :
7967 499310 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD)
7968 998620 : HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
7969 499310 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
7970 :
7971 499310 : TH11 = TempSurfOutTmp;
7972 :
7973 499310 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) {
7974 : // Read Kiva results for each surface
7975 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7976 0 : state.dataSurfaceGeometry->kivaManager.surfaceMap[SurfNum].results.Tconv - Constant::Kelvin;
7977 :
7978 0 : TH11 = 0.0;
7979 : }
7980 :
7981 499386 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
7982 :
7983 : } else { // Movable insulation present
7984 0 : Real64 HMovInsul = state.dataSurface->intMovInsuls(SurfNum).H;
7985 0 : if (construct.SourceSinkPresent) {
7986 :
7987 0 : ShowSevereError(state, "Interior movable insulation is not valid with embedded sources/sinks");
7988 0 : ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
7989 0 : ShowContinueError(state,
7990 0 : format("interior movable insulation {} for a surface with that construction.",
7991 0 : s_mat->materials(state.dataSurface->intMovInsuls(SurfNum).matNum)->Name));
7992 0 : ShowContinueError(state,
7993 : "This is not currently allowed because the heat balance equations do not currently accommodate "
7994 : "this combination.");
7995 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
7996 : }
7997 :
7998 0 : Real64 F1 = HMovInsul / (HMovInsul + HConvIn_surf + DataHeatBalSurface::IterDampConst);
7999 :
8000 0 : state.dataHeatBalSurf->SurfTempIn(SurfNum) =
8001 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
8002 0 : construct.CTFCross[0] * TH11 +
8003 0 : F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
8004 0 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
8005 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
8006 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
8007 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum))) /
8008 0 : (construct.CTFInside[0] + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
8009 :
8010 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8011 0 : (construct.CTFInside[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
8012 0 : HMovInsul * state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) -
8013 0 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) - construct.CTFCross[0] * TH11) /
8014 : (HMovInsul);
8015 : // if any mixed heat transfer models in zone, apply limits to CTF result
8016 0 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum])
8017 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8018 0 : max(DataHeatBalSurface::MinSurfaceTempLimit,
8019 0 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
8020 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
8021 : }
8022 : }
8023 : }
8024 99881 : for (int SurfNum : HTWindowSurfs) {
8025 0 : auto &surface = state.dataSurface->Surface(SurfNum);
8026 0 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8027 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8028 0 : if (SurfNum != repSurfNum) continue;
8029 : }
8030 0 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
8031 0 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // Not const, because storm window may change this
8032 0 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8033 0 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8034 : // Lookup up the TDD:DOME object
8035 0 : int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
8036 0 : int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
8037 : // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
8038 0 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
8039 :
8040 : // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
8041 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
8042 : // = SurfWinQRadSWwinAbs(SurfNum,1)/2.0
8043 0 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
8044 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8045 0 : (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
8046 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) + HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
8047 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
8048 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
8049 0 : Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
8050 0 : (Ueff + HConvIn_surf +
8051 : DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
8052 : // solar | Convection from surface to zone air | Net radiant exchange with
8053 : // other zone surfaces | Iterative damping term (for stability) | Current
8054 : // conduction from the outside surface | Coefficient for conduction (current
8055 : // time) | Convection and damping term
8056 0 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8057 :
8058 0 : Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(SurfNum) + Constant::Kelvin));
8059 :
8060 : // fill out report vars for components of Window Heat Gain
8061 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) =
8062 0 : HConvIn_surf * surface.Area * (state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(SurfNum));
8063 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
8064 0 : state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
8065 0 : (Sigma_Temp_4 - (state.dataSurface->SurfWinIRfromParentZone(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)));
8066 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) =
8067 0 : state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
8068 0 : (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
8069 0 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum);
8070 :
8071 : // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
8072 0 : state.dataSurface->SurfWinHeatGain(SurfNum) =
8073 0 : state.dataSurface->SurfWinTransSolar(SurfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) +
8074 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) -
8075 0 : surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum);
8076 : // Net transmitted solar | Convection | IR exchange | IR
8077 : // Zone diffuse interior shortwave reflected back into the TDD
8078 :
8079 : } else { // Regular window
8080 0 : if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
8081 : // Get outside convection coeff for exterior window here to avoid calling
8082 : // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
8083 : // (HeatBalanceSurfaceManager USEing and WindowManager and
8084 : // WindowManager USEing HeatBalanceSurfaceManager)
8085 0 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
8086 0 : auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
8087 0 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
8088 0 : Real64 EmisOut = thisMaterial->AbsorpThermalFront; // Glass outside surface emissivity
8089 0 : DataSurfaces::WinShadingType const shading_flag(state.dataSurface->SurfWinShadingFlag(SurfNum));
8090 0 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
8091 : // Exterior shade in place
8092 0 : int const ConstrNumSh = surface.activeShadedConstruction;
8093 0 : if (ConstrNumSh != 0) {
8094 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
8095 0 : auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
8096 0 : assert(thisMaterial2 != nullptr);
8097 0 : RoughSurf = thisMaterial2->Roughness;
8098 0 : EmisOut = thisMaterial2->AbsorpThermal;
8099 : }
8100 : }
8101 :
8102 : // Get the outside effective emissivity for Equivalent layer model
8103 0 : if (construct.WindowTypeEQL) {
8104 0 : EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
8105 : }
8106 : // Set Exterior Convection Coefficient...
8107 0 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
8108 :
8109 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
8110 :
8111 0 : } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
8112 :
8113 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
8114 : // subroutine)
8115 0 : Convect::InitExtConvCoeff(state,
8116 : SurfNum,
8117 : 0.0,
8118 : RoughSurf,
8119 : EmisOut,
8120 : TH11,
8121 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
8122 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
8123 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
8124 0 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
8125 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
8126 :
8127 0 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
8128 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0; // Reset SurfHcExt because of wetness
8129 : }
8130 :
8131 : } else { // Not Wind exposed
8132 :
8133 : // Calculate exterior heat transfer coefficients for windspeed = 0
8134 0 : Convect::InitExtConvCoeff(state,
8135 : SurfNum,
8136 : 0.0,
8137 : RoughSurf,
8138 : EmisOut,
8139 : TH11,
8140 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
8141 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
8142 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
8143 0 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
8144 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
8145 : }
8146 : } else { // Interior Surface
8147 :
8148 0 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
8149 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
8150 : } else {
8151 : // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
8152 : // same
8153 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
8154 : }
8155 : }
8156 :
8157 : // Following call determines inside surface temperature of glazing, and of
8158 : // frame and/or divider, if present
8159 0 : Window::CalcWindowHeatBalance(
8160 0 : state, SurfNum, state.dataHeatBalSurf->SurfHConvExt(SurfNum), state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TH11);
8161 0 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8162 : }
8163 : }
8164 : } // ...end of inside surface heat balance equation selection
8165 :
8166 699129 : for (int SurfNum : HTSurfs) {
8167 599248 : int const ZoneNum = state.dataSurface->Surface(SurfNum).Zone;
8168 599248 : auto &zone = state.dataHeatBal->Zone(ZoneNum);
8169 599248 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
8170 599248 : Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
8171 599248 : TH12 = state.dataHeatBalSurf->SurfTempIn(SurfNum);
8172 599248 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = TH11; // For reporting
8173 599248 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Dome) continue;
8174 599248 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8175 : // Tubular daylighting devices are treated as one big object with an effective R value.
8176 : // The outside face temperature of the TDD:DOME and the inside face temperature of the
8177 : // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
8178 : // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
8179 : // and the outside face of the TDD:DIFFUSER for reporting.
8180 :
8181 : // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
8182 0 : int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
8183 0 : state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
8184 0 : state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
8185 :
8186 : // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
8187 : // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
8188 0 : TH11 = state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
8189 0 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
8190 : }
8191 :
8192 599248 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
8193 0 : TestSurfTempCalcHeatBalanceInsideSurf(state, TH12, SurfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
8194 : }
8195 :
8196 : } // ...end of main loops over all surfaces for inside heat balances
8197 :
8198 : // Interzone surface updating: interzone surfaces have other side temperatures
8199 : // which can vary as the simulation iterates through the inside heat
8200 : // balance. This block is intended to "lock" the opposite side (outside)
8201 : // temperatures to the correct value, namely the value calculated by the
8202 : // inside surface heat balance for the other side.
8203 : // assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
8204 : // int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
8205 99881 : for (int SurfNum : IZSurfs) {
8206 0 : int const surfExtBoundCond = state.dataSurface->Surface(SurfNum).ExtBoundCond;
8207 : // Set the outside surface temperature to the inside surface temperature of the interzone pair.
8208 : // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
8209 : // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
8210 : // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
8211 0 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
8212 0 : state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
8213 : }
8214 :
8215 99881 : ++state.dataHeatBal->InsideSurfIterations;
8216 :
8217 : // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
8218 99881 : Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
8219 699129 : for (int SurfNum : HTNonWindowSurfs) {
8220 599248 : MaxDelTemp = max(std::abs(state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfTempInsOld(SurfNum)), MaxDelTemp);
8221 599248 : if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
8222 : // also check all internal nodes as well as surface faces
8223 599172 : MaxDelTemp = max(MaxDelTemp, state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).MaxNodeDelTemp);
8224 : }
8225 : } // ...end of loop to check for convergence
8226 :
8227 99881 : if (!state.dataHeatBal->AnyCondFD) {
8228 19 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) Converged = true;
8229 : } else {
8230 99862 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTempCondFD) Converged = true;
8231 :
8232 : // resets relaxation factor to speed up iterations when under-relaxation is not needed.
8233 99862 : if (state.dataHeatBal->InsideSurfIterations <= 1) {
8234 48972 : state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
8235 : }
8236 99862 : if ((state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::IterationsForCondFDRelaxChange) && !Converged) {
8237 : // adjust relaxation factor down, assume large number of iterations is result of instability
8238 492 : state.dataHeatBal->CondFDRelaxFactor *= 0.9;
8239 492 : if (state.dataHeatBal->CondFDRelaxFactor < 0.1) state.dataHeatBal->CondFDRelaxFactor = 0.1;
8240 : }
8241 : }
8242 :
8243 : #ifdef EP_Count_Calls
8244 : state.dataTimingsData->NumMaxInsideSurfIterations =
8245 : max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
8246 : #endif
8247 :
8248 99881 : if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) Converged = false;
8249 :
8250 99881 : if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
8251 0 : if (!state.dataGlobal->WarmupFlag) {
8252 0 : ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
8253 0 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
8254 0 : if (!state.dataHeatBal->AnyCondFD) {
8255 0 : ShowWarningError(state,
8256 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
8257 : "Allowed Temp Diff [C] ={:.3R}",
8258 : MaxDelTemp,
8259 0 : state.dataHeatBal->MaxAllowedDelTemp));
8260 0 : ShowContinueErrorTimeStamp(state, "");
8261 : } else {
8262 0 : ShowWarningError(state,
8263 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
8264 : "Allowed Temp Diff [C] ={:.6R}",
8265 : MaxDelTemp,
8266 0 : state.dataHeatBal->MaxAllowedDelTempCondFD));
8267 0 : ShowContinueErrorTimeStamp(state, "");
8268 : }
8269 : } else {
8270 0 : ShowRecurringWarningErrorAtEnd(state,
8271 : "Inside surface heat balance convergence problem continues",
8272 0 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
8273 : MaxDelTemp,
8274 : MaxDelTemp,
8275 : _,
8276 : "[C]",
8277 : "[C]");
8278 : }
8279 : }
8280 0 : break; // iteration loop
8281 : }
8282 :
8283 : } // ...end of main inside heat balance DO loop (ends when Converged)
8284 :
8285 : // Update SumHmXXXX for non-window EMPD or HAMT surfaces
8286 48980 : if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
8287 :
8288 : // these SumHmA* variables are only used for EMPD and HAMT and should be reset each time step (and every iteration)
8289 0 : for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
8290 0 : thisZoneHB.SumHmAW = 0.0;
8291 0 : thisZoneHB.SumHmARa = 0.0;
8292 0 : thisZoneHB.SumHmARaW = 0.0;
8293 : }
8294 :
8295 0 : for (int SurfNum : HTNonWindowSurfs) {
8296 0 : auto const &surface = state.dataSurface->Surface(SurfNum);
8297 0 : int ZoneNum = surface.Zone;
8298 0 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
8299 :
8300 0 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8301 0 : HeatBalanceHAMTManager::UpdateHeatBalHAMT(state, SurfNum);
8302 :
8303 0 : Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
8304 :
8305 0 : thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
8306 :
8307 0 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).MAT);
8308 0 : RhoAirZone = Psychrometrics::PsyRhoAirFnPbTdbW(
8309 : state,
8310 0 : state.dataEnvrn->OutBaroPress,
8311 : MAT_zone,
8312 0 : Psychrometrics::PsyWFnTdbRhPb(
8313 : state,
8314 : MAT_zone,
8315 0 : Psychrometrics::PsyRhFnTdbRhov(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum), rhoAirZone),
8316 0 : state.dataEnvrn->OutBaroPress));
8317 :
8318 0 : Real64 const surfInTemp(state.dataHeatBalSurf->SurfTempInTmp(SurfNum));
8319 : Wsurf =
8320 0 : Psychrometrics::PsyWFnTdbRhPb(state,
8321 : surfInTemp,
8322 0 : Psychrometrics::PsyRhFnTdbRhov(state, surfInTemp, state.dataMstBal->RhoVaporSurfIn(SurfNum), wsurf),
8323 0 : state.dataEnvrn->OutBaroPress);
8324 :
8325 0 : thisZoneHB.SumHmARa += FD_Area_fac * RhoAirZone;
8326 :
8327 0 : thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); // old eq'n: FD_Area_fac * RhoAirZone * Wsurf;
8328 :
8329 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
8330 : // need to calculate the amount of moisture that is entering or
8331 : // leaving the zone Qm [kg/sec] = hmi * Area * (Del Rhov)
8332 : // {Hmi [m/sec]; Area [m2]; Rhov [kg moist/m3] }
8333 : // Positive values are into the zone and negative values are
8334 : // leaving the zone. SumHmAw is the sum of the moisture entering or
8335 : // leaving the zone from all of the surfaces and is a rate. Multiply
8336 : // by time to get the actual amount affecting the zone volume of air.
8337 :
8338 0 : MoistureBalanceEMPDManager::UpdateMoistureBalanceEMPD(state, SurfNum);
8339 0 : state.dataMstBal->RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum);
8340 0 : Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
8341 0 : thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
8342 0 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
8343 0 : thisZoneHB.SumHmARa +=
8344 0 : FD_Area_fac *
8345 0 : Psychrometrics::PsyRhoAirFnPbTdbW(
8346 : state,
8347 0 : state.dataEnvrn->OutBaroPress,
8348 : MAT_zone,
8349 0 : Psychrometrics::PsyWFnTdbRhPb(state,
8350 : MAT_zone,
8351 0 : Psychrometrics::PsyRhFnTdbRhovLBnd0C(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum)),
8352 0 : state.dataEnvrn->OutBaroPress)); // surfInTemp, PsyWFnTdbRhPb( surfInTemp, PsyRhFnTdbRhovLBnd0C(
8353 : // surfInTemp, RhoVaporAirIn( SurfNum ) ), OutBaroPress ) );
8354 0 : thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum);
8355 : }
8356 : }
8357 : }
8358 48980 : }
8359 :
8360 200983 : void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state,
8361 : const int FirstZone, // First zone to simulate
8362 : const int LastZone, // Last zone to simulate
8363 : const std::vector<int> &IZSurfs, // Last zone to simulate
8364 : ObjexxFCL::Optional_int_const ZoneToResimulate)
8365 : {
8366 :
8367 : // This function performs a heat balance on the inside face of each
8368 : // surface in the building. It is a copy of CalcHeatBalanceInsideSurf,
8369 : // simplified for CTF surfaces only.
8370 :
8371 : // REFERENCES:
8372 : // (I)BLAST legacy routine HBSRF
8373 :
8374 200983 : auto &s_mat = state.dataMaterial;
8375 200983 : auto &Surface = state.dataSurface->Surface;
8376 :
8377 200983 : constexpr std::string_view Inside("Inside");
8378 :
8379 200983 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime) {
8380 : // Set up coefficient arrays that never change - loop over non-window HT surfaces
8381 231 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8382 270 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8383 144 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8384 144 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8385 144 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8386 854 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8387 710 : int const ConstrNum = Surface(surfNum).Construction;
8388 710 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8389 710 : if (Surface(surfNum).ExtBoundCond == surfNum) {
8390 143 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 1;
8391 : } else {
8392 567 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 0;
8393 : }
8394 710 : if (construct.SourceSinkPresent) {
8395 0 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 1;
8396 : } else {
8397 710 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 0;
8398 : }
8399 : }
8400 : }
8401 : }
8402 :
8403 105 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime = false;
8404 : }
8405 :
8406 488661 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8407 611667 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8408 323989 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8409 : // loop over all heat transfer surface except TDD Dome.
8410 323989 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
8411 323989 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
8412 : // determine reference air temperatures and other variable terms - loop over all surfaces
8413 2104462 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8414 1780473 : auto const &surface = Surface(surfNum);
8415 1780473 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8416 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8417 0 : if (surfNum != repSurfNum) continue;
8418 : }
8419 :
8420 1780473 : int const ConstrNum = Surface(surfNum).Construction;
8421 1780473 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8422 1780473 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) = construct.CTFCross[0];
8423 1780473 : state.dataHeatBalSurf->SurfCTFInside0(surfNum) = construct.CTFInside[0];
8424 1780473 : state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) = construct.CTFSourceIn[0];
8425 1780473 : state.dataHeatBalSurf->SurfTempOutHist(surfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
8426 1780473 : if (construct.SourceSinkPresent) {
8427 0 : state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) = state.dataHeatBalSurf->SurfQsrcHist(surfNum, 1);
8428 : }
8429 :
8430 : // The special heat balance terms for pools are used only when the pool is operating, so IsPool can change
8431 1780473 : if (state.dataSurface->SurfIsPool(surfNum)) {
8432 0 : if ((std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit) ||
8433 0 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit)) {
8434 0 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 1;
8435 : } else {
8436 0 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 0;
8437 : }
8438 : }
8439 1780473 : Real64 RefAirTemp = state.dataSurface->Surface(surfNum).getInsideAirTemperature(state, surfNum);
8440 1780473 : state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = RefAirTemp;
8441 1780473 : state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(surfNum);
8442 : }
8443 :
8444 : // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
8445 : // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
8446 : // CalcWindowHeatBalance.
8447 : // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
8448 323989 : int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
8449 323989 : int const lastWindowSurf = thisSpace.WindowSurfaceLast;
8450 412551 : for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
8451 88562 : state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
8452 88562 : state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
8453 88562 : state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
8454 88562 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
8455 88562 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
8456 88562 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
8457 88562 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
8458 88562 : state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
8459 88562 : state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
8460 88562 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
8461 88562 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
8462 88562 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
8463 88562 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
8464 : }
8465 :
8466 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
8467 323990 : for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
8468 1 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
8469 1 : state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
8470 : }
8471 :
8472 : // Set up coefficient arrays prior to calculations and precalc terms that do no change during iteration - non-window surfaces
8473 323989 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8474 323989 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8475 323989 : Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
8476 323989 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8477 : // this loop auto-vectorizes
8478 2015900 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8479 1691911 : auto const &surface = Surface(surfNum);
8480 1691911 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8481 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8482 0 : if (surfNum != repSurfNum) continue;
8483 : }
8484 :
8485 : // Pre-calculate a few terms before the iteration loop
8486 1691911 : state.dataHeatBalSurf->SurfTempTerm(surfNum) =
8487 1691911 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8488 1691911 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8489 1691911 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8490 1691911 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8491 1691911 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
8492 1691911 : state.dataHeatBalSurf->SurfTempDiv(surfNum) =
8493 1691911 : 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
8494 1691911 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
8495 1691911 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
8496 1691911 : (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant);
8497 : }
8498 : }
8499 : }
8500 :
8501 200983 : state.dataHeatBal->InsideSurfIterations = 0;
8502 200983 : bool Converged = false; // .TRUE. if inside heat balance has converged
8503 978994 : while (!Converged) { // Start of main inside heat balance iteration loop...
8504 :
8505 778011 : state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
8506 :
8507 1556022 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
8508 778011 : state.dataHeatBalSurf->SurfTempIn,
8509 778011 : state.dataHeatBal->InsideSurfIterations,
8510 778011 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
8511 : ZoneToResimulate,
8512 : Inside); // Update the radiation balance
8513 :
8514 : // Every 30 iterations, recalculate the inside convection coefficients in case
8515 : // there has been a significant drift in the surface temperatures predicted.
8516 : // This is not fool-proof and it basically means that the outside surface
8517 : // heat balance is in error (potentially) once HConvIn is re-evaluated.
8518 : // The choice of 30 is not significant--just want to do this a couple of
8519 : // times before the iteration limit is hit.
8520 1355039 : if ((state.dataHeatBal->InsideSurfIterations > 0) &&
8521 577028 : (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
8522 139 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
8523 : // Since HConvIn has changed re-calculate a few terms - non-window surfaces
8524 313 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8525 348 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8526 174 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8527 174 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8528 174 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8529 :
8530 174 : Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
8531 174 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8532 : // this loop auto-vectorizes
8533 1258 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8534 1084 : auto const &surface = Surface(surfNum);
8535 1084 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8536 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8537 0 : if (surfNum != repSurfNum) continue;
8538 : }
8539 :
8540 1084 : state.dataHeatBalSurf->SurfTempTerm(surfNum) =
8541 1084 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8542 1084 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8543 1084 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8544 1084 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8545 1084 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
8546 1084 : state.dataHeatBalSurf->SurfTempDiv(surfNum) =
8547 1084 : 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
8548 1084 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
8549 1084 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
8550 1084 : (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) +
8551 : iterDampConstant);
8552 : }
8553 : }
8554 : }
8555 : }
8556 :
8557 : // Loop over non-window surfaces
8558 1926310 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8559 2401033 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8560 1252734 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8561 1252734 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8562 1252734 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8563 1252734 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8564 : // this loop auto-vectorizes
8565 8063886 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8566 : // Perform heat balance on the inside face of the surface ...
8567 : // The following are possibilities here (this function only does CTF, see CalcHeatBalanceInsideSurf2 for others):
8568 : // (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
8569 : // (b) the surface is adiabatic (a partition), in which case the temperature of both sides are the same
8570 : // (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
8571 : // (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
8572 : // (e) standard opaque surface with movable insulation, special two-part equation
8573 : // In the surface calculation there are the following Algorithm types for opaque surfaces that
8574 : // do not have movable insulation:
8575 : // (a) the regular CTF calc (SolutionAlgo = UseCTF)
8576 : // (b) the EMPD calc (Solutionalgo = UseEMPD)
8577 : // (c) the CondFD calc (SolutionAlgo = UseCondFD)
8578 : // (d) the HAMT calc (solutionalgo = UseHAMT).
8579 :
8580 : // For adiabatic surface:
8581 : // Adiabatic: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] + HConvIn_surf + IterDampConst));
8582 : // Adiabatic: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
8583 : // Ad+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst *
8584 : // SurfTempInsOld(SurfNum)) * TempDiv; Ad+Pool: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] +
8585 : // PoolHeatTransCoefs(SurfNum) + IterDampConst); Ad+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) +
8586 : // QPoolSurfNumerator(SurfNum) + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
8587 :
8588 : // For standard or interzone surface:
8589 : // Standard: TempDiv = (1.0 / (construct.CTFInside(0) + HConvIn_surf + IterDampConst));
8590 : // Standard: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) *
8591 : // TempDiv; Std+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst
8592 : // * SurfTempInsOld(SurfNum)) * TempDiv; Std+Pool: TempDiv = (1.0 / (construct.CTFInside(0) + PoolHeatTransCoefs(SurfNum) +
8593 : // IterDampConst); Std+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + QPoolSurfNumerator(SurfNum) +
8594 : // IterDampConst* SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) * TempDiv;
8595 :
8596 : // Composite with Adiabatic/Source/Pool flags:
8597 : // TempDiv = (1.0 / (construct.CTFInside(0) - SurfIsAdiabatic*construct.CTFCross[0]+
8598 : // SurfIsOperatingPool*PoolHeatTransCoefs(SurfNum) + IsNotPoolSurf*HConvIn_surf + IterDampConst));
8599 : // SurfTempInTmp(SurfNum) = (IsNotPoolSurf*TempTerm + IsSource*construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) +
8600 : // SurfIsOperatingPool*SurfCTFConstInPart(SurfNum) + SurfIsOperatingPool*QPoolSurfNumerator(SurfNum)
8601 : // + IterDampConst * SurfTempInsOld(SurfNum)+
8602 : // IsNotAdiabatic*IsNotSource*construct.CTFCross[0]
8603 : // * TH11) * TempDiv;
8604 :
8605 : // Calculate the current inside surface temperature
8606 6811152 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8607 6811152 : ((!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) *
8608 6811152 : (state.dataHeatBalSurf->SurfTempTerm(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum)) +
8609 6811152 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) * state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) *
8610 6811152 : state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) +
8611 6811152 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) +
8612 6811152 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum) +
8613 6811152 : iterDampConstant * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
8614 6811152 : (!state.dataHeatBalSurf->SurfIsAdiabatic(surfNum)) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) *
8615 6811152 : state.dataHeatBalSurf->SurfTempOutHist(surfNum)) *
8616 6811152 : state.dataHeatBalSurf->SurfTempDiv(surfNum);
8617 : // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
8618 : // radiation from internal sources | Convection from surface to zone air | Net radiant
8619 : // exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there
8620 : // is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot
8621 : // water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from
8622 : // an electric baseboard heater | Iterative damping term (for stability) | Current
8623 : // conduction from | the outside surface | Coefficient for conduction (current time) |
8624 : // Convection and damping term | Radiation from AFN ducts
8625 :
8626 6811152 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
8627 : }
8628 :
8629 : // Loop over non-window surfaces (includes TubularDaylightingDomes)
8630 8063886 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8631 6811152 : auto &movInsul = state.dataSurface->intMovInsuls(surfNum);
8632 :
8633 6811152 : bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && movInsul.present;
8634 6811152 : if (movableInsulPresent) { // Movable insulation present, recalc surface temps
8635 0 : Real64 HMovInsul = movInsul.H;
8636 0 : Real64 F1 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvInt(surfNum) + DataHeatBalSurface::IterDampConst);
8637 0 : state.dataHeatBalSurf->SurfTempIn(surfNum) =
8638 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
8639 0 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum) +
8640 0 : F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8641 0 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8642 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8643 0 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8644 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8645 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum))) /
8646 0 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
8647 :
8648 0 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8649 0 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum) +
8650 0 : HMovInsul * state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) -
8651 0 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) -
8652 0 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum)) /
8653 : (HMovInsul);
8654 : }
8655 :
8656 6811152 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
8657 0 : if (state.dataConstruction->Construct(Surface(surfNum).Construction).SourceSinkPresent) {
8658 : // Set the appropriate parameters for the radiant system
8659 : // Radiant system does not need the damping coefficient terms (hopefully)
8660 : Real64 const RadSysDiv(1.0 /
8661 0 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + state.dataHeatBalSurf->SurfHConvInt(surfNum)));
8662 : Real64 const TempTerm(
8663 0 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8664 0 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
8665 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8666 0 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8667 0 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8668 0 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / state.dataGlobal->TimeStepZoneSec));
8669 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum) =
8670 0 : TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
8671 : // radiation from internal sources | Convection from surface to zone air | Radiant flux
8672 : // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
8673 : // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
8674 : // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
8675 : // sides same temp) | Convection and damping term
8676 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum) =
8677 0 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * RadSysDiv; // Outside temp=inside temp for a partition |
8678 : // Cond term (both partition sides same temp) |
8679 : // Convection and damping term
8680 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum) =
8681 0 : state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * RadSysDiv; // QTF term for the source | Cond term (both
8682 : // partition sides same temp) | Convection and
8683 : // damping term
8684 :
8685 0 : if (Surface(surfNum).ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
8686 : // The inside coefficients of one side are equal to the outside coefficients of the other side. But,
8687 : // the inside coefficients are set up once the heat balance equation for that side has been calculated.
8688 : // For both sides to actually have been set, we have to wait until we get to the second side in the surface
8689 : // derived type. At that point, both inside coefficient sets have been evaluated.
8690 0 : if (Surface(surfNum).ExtBoundCond <= surfNum) { // Both of the inside coefficients have now been set
8691 0 : int OtherSideSurfNum = Surface(surfNum).ExtBoundCond;
8692 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
8693 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum);
8694 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
8695 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum);
8696 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
8697 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum);
8698 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(surfNum) =
8699 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
8700 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(surfNum) =
8701 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
8702 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(surfNum) =
8703 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
8704 : }
8705 : }
8706 : }
8707 : }
8708 : }
8709 :
8710 : // Loop over window surfaces
8711 1252734 : int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
8712 1252734 : int const lastWindowSurf = thisSpace.WindowSurfaceLast;
8713 1632492 : for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
8714 379758 : auto &surface = state.dataSurface->Surface(surfNum);
8715 379758 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8716 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8717 0 : if (surfNum != repSurfNum) continue;
8718 : }
8719 379758 : Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum));
8720 379758 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(surfNum);
8721 379758 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8722 379758 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8723 : // Lookup up the TDD:DOME object
8724 2 : int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
8725 2 : int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
8726 : // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
8727 2 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
8728 :
8729 : // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
8730 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
8731 : // = SurfWinQRadSWwinAbs(surfNum,1)/2.0
8732 2 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surfNum));
8733 2 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8734 2 : (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, 1) / 2.0 +
8735 2 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8736 2 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8737 2 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8738 2 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
8739 2 : Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
8740 2 : (Ueff + HConvIn_surf +
8741 : DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
8742 : // solar | Convection from surface to zone air | Net radiant exchange with
8743 : // other zone surfaces | Iterative damping term (for stability) | Current
8744 : // conduction from the outside surface | Coefficient for conduction (current
8745 : // time) | Convection and damping term
8746 2 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
8747 2 : Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(surfNum) + Constant::Kelvin));
8748 :
8749 : // fill out report vars for components of Window Heat Gain
8750 2 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
8751 4 : HConvIn_surf * surface.Area *
8752 2 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
8753 2 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
8754 2 : state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
8755 2 : (Sigma_Temp_4 -
8756 2 : (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum)));
8757 2 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
8758 2 : state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
8759 2 : (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
8760 2 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(surfNum);
8761 :
8762 : // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
8763 2 : state.dataSurface->SurfWinHeatGain(surfNum) =
8764 2 : state.dataSurface->SurfWinTransSolar(surfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) +
8765 2 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) -
8766 2 : surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum);
8767 : // Net transmitted solar | Convection | IR exchange | IR
8768 : // Zone diffuse interior shortwave reflected back into the TDD
8769 : } else { // Regular window
8770 379756 : if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
8771 : // Get outside convection coeff for exterior window here to avoid calling
8772 : // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
8773 : // (HeatBalanceSurfaceManager USEing and WindowManager and
8774 : // WindowManager USEing HeatBalanceSurfaceManager)
8775 88560 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
8776 88560 : auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
8777 88560 : assert(thisMaterial != nullptr);
8778 88560 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
8779 88560 : Real64 EmisOut = thisMaterial->AbsorpThermalFront; // Glass outside surface emissivity
8780 88560 : DataSurfaces::WinShadingType const shading_flag = state.dataSurface->SurfWinShadingFlag(surfNum);
8781 88560 : if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
8782 : // Exterior shade in place
8783 0 : int const ConstrNumSh = Surface(surfNum).activeShadedConstruction;
8784 0 : if (ConstrNumSh != 0) {
8785 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
8786 0 : auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
8787 0 : RoughSurf = thisMaterial2->Roughness;
8788 0 : EmisOut = thisMaterial2->AbsorpThermal;
8789 : }
8790 : }
8791 :
8792 : // Get the outside effective emissivity for Equivalent layer model
8793 88560 : if (construct.WindowTypeEQL) {
8794 2367 : EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
8795 : }
8796 : // Set Exterior Convection Coefficient...
8797 88560 : if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
8798 :
8799 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
8800 :
8801 88560 : } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
8802 :
8803 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
8804 : // subroutine)
8805 88560 : Convect::InitExtConvCoeff(state,
8806 : surfNum,
8807 : 0.0,
8808 : RoughSurf,
8809 : EmisOut,
8810 : TH11,
8811 88560 : state.dataHeatBalSurf->SurfHConvExt(surfNum),
8812 88560 : state.dataHeatBalSurf->SurfHSkyExt(surfNum),
8813 88560 : state.dataHeatBalSurf->SurfHGrdExt(surfNum),
8814 88560 : state.dataHeatBalSurf->SurfHAirExt(surfNum),
8815 88560 : state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
8816 :
8817 88560 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
8818 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = 1000.0; // Reset SurfHcExt because of wetness
8819 : }
8820 :
8821 : } else { // Not Wind exposed
8822 :
8823 : // Calculate exterior heat transfer coefficients for windspeed = 0
8824 0 : Convect::InitExtConvCoeff(state,
8825 : surfNum,
8826 : 0.0,
8827 : RoughSurf,
8828 : EmisOut,
8829 : TH11,
8830 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum),
8831 0 : state.dataHeatBalSurf->SurfHSkyExt(surfNum),
8832 0 : state.dataHeatBalSurf->SurfHGrdExt(surfNum),
8833 0 : state.dataHeatBalSurf->SurfHAirExt(surfNum),
8834 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
8835 : }
8836 :
8837 : } else { // Interior Surface
8838 :
8839 0 : if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
8840 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
8841 : } else {
8842 : // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
8843 : // same
8844 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
8845 : }
8846 : }
8847 :
8848 : // Following call determines inside surface temperature of glazing, and of
8849 : // frame and/or divider, if present
8850 88560 : Window::CalcWindowHeatBalance(
8851 88560 : state, surfNum, state.dataHeatBalSurf->SurfHConvExt(surfNum), state.dataHeatBalSurf->SurfTempInTmp(surfNum), TH11);
8852 88560 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
8853 : }
8854 : }
8855 : }
8856 :
8857 1252734 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
8858 1252734 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
8859 8443644 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8860 7190910 : auto &zone = state.dataHeatBal->Zone(zoneNum);
8861 :
8862 7190910 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
8863 7190910 : Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(surfNum);
8864 7190910 : TH12 = state.dataHeatBalSurf->SurfTempIn(surfNum);
8865 7190910 : state.dataHeatBalSurf->SurfTempOut(surfNum) = TH11; // For reporting
8866 7190910 : if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8867 : // Tubular daylighting devices are treated as one big object with an effective R value.
8868 : // The outside face temperature of the TDD:DOME and the inside face temperature of the
8869 : // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
8870 : // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
8871 : // and the outside face of the TDD:DIFFUSER for reporting.
8872 :
8873 : // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
8874 2 : int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(surfNum)).Dome;
8875 2 : state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
8876 2 : state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(surfNum);
8877 :
8878 : // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
8879 : // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
8880 2 : TH11 = state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
8881 2 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
8882 : }
8883 :
8884 7190910 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
8885 0 : TestSurfTempCalcHeatBalanceInsideSurf(
8886 0 : state, TH12, surfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
8887 : }
8888 : }
8889 : }
8890 : } // ...end of main loops over all surfaces for inside heat balances
8891 :
8892 : // Interzone surface updating: interzone surfaces have other side temperatures
8893 : // which can vary as the simulation iterates through the inside heat
8894 : // balance. This block is intended to "lock" the opposite side (outside)
8895 : // temperatures to the correct value, namely the value calculated by the
8896 : // inside surface heat balance for the other side.
8897 : // assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
8898 : // int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
8899 1532725 : for (int SurfNum : IZSurfs) {
8900 754714 : int const surfExtBoundCond = Surface(SurfNum).ExtBoundCond;
8901 : // Set the outside surface temperature to the inside surface temperature of the interzone pair.
8902 : // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
8903 : // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
8904 : // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
8905 754714 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
8906 754714 : state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
8907 754714 : state.dataHeatBalSurf->SurfTempOutHist(SurfNum) = state.dataHeatBalSurf->SurfTempOut(SurfNum);
8908 : }
8909 :
8910 778011 : ++state.dataHeatBal->InsideSurfIterations;
8911 :
8912 : // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
8913 778011 : Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
8914 1926310 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8915 2401033 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8916 1252734 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8917 1252734 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8918 1252734 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8919 8063886 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8920 6811152 : Real64 delta = state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfTempInsOld(surfNum);
8921 6811152 : Real64 absDif = std::abs(delta);
8922 6811152 : MaxDelTemp = std::max(absDif, MaxDelTemp);
8923 : }
8924 : }
8925 : } // ...end of loop to check for convergence
8926 :
8927 778011 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) Converged = true;
8928 :
8929 : #ifdef EP_Count_Calls
8930 : state.dataTimingsData->NumMaxInsideSurfIterations =
8931 : max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
8932 : #endif
8933 :
8934 778011 : if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) Converged = false;
8935 :
8936 778011 : if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
8937 0 : if (!state.dataGlobal->WarmupFlag) {
8938 0 : ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
8939 0 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
8940 0 : ShowWarningError(state,
8941 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max Allowed "
8942 : "Temp Diff [C] ={:.6R}",
8943 : MaxDelTemp,
8944 0 : state.dataHeatBal->MaxAllowedDelTempCondFD));
8945 0 : ShowContinueErrorTimeStamp(state, "");
8946 : } else {
8947 0 : ShowRecurringWarningErrorAtEnd(state,
8948 : "Inside surface heat balance convergence problem continues",
8949 0 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
8950 : MaxDelTemp,
8951 : MaxDelTemp,
8952 : _,
8953 : "[C]",
8954 : "[C]");
8955 : }
8956 : }
8957 0 : break; // iteration loop
8958 : }
8959 :
8960 : } // ...end of main inside heat balance iteration loop (ends when Converged)
8961 200983 : }
8962 :
8963 249963 : void sumSurfQdotRadHVAC(EnergyPlusData &state)
8964 : {
8965 249999 : for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
8966 36 : auto const &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
8967 36 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = thisSurfQRadFromHVAC.HTRadSys + thisSurfQRadFromHVAC.HWBaseboard +
8968 36 : thisSurfQRadFromHVAC.SteamBaseboard + thisSurfQRadFromHVAC.ElecBaseboard +
8969 36 : thisSurfQRadFromHVAC.CoolingPanel;
8970 : }
8971 249963 : }
8972 :
8973 5 : void TestSurfTempCalcHeatBalanceInsideSurf(EnergyPlusData &state, Real64 TH12, int const SurfNum, DataHeatBalance::ZoneData &zone, int WarmupSurfTemp)
8974 : {
8975 5 : std::string surfName = state.dataSurface->Surface(SurfNum).Name;
8976 :
8977 5 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
8978 4 : if (state.dataGlobal->WarmupFlag) ++WarmupSurfTemp;
8979 4 : if (!state.dataGlobal->WarmupFlag || WarmupSurfTemp > 10 || state.dataGlobal->DisplayExtraWarnings) {
8980 4 : if (TH12 < DataHeatBalSurface::MinSurfaceTempLimit) {
8981 2 : if (state.dataSurface->SurfLowTempErrCount(SurfNum) == 0) {
8982 4 : ShowSevereMessage(
8983 4 : state, format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
8984 4 : ShowContinueErrorTimeStamp(state, "");
8985 2 : if (!zone.TempOutOfBoundsReported) {
8986 1 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
8987 1 : if (zone.FloorArea > 0.0) {
8988 1 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
8989 : } else {
8990 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
8991 : }
8992 1 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
8993 1 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
8994 1 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
8995 : } else {
8996 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
8997 : }
8998 1 : if (zone.IsControlled) {
8999 3 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9000 : } else {
9001 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9002 : }
9003 1 : zone.TempOutOfBoundsReported = true;
9004 : }
9005 18 : ShowRecurringSevereErrorAtEnd(state,
9006 4 : "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9007 2 : state.dataSurface->SurfLowTempErrCount(SurfNum),
9008 : TH12,
9009 : TH12,
9010 : _,
9011 : "C",
9012 : "C");
9013 : } else {
9014 0 : ShowRecurringSevereErrorAtEnd(state,
9015 0 : "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9016 0 : state.dataSurface->SurfLowTempErrCount(SurfNum),
9017 : TH12,
9018 : TH12,
9019 : _,
9020 : "C",
9021 : "C");
9022 : }
9023 : } else {
9024 2 : if (state.dataSurface->SurfHighTempErrCount(SurfNum) == 0) {
9025 4 : ShowSevereMessage(
9026 4 : state, format(R"(Temperature (high) out of bounds ({:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9027 4 : ShowContinueErrorTimeStamp(state, "");
9028 2 : if (!zone.TempOutOfBoundsReported) {
9029 1 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9030 1 : if (zone.FloorArea > 0.0) {
9031 1 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9032 : } else {
9033 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
9034 : }
9035 1 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9036 1 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9037 1 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9038 : } else {
9039 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9040 : }
9041 1 : if (zone.IsControlled) {
9042 3 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9043 : } else {
9044 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9045 : }
9046 1 : zone.TempOutOfBoundsReported = true;
9047 : }
9048 18 : ShowRecurringSevereErrorAtEnd(state,
9049 4 : "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9050 2 : state.dataSurface->SurfHighTempErrCount(SurfNum),
9051 : TH12,
9052 : TH12,
9053 : _,
9054 : "C",
9055 : "C");
9056 : } else {
9057 0 : ShowRecurringSevereErrorAtEnd(state,
9058 0 : "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9059 0 : state.dataSurface->SurfHighTempErrCount(SurfNum),
9060 : TH12,
9061 : TH12,
9062 : _,
9063 : "C",
9064 : "C");
9065 : }
9066 : }
9067 4 : if (zone.EnforcedReciprocity) {
9068 0 : if (WarmupSurfTemp > 3) {
9069 0 : ShowSevereError(state, format("CalcHeatBalanceInsideSurf: Zone=\"{}\" has view factor enforced reciprocity", zone.Name));
9070 0 : ShowContinueError(state, " and is having temperature out of bounds errors. Please correct zone geometry and rerun.");
9071 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
9072 : }
9073 4 : } else if (WarmupSurfTemp > 10) {
9074 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
9075 : }
9076 : }
9077 : }
9078 5 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal)) {
9079 0 : if (!state.dataGlobal->WarmupFlag) {
9080 0 : if (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal) {
9081 0 : ShowSevereError(state,
9082 0 : format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9083 0 : ShowContinueErrorTimeStamp(state, "");
9084 0 : if (!zone.TempOutOfBoundsReported) {
9085 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9086 0 : if (zone.FloorArea > 0.0) {
9087 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9088 : } else {
9089 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
9090 : }
9091 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9092 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9093 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9094 : } else {
9095 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9096 : }
9097 0 : if (zone.IsControlled) {
9098 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9099 : } else {
9100 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9101 : }
9102 0 : zone.TempOutOfBoundsReported = true;
9103 : }
9104 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9105 : } else {
9106 0 : ShowSevereError(state,
9107 0 : format(R"(Temperature (high) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9108 0 : ShowContinueErrorTimeStamp(state, "");
9109 0 : if (!zone.TempOutOfBoundsReported) {
9110 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9111 0 : if (zone.FloorArea > 0.0) {
9112 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9113 : } else {
9114 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
9115 : }
9116 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9117 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9118 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9119 : } else {
9120 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9121 : }
9122 0 : if (zone.IsControlled) {
9123 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9124 : } else {
9125 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9126 : }
9127 0 : zone.TempOutOfBoundsReported = true;
9128 : }
9129 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9130 : }
9131 : } else {
9132 0 : if (TH12 < -10000. || TH12 > 10000.) {
9133 0 : ShowSevereError(
9134 : state,
9135 0 : format(R"(CalcHeatBalanceInsideSurf: The temperature of {:.2R} C for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9136 0 : ShowContinueError(state, "..is very far out of bounds during warmup. This may be an indication of a malformed zone.");
9137 0 : ShowContinueErrorTimeStamp(state, "");
9138 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9139 : }
9140 : }
9141 : }
9142 5 : }
9143 :
9144 1053753 : void CalcOutsideSurfTemp(EnergyPlusData &state,
9145 : int const SurfNum, // Surface number DO loop counter
9146 : int const spaceNum, // Space number the current surface is attached to
9147 : int const ConstrNum, // Construction index for the current surface
9148 : Real64 const HMovInsul, // "Convection" coefficient of movable insulation
9149 : Real64 const TempExt, // Exterior temperature boundary condition
9150 : bool &ErrorFlag // Error flag for movable insulation problem
9151 : )
9152 : {
9153 :
9154 : // SUBROUTINE INFORMATION:
9155 : // AUTHOR George Walton
9156 : // DATE WRITTEN December 1979
9157 : // MODIFIED Jun 1990 (RDT for new CTF arrays)
9158 : // Jul 2000 (RJL for Moisture algorithms)
9159 : // Sep 2000 (RKS for new radiant exchange algorithm)
9160 : // Dec 2000 (RKS for radiant system model addition)
9161 : // Aug 2010 (BG added radiant heat flow rate reporting)
9162 : // RE-ENGINEERED Mar 1998 (RKS)
9163 :
9164 : // PURPOSE OF THIS SUBROUTINE:
9165 : // This subroutine performs a heat balance on the outside face of each
9166 : // surface in the building. NOTE that this also sets some coefficients
9167 : // that are needed for radiant system modeling. Thus, it is extremely
9168 : // important that if someone makes changes to the heat balance equations
9169 : // at a later date that they must also make changes to the coefficient
9170 : // setting portion of this subroutine as well.
9171 :
9172 : // METHODOLOGY EMPLOYED:
9173 : // Various boundary conditions are set and additional parameters are set-
9174 : // up. Then, the proper heat balance equation is selected based on the
9175 : // presence of movable insulation, thermal mass of the surface construction,
9176 : // and convection model being used.
9177 :
9178 : // REFERENCES:
9179 : // (I)BLAST legacy routine HBOUT
9180 : // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
9181 :
9182 : // Determine whether or not movable insulation is present
9183 1053753 : bool MovInsulPresent = (HMovInsul > 0.0); // .TRUE. if movable insulation is currently present for surface
9184 : bool QuickConductionSurf; // .TRUE. if the cross CTF term is relatively large
9185 : Real64 F1; // Intermediate calculation variable
9186 : Real64 F2; // Intermediate calculation variable
9187 : // Determine whether this surface is a "slow conductive" or "quick conductive"
9188 : // surface. Designates are inherited from BLAST. Basically, a "quick" surface
9189 : // requires the inside heat balance to be accounted for in the heat balance
9190 : // while a "slow" surface can used the last time step's value for inside
9191 : // surface temperature.
9192 1053753 : auto &s_mat = state.dataMaterial;
9193 :
9194 1053753 : auto &surface = state.dataSurface->Surface(SurfNum);
9195 1053753 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
9196 1053753 : if (construct.CTFCross[0] > 0.01) {
9197 711822 : QuickConductionSurf = true;
9198 711822 : F1 = construct.CTFCross[0] / (construct.CTFInside[0] + state.dataHeatBalSurf->SurfHConvInt(SurfNum));
9199 : } else {
9200 341931 : QuickConductionSurf = false;
9201 : }
9202 :
9203 1053753 : Real64 TSky = state.dataEnvrn->SkyTemp;
9204 1053753 : Real64 TGround = state.dataEnvrn->OutDryBulbTemp;
9205 1053753 : Real64 TSrdSurfs = 0.0;
9206 :
9207 1053753 : if (surface.SurfHasSurroundingSurfProperty) {
9208 6 : int SrdSurfsNum = surface.SurfSurroundingSurfacesNum;
9209 6 : if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched != nullptr) {
9210 3 : TSky = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched->getCurrentVal();
9211 : }
9212 6 : if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched != nullptr) {
9213 1 : TGround = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched->getCurrentVal();
9214 : }
9215 6 : TSrdSurfs = state.dataSurface->Surface(SurfNum).SrdSurfTemp;
9216 : }
9217 1053753 : if (surface.UseSurfPropertyGndSurfTemp) {
9218 3 : TGround = state.dataSurface->GroundSurfsProperty(surface.SurfPropertyGndSurfIndex).SurfsTempAvg;
9219 : }
9220 :
9221 : // Now, calculate the outside surface temperature using the proper heat balance equation.
9222 : // Each case has been separated out into its own IF-THEN block for clarity. Additional
9223 : // cases can simply be added anywhere in the following section. This is the last step
9224 : // in the main loop. Once the proper heat balance is done, the simulation goes on to
9225 : // the next SurfNum.
9226 :
9227 : // Outside heat balance case: Tubular daylighting device
9228 1053753 : Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum));
9229 1053753 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
9230 :
9231 : // Lookup up the TDD:DIFFUSER object
9232 0 : int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
9233 0 : int SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser;
9234 0 : int spaceNum2 = state.dataSurface->Surface(SurfNum2).spaceNum;
9235 0 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(PipeNum).Reff; // 1 / effective R value between TDD:DOME and TDD:DIFFUSER
9236 0 : F1 = Ueff / (Ueff + state.dataHeatBalSurf->SurfHConvInt(SurfNum2));
9237 :
9238 : // Similar to opaque surface but inside conditions of TDD:DIFFUSER are used, and no embedded sources/sinks.
9239 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
9240 : // SurfOpaqQRadSWOutAbs(SurfNum) does not apply for TDD:DOME, must use SurfWinQRadSWwinAbs(SurfNum,1)/2.0 instead.
9241 : //+Construct(ConstrNum)%CTFSourceOut[0] & TDDs cannot be radiant systems
9242 : // *SurfQsrcHist(1,SurfNum) &
9243 : //+Construct(ConstrNum)%CTFSourceIn[0] & TDDs cannot be radiant systems
9244 : // *SurfQsrcHist(1,SurfNum) &
9245 0 : TH11 = (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
9246 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9247 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) +
9248 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9249 0 : F1 * (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum2, 1) / 2.0 + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum2) +
9250 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum2) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum2).MAT +
9251 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum2))) /
9252 0 : (Ueff + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9253 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9254 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9255 0 : F1 * Ueff); // Instead of SurfOpaqQRadSWOutAbs(SurfNum) | ODB used to approx ground surface temp | Use TDD:DIFFUSER surface | Use
9256 : // TDD:DIFFUSER surface | Use TDD:DIFFUSER surface and zone | Use TDD:DIFFUSER surface
9257 :
9258 : // Outside heat balance case: No movable insulation, slow conduction
9259 1053753 : } else if ((!MovInsulPresent) && (!QuickConductionSurf)) {
9260 : // Add LWR from surrounding surfaces
9261 341930 : if (surface.OSCMPtr == 0) {
9262 341930 : if (construct.SourceSinkPresent) {
9263 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9264 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9265 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9266 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9267 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9268 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
9269 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9270 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9271 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
9272 : } else {
9273 341930 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9274 341930 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9275 341930 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9276 341930 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9277 341930 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
9278 341930 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9279 341930 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9280 341930 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
9281 : }
9282 : // Outside Heat Balance case: Other Side Conditions Model
9283 : } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
9284 : // local copies of variables for clarity in radiation terms
9285 : // TODO: - int OSCMPtr; // "Pointer" to OSCM data structure (other side conditions from a model)
9286 : Real64 RadTemp =
9287 0 : state.dataSurface->OSCM(surface.OSCMPtr).TRad; // local value for Effective radiation temperature for OtherSideConditions model
9288 0 : Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad; // local value for effective (linearized) radiation coefficient
9289 :
9290 : // patterned after "No movable insulation, slow conduction," but with new radiation terms and no sun,
9291 0 : if (construct.SourceSinkPresent) {
9292 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9293 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9294 0 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9295 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
9296 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
9297 : } else {
9298 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9299 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9300 0 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
9301 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
9302 : }
9303 : }
9304 : // Outside heat balance case: No movable insulation, quick conduction
9305 1053753 : } else if ((!MovInsulPresent) && (QuickConductionSurf)) {
9306 711822 : if (surface.OSCMPtr == 0) {
9307 711822 : if (construct.SourceSinkPresent) {
9308 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9309 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9310 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9311 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9312 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9313 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9314 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9315 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9316 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9317 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9318 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9319 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9320 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9321 0 : F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
9322 : } else {
9323 711822 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9324 711822 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9325 711822 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9326 711822 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9327 711822 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9328 711822 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9329 711822 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9330 711822 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9331 711822 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9332 711822 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9333 711822 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9334 711822 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9335 711822 : F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
9336 : }
9337 : // Outside Heat Balance case: Other Side Conditions Model
9338 : } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
9339 : // local copies of variables for clarity in radiation terms
9340 0 : Real64 RadTemp = state.dataSurface->OSCM(surface.OSCMPtr).TRad;
9341 0 : Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad;
9342 : // patterned after "No movable insulation, quick conduction," but with new radiation terms and no sun,
9343 0 : if (construct.SourceSinkPresent) {
9344 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9345 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9346 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9347 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9348 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9349 0 : construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9350 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9351 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9352 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
9353 0 : F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
9354 : } else {
9355 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9356 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9357 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9358 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9359 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9360 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9361 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
9362 0 : F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
9363 : }
9364 : }
9365 : // Outside heat balance case: Movable insulation, slow conduction
9366 711823 : } else if ((MovInsulPresent) && (!QuickConductionSurf)) {
9367 :
9368 1 : F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9369 1 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9370 1 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
9371 :
9372 1 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9373 1 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9374 1 : F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
9375 1 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9376 1 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9377 1 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
9378 1 : (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul); // ODB used to approx ground surface temp
9379 :
9380 : // Outside heat balance case: Movable insulation, quick conduction
9381 0 : } else if ((MovInsulPresent) && (QuickConductionSurf)) {
9382 :
9383 0 : F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9384 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9385 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
9386 :
9387 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9388 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9389 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9390 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9391 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)) +
9392 0 : F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
9393 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9394 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9395 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
9396 0 : (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul - F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp
9397 :
9398 : } // ...end of outside heat balance cases IF-THEN block
9399 :
9400 : // multiply out linearized radiation coeffs for reporting
9401 : Real64 const HExtSurf_fac(
9402 1053753 : -(state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * (TH11 - TSky) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) * (TH11 - TempExt) +
9403 1053753 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * (TH11 - TGround) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * (TH11 - TSrdSurfs)));
9404 1053753 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = HExtSurf_fac;
9405 :
9406 : // Set the radiant system heat balance coefficients if this surface is also a radiant system
9407 1053753 : if (construct.SourceSinkPresent) {
9408 :
9409 1 : if (MovInsulPresent) {
9410 : // Note: if movable insulation is ever added back in correctly, the heat balance equations above must be fixed
9411 2 : ShowSevereError(state, "Exterior movable insulation is not valid with embedded sources/sinks");
9412 1 : ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
9413 2 : ShowContinueError(state,
9414 2 : format("exterior movable insulation {} for a surface with that construction.",
9415 1 : s_mat->materials(state.dataSurface->extMovInsuls(SurfNum).matNum)->Name));
9416 2 : ShowContinueError(state,
9417 : "This is not currently allowed because the heat balance equations do not currently accommodate this combination.");
9418 1 : ErrorFlag = true;
9419 1 : return;
9420 :
9421 : } else {
9422 0 : Real64 const RadSysDiv(1.0 / (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) +
9423 0 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) +
9424 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) +
9425 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)));
9426 :
9427 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
9428 0 : (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9429 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9430 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9431 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround) *
9432 : RadSysDiv; // ODB used to approx ground surface temp
9433 :
9434 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = construct.CTFCross[0] * RadSysDiv;
9435 :
9436 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = construct.CTFSourceOut[0] * RadSysDiv;
9437 : }
9438 : }
9439 : }
9440 :
9441 0 : void CalcExteriorVentedCavity(EnergyPlusData &state, int const SurfNum) // index of surface
9442 : {
9443 :
9444 : // SUBROUTINE INFORMATION:
9445 : // AUTHOR B Griffith
9446 : // DATE WRITTEN January 2005
9447 :
9448 : // PURPOSE OF THIS SUBROUTINE:
9449 : // manages calculating the temperatures of baffle and air cavity for
9450 : // multi-skin configuration.
9451 :
9452 : // METHODOLOGY EMPLOYED:
9453 : // derived from CalcPassiveTranspiredCollector
9454 :
9455 : // local working variables
9456 : Real64 HrPlen;
9457 : Real64 HcPlen;
9458 : Real64 Isc;
9459 : Real64 MdotVent;
9460 : Real64 VdotWind;
9461 : Real64 VdotThermal;
9462 :
9463 0 : int CavNum = state.dataSurface->SurfExtCavNum(SurfNum);
9464 0 : Real64 TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
9465 0 : Real64 OutHumRatExt = Psychrometrics::PsyWFnTdbTwbPb(
9466 0 : state, state.dataSurface->SurfOutDryBulbTemp(SurfNum), state.dataSurface->SurfOutWetBulbTemp(SurfNum), state.dataEnvrn->OutBaroPress);
9467 0 : Real64 RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, OutHumRatExt);
9468 0 : Real64 holeArea = state.dataHeatBal->ExtVentedCavity(CavNum).ActualArea * state.dataHeatBal->ExtVentedCavity(CavNum).Porosity;
9469 : // Aspect Ratio of gap
9470 0 : Real64 AspRat = state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL * 2.0 / state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick;
9471 0 : Real64 TmpTscoll = state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast;
9472 0 : Real64 TmpTaPlen = state.dataHeatBal->ExtVentedCavity(CavNum).TairLast;
9473 :
9474 : // all the work is done in this routine located in GeneralRoutines.cc
9475 :
9476 0 : for (int iter = 1; iter <= 3; ++iter) { // this is a sequential solution approach.
9477 :
9478 0 : TranspiredCollector::CalcPassiveExteriorBaffleGap(state,
9479 0 : state.dataHeatBal->ExtVentedCavity(CavNum).SurfPtrs,
9480 : holeArea,
9481 0 : state.dataHeatBal->ExtVentedCavity(CavNum).Cv,
9482 0 : state.dataHeatBal->ExtVentedCavity(CavNum).Cd,
9483 0 : state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL,
9484 0 : state.dataHeatBal->ExtVentedCavity(CavNum).SolAbsorp,
9485 0 : state.dataHeatBal->ExtVentedCavity(CavNum).LWEmitt,
9486 0 : state.dataHeatBal->ExtVentedCavity(CavNum).Tilt,
9487 : AspRat,
9488 0 : state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick,
9489 0 : state.dataHeatBal->ExtVentedCavity(CavNum).BaffleRoughness,
9490 0 : state.dataHeatBal->ExtVentedCavity(CavNum).QdotSource,
9491 : TmpTscoll,
9492 : TmpTaPlen,
9493 : HcPlen,
9494 : HrPlen,
9495 : Isc,
9496 : MdotVent,
9497 : VdotWind,
9498 : VdotThermal);
9499 :
9500 : } // sequential solution
9501 : // now fill results into derived types
9502 0 : state.dataHeatBal->ExtVentedCavity(CavNum).Isc = Isc;
9503 0 : state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav = TmpTaPlen;
9504 0 : state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle = TmpTscoll;
9505 0 : state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen = HrPlen;
9506 0 : state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen = HcPlen;
9507 0 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveACH =
9508 0 : (MdotVent / RhoAir) *
9509 0 : (1.0 / (state.dataHeatBal->ExtVentedCavity(CavNum).ProjArea * state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick)) *
9510 : Constant::rSecsInHour;
9511 0 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotVent = MdotVent;
9512 0 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotWind = VdotWind * RhoAir;
9513 0 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotTherm = VdotThermal * RhoAir;
9514 :
9515 : // now do some updates
9516 0 : state.dataHeatBal->ExtVentedCavity(CavNum).TairLast = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
9517 0 : state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
9518 :
9519 : // update the OtherSideConditionsModel coefficients.
9520 0 : int thisOSCM = state.dataHeatBal->ExtVentedCavity(CavNum).OSCMPtr;
9521 :
9522 0 : state.dataSurface->OSCM(thisOSCM).TConv = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
9523 0 : state.dataSurface->OSCM(thisOSCM).HConv = state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen;
9524 0 : state.dataSurface->OSCM(thisOSCM).TRad = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
9525 0 : state.dataSurface->OSCM(thisOSCM).HRad = state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen;
9526 0 : }
9527 :
9528 83022 : void GatherComponentLoadsSurfAbsFact(EnergyPlusData &state)
9529 : {
9530 : // SUBROUTINE INFORMATION:
9531 : // AUTHOR Jason Glazer
9532 : // DATE WRITTEN September 2012
9533 :
9534 : // PURPOSE OF THIS SUBROUTINE:
9535 : // Gather values during sizing used for surface absorption factors
9536 :
9537 : // METHODOLOGY EMPLOYED:
9538 : // Save sequence of values for report during sizing.
9539 :
9540 : // This is by surface, so it works for both space and zone component loads
9541 83022 : if (state.dataGlobal->CompLoadReportIsReq && !state.dataGlobal->isPulseZoneSizing) {
9542 7452 : int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
9543 7452 : auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
9544 82566 : for (int jSurf = 1; jSurf <= state.dataSurface->TotSurfaces; ++jSurf) {
9545 75114 : auto const &surface = state.dataSurface->Surface(jSurf);
9546 75114 : if (!surface.HeatTransSurf || surface.Zone == 0) continue; // Skip non-heat transfer surfaces
9547 75114 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) continue; // Skip tubular daylighting device domes
9548 75114 : surfCLDayTS.surf[jSurf - 1].ITABSFseq = state.dataHeatBalSurf->SurfAbsThermalInt(jSurf);
9549 75114 : surfCLDayTS.surf[jSurf - 1].TMULTseq = state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).radThermAbsMult;
9550 : }
9551 : }
9552 83022 : }
9553 :
9554 625134 : Real64 GetSurfIncidentSolarMultiplier(EnergyPlusData &state, int SurfNum)
9555 : {
9556 625134 : if (!state.dataSurface->Surface(SurfNum).hasIncSolMultiplier) {
9557 625132 : return 1.0;
9558 2 : } else if (state.dataSurface->SurfIncSolMultiplier(SurfNum).sched != nullptr) {
9559 0 : return state.dataSurface->SurfIncSolMultiplier(SurfNum).sched->getCurrentVal() * state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
9560 : } else {
9561 2 : return state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
9562 : }
9563 : }
9564 :
9565 116 : void InitSurfacePropertyViewFactors(EnergyPlusData &state)
9566 : {
9567 :
9568 : // purpose:
9569 : // Initializes sky and ground surfaces view factors of exterior surfaces
9570 : // used by SurfaceProperty:LocalEnvironment
9571 : // view factors are constant hence should be set only once
9572 :
9573 116 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9574 108 : return;
9575 : }
9576 8 : if (!state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
9577 0 : return;
9578 : }
9579 :
9580 50 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9581 42 : auto &Surface = state.dataSurface->Surface(SurfNum);
9582 42 : if (Surface.SurfHasSurroundingSurfProperty || Surface.IsSurfPropertyGndSurfacesDefined) {
9583 :
9584 18 : int GndSurfsNum = 0;
9585 18 : int SrdSurfsNum = 0;
9586 18 : Real64 SrdSurfsViewFactor = 0.0;
9587 18 : Real64 SurfsSkyViewFactor = 0.0;
9588 18 : Real64 GroundSurfsViewFactor = 0.0;
9589 18 : bool IsSkyViewFactorSet = false;
9590 18 : bool IsGroundViewFactorSet = false;
9591 18 : bool SetGroundViewFactorObject = false;
9592 18 : if (Surface.SurfHasSurroundingSurfProperty) {
9593 18 : SrdSurfsNum = Surface.SurfSurroundingSurfacesNum;
9594 18 : auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
9595 18 : SurfsSkyViewFactor = SrdSurfsProperty.SkyViewFactor;
9596 18 : IsSkyViewFactorSet = SrdSurfsProperty.IsSkyViewFactorSet;
9597 18 : if (SurfsSkyViewFactor > 0.0) {
9598 12 : SrdSurfsViewFactor += SurfsSkyViewFactor;
9599 : }
9600 18 : if (!Surface.IsSurfPropertyGndSurfacesDefined) {
9601 8 : SrdSurfsViewFactor += SrdSurfsProperty.GroundViewFactor;
9602 8 : IsGroundViewFactorSet = SrdSurfsProperty.IsGroundViewFactorSet;
9603 8 : GroundSurfsViewFactor = SrdSurfsProperty.GroundViewFactor;
9604 : }
9605 46 : for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
9606 28 : SrdSurfsViewFactor += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
9607 : }
9608 : }
9609 18 : if (Surface.IsSurfPropertyGndSurfacesDefined) {
9610 10 : GndSurfsNum = Surface.SurfPropertyGndSurfIndex;
9611 10 : IsGroundViewFactorSet = state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet;
9612 10 : GroundSurfsViewFactor = state.dataSurface->GroundSurfsProperty(GndSurfsNum).SurfsViewFactorSum;
9613 10 : SrdSurfsViewFactor += GroundSurfsViewFactor;
9614 : }
9615 :
9616 : // Check if the sum of all defined view factors > 1.0
9617 18 : if (SrdSurfsViewFactor > 1.0) {
9618 0 : ShowSevereError(state, format("Illegal surrounding surfaces view factors for {}.", Surface.Name));
9619 0 : ShowContinueError(state, " The sum of sky, ground, and all surrounding surfaces view factors should be less than or equal to 1.0.");
9620 : }
9621 18 : if (IsSkyViewFactorSet && IsGroundViewFactorSet) {
9622 : // If both surface sky and ground view factor defined, overwrite with the defined value
9623 6 : Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
9624 6 : Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
9625 12 : } else if (IsSkyViewFactorSet && !IsGroundViewFactorSet) {
9626 : // If only sky view factor defined, ground view factor = 1 - all other defined view factors.
9627 6 : Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
9628 6 : Surface.ViewFactorGroundIR = 1 - SrdSurfsViewFactor;
9629 6 : if (GndSurfsNum > 0) {
9630 2 : SetGroundViewFactorObject = true;
9631 2 : state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
9632 : } else {
9633 4 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
9634 : }
9635 6 : } else if (!IsSkyViewFactorSet && IsGroundViewFactorSet) {
9636 : // If only ground view factor defined, sky view factor = 1 - all other defined view factors.
9637 2 : Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
9638 2 : Surface.ViewFactorSkyIR = 1 - SrdSurfsViewFactor;
9639 2 : if (SrdSurfsNum > 0) {
9640 2 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
9641 2 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
9642 : }
9643 : } else {
9644 : // If neither ground nor sky view factor specified, continue to use the original proportion.
9645 4 : Surface.ViewFactorSkyIR *= 1 - SrdSurfsViewFactor;
9646 4 : Surface.ViewFactorGroundIR *= 1 - SrdSurfsViewFactor;
9647 4 : if (SrdSurfsNum > 0) {
9648 4 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
9649 4 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
9650 4 : if (GndSurfsNum == 0) {
9651 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
9652 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsGroundViewFactorSet = true;
9653 : }
9654 : }
9655 4 : if (GndSurfsNum > 0) {
9656 4 : SetGroundViewFactorObject = true;
9657 4 : state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
9658 : }
9659 : }
9660 18 : if (SetGroundViewFactorObject) {
9661 6 : ReSetGroundSurfacesViewFactor(state, SurfNum);
9662 : }
9663 : }
9664 : }
9665 : }
9666 :
9667 249966 : void GetGroundSurfacesTemperatureAverage(EnergyPlusData &state)
9668 : {
9669 : // returns ground surfaces average temperature (deg C)
9670 : // ground surfaces viewed by a building exterior surface
9671 : // ground surfaces temperature weighed using view factors
9672 :
9673 249966 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9674 249959 : return;
9675 : }
9676 :
9677 37 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9678 30 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) continue;
9679 7 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9680 7 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9681 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9682 0 : continue;
9683 : }
9684 7 : Real64 GndSurfaceTemp = 0.0;
9685 7 : Real64 GndSurfViewFactor = 0.0;
9686 7 : Real64 GndSurfaceTempSum = 0.0;
9687 24 : for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
9688 17 : GndSurfViewFactor = GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor;
9689 17 : if (GndSurfViewFactor == 0.0) continue;
9690 11 : if (GndSurfsProperty.GndSurfs(gSurfNum).tempSched == nullptr) continue;
9691 11 : GndSurfaceTemp = GndSurfsProperty.GndSurfs(gSurfNum).tempSched->getCurrentVal();
9692 11 : GndSurfaceTempSum += GndSurfViewFactor * pow_4(GndSurfaceTemp + Constant::Kelvin);
9693 : }
9694 7 : if (GndSurfaceTempSum == 0.0) {
9695 0 : GndSurfsProperty.SurfsTempAvg = 0.0;
9696 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9697 0 : continue;
9698 : }
9699 7 : GndSurfsProperty.SurfsTempAvg = root_4(GndSurfaceTempSum / GndSurfsProperty.SurfsViewFactorSum) - Constant::Kelvin;
9700 : }
9701 : }
9702 :
9703 249960 : void GetGroundSurfacesReflectanceAverage(EnergyPlusData &state)
9704 : {
9705 : // returns ground surfaces average reflectance (dimensionless)
9706 : // ground reflectance viewed by a building exterior surface
9707 : // ground surfaces reflectance weighed using view factors
9708 :
9709 249960 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9710 249953 : return;
9711 : }
9712 37 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9713 :
9714 30 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) continue;
9715 7 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9716 7 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9717 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9718 0 : continue;
9719 : }
9720 7 : Real64 GndSurfRefl = 0.0;
9721 7 : Real64 GndSurfsReflSum = 0.0;
9722 24 : for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
9723 17 : if (GndSurfsProperty.GndSurfs(gSurfNum).reflSched == nullptr) continue;
9724 12 : GndSurfRefl = GndSurfsProperty.GndSurfs(gSurfNum).reflSched->getCurrentVal();
9725 12 : GndSurfsReflSum += GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor * GndSurfRefl;
9726 : }
9727 7 : if (GndSurfsReflSum == 0.0) {
9728 3 : GndSurfsProperty.SurfsReflAvg = 0.0;
9729 3 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9730 3 : continue;
9731 : }
9732 4 : GndSurfsProperty.SurfsReflAvg = GndSurfsReflSum / GndSurfsProperty.SurfsViewFactorSum;
9733 : }
9734 : }
9735 :
9736 6 : void ReSetGroundSurfacesViewFactor(EnergyPlusData &state, int const SurfNum)
9737 : {
9738 : // resets ground view factors based on view factors identity
9739 : // the ground view factor value is set to the first element
9740 : // when the ground view factor input field is blank
9741 :
9742 6 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) return;
9743 6 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9744 6 : GndSurfsProperty.SurfsViewFactorSum = state.dataSurface->Surface(SurfNum).ViewFactorGroundIR;
9745 :
9746 6 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9747 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9748 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9749 0 : return;
9750 : }
9751 6 : GndSurfsProperty.GndSurfs(1).ViewFactor = GndSurfsProperty.SurfsViewFactorSum;
9752 : }
9753 :
9754 249965 : void GetSurroundingSurfacesTemperatureAverage(EnergyPlusData &state)
9755 : {
9756 : // returns surrounding surfaces average temperature (deg C)
9757 : // surrounding surfaces viewed by an exterior surface
9758 : // surrounding surfaces temperature weighed using view factors
9759 :
9760 249965 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9761 249959 : return;
9762 : }
9763 :
9764 33 : for (auto &surface : state.dataSurface->Surface) {
9765 27 : if (!surface.SurfHasSurroundingSurfProperty) continue;
9766 : // local vars
9767 10 : Real64 SrdSurfaceTemp = 0.0;
9768 10 : Real64 SrdSurfaceTempSum = 0.0;
9769 10 : auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(surface.SurfSurroundingSurfacesNum);
9770 26 : for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
9771 16 : SrdSurfaceTemp = SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() + Constant::Kelvin;
9772 16 : SrdSurfaceTempSum += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor * pow_4(SrdSurfaceTemp);
9773 : }
9774 10 : surface.SrdSurfTemp = root_4(SrdSurfaceTempSum / surface.ViewFactorSrdSurfs) - Constant::Kelvin;
9775 : }
9776 : }
9777 : } // namespace EnergyPlus::HeatBalanceSurfaceManager
|