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 2799882 : 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 2799882 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
159 803 : DisplayString(state, "Initializing Surfaces");
160 : }
161 2799882 : InitSurfaceHeatBalance(state); // Initialize all heat balance related parameters
162 :
163 : // Solve the zone heat balance 'Detailed' solution
164 : // Call the outside and inside surface heat balances
165 2799882 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
166 803 : DisplayString(state, "Calculate Outside Surface Heat Balance");
167 : }
168 2799882 : CalcHeatBalanceOutsideSurf(state);
169 2799882 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
170 803 : DisplayString(state, "Calculate Inside Surface Heat Balance");
171 : }
172 2799882 : CalcHeatBalanceInsideSurf(state);
173 :
174 : // The air heat balance must be called before the temperature history
175 : // updates because there may be a radiant system in the building
176 2799882 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
177 803 : DisplayString(state, "Calculate Air Heat Balance");
178 : }
179 2799882 : HeatBalanceAirManager::ManageAirHeatBalance(state);
180 :
181 : // IF NECESSARY, do one final "average" heat balance pass. This is only
182 : // necessary if a radiant system is present and it was actually on for
183 : // part or all of the time step.
184 2799877 : UpdateFinalSurfaceHeatBalance(state);
185 :
186 : // Before we leave the Surface Manager the thermal histories need to be updated
187 2799877 : if (state.dataHeatBal->AnyCTF || state.dataHeatBal->AnyEMPD) {
188 2624518 : UpdateThermalHistories(state); // Update the thermal histories
189 : }
190 :
191 2799877 : if (state.dataHeatBal->AnyCondFD) {
192 1930572 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
193 1772040 : auto const &surface = state.dataSurface->Surface(SurfNum);
194 1772040 : int const ConstrNum = surface.Construction;
195 1772040 : if (ConstrNum <= 0) {
196 0 : continue; // Shading surface, not really a heat transfer surface
197 : }
198 1772040 : if (state.dataConstruction->Construct(ConstrNum).TypeIsWindow) {
199 67284 : continue; // Windows simulated in Window module
200 : }
201 1704756 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CondFD) {
202 50430 : continue;
203 : }
204 1654326 : state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).UpdateMoistureBalance();
205 : }
206 : }
207 :
208 2799877 : ThermalComfort::ManageThermalComfort(state, false); // "Record keeping" for the zone
209 :
210 2799877 : ReportSurfaceHeatBalance(state);
211 2799877 : if (state.dataGlobal->ZoneSizingCalc) {
212 834366 : OutputReportTabular::GatherComponentLoadsSurface(state);
213 : }
214 :
215 2799877 : CalcThermalResilience(state);
216 :
217 2799877 : if (state.dataOutRptTab->displayThermalResilienceSummary) {
218 1086699 : ReportThermalResilience(state);
219 : }
220 :
221 2799877 : if (state.dataOutRptTab->displayCO2ResilienceSummary) {
222 19089 : ReportCO2Resilience(state);
223 : }
224 :
225 2799877 : if (state.dataOutRptTab->displayVisualResilienceSummary) {
226 92393 : ReportVisualResilience(state);
227 : }
228 :
229 2799877 : state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime = false;
230 2799877 : }
231 :
232 : // Beginning Initialization Section of the Module
233 : //******************************************************************************
234 :
235 2800078 : void UpdateVariableAbsorptances(EnergyPlusData &state)
236 : {
237 2800078 : auto &s_mat = state.dataMaterial;
238 2803927 : for (int surfNum : state.dataSurface->AllVaryAbsOpaqSurfaceList) {
239 3849 : auto const &thisConstruct = state.dataConstruction->Construct(state.dataSurface->Surface(surfNum).Construction);
240 3849 : auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
241 3849 : assert(thisMaterial != nullptr);
242 3849 : if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::Scheduled) {
243 0 : if (thisMaterial->absorpThermalVarSched != nullptr) {
244 0 : state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
245 : }
246 0 : if (thisMaterial->absorpSolarVarSched != nullptr) {
247 0 : state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
248 : }
249 : } else {
250 : Real64 triggerValue;
251 3849 : if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceTemperature) {
252 3849 : triggerValue = state.dataHeatBalSurf->SurfTempOut(surfNum);
253 0 : } else if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceReceivedSolarRadiation) {
254 0 : triggerValue = state.dataHeatBal->SurfQRadSWOutIncident(surfNum);
255 : } else { // controlled by heating cooling mode
256 0 : int zoneNum = state.dataSurface->Surface(surfNum).Zone;
257 0 : bool isCooling = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).TotalOutputRequired < 0);
258 0 : triggerValue = static_cast<Real64>(isCooling);
259 : }
260 3849 : if (thisMaterial->absorpThermalVarCurve != nullptr) {
261 3849 : state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) =
262 3849 : max(min(thisMaterial->absorpThermalVarCurve->value(state, triggerValue), 0.9999), 0.0001);
263 : }
264 3849 : if (thisMaterial->absorpSolarVarCurve != nullptr) {
265 3849 : state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) =
266 3849 : max(min(thisMaterial->absorpSolarVarCurve->value(state, triggerValue), 0.9999), 0.0001);
267 : }
268 : }
269 2800078 : }
270 2800078 : }
271 :
272 2800078 : void InitSurfaceHeatBalance(EnergyPlusData &state)
273 : {
274 :
275 : // SUBROUTINE INFORMATION:
276 : // AUTHOR Richard J. Liesen
277 : // DATE WRITTEN January 1998
278 : // MODIFIED Nov. 1999, FCW,
279 : // Move ComputeIntThermalAbsorpFactors
280 : // so called every timestep
281 : // MODIFIED Aug. 2017
282 : // Add initializations of surface data to linked air node value if defined
283 :
284 : // PURPOSE OF THIS SUBROUTINE:
285 : // This subroutine is for surface initializations within the
286 : // heat balance.
287 :
288 : // METHODOLOGY EMPLOYED:
289 : // Uses the status flags to trigger record keeping events.
290 :
291 : // // Using/Aliasing
292 : // using namespace SolarShading;
293 : // using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
294 : // using HeatBalFiniteDiffManager::InitHeatBalFiniteDiff;
295 : // using InternalHeatGains::ManageInternalHeatGains;
296 : //
297 : // auto &Surface = state.dataSurface->Surface;
298 : //
299 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
300 803 : DisplayString(state, "Initializing Outdoor environment for Surfaces");
301 : }
302 :
303 : // set zone level wind dir to global value
304 : // Initialize zone outdoor environmental variables
305 : // Bulk Initialization for Temperatures & WindSpeed
306 : // using the zone, modify the zone Dry/Wet BulbTemps
307 :
308 : // Initialize surface outdoor environmental variables
309 : // Bulk Initialization for Temperatures & WindSpeed
310 : // using the surface centroids, modify the surface Dry/Wet BulbTemps
311 2800078 : DataSurfaces::SetSurfaceOutBulbTempAt(state);
312 2800078 : DataSurfaces::CheckSurfaceOutBulbTempAt(state);
313 :
314 2800078 : DataSurfaces::SetSurfaceWindSpeedAt(state);
315 2800078 : DataSurfaces::SetSurfaceWindDirAt(state);
316 2800078 : if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
317 620862 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
318 613426 : if (state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode > 0) {
319 2706 : auto const &linkedNode = state.dataLoopNodes->Node(state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode);
320 2706 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) = linkedNode.OutAirDryBulb;
321 2706 : state.dataSurface->SurfOutWetBulbTemp(SurfNum) = linkedNode.OutAirWetBulb;
322 2706 : state.dataSurface->SurfOutWindSpeed(SurfNum) = linkedNode.OutAirWindSpeed;
323 2706 : state.dataSurface->SurfOutWindDir(SurfNum) = linkedNode.OutAirWindDir;
324 : }
325 : }
326 : }
327 : // Overwriting surface and zone level environmental data with EMS override value
328 2800078 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
329 45429895 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
330 45010347 : if (state.dataSurface->SurfOutDryBulbTempEMSOverrideOn(SurfNum)) {
331 0 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) = state.dataSurface->SurfOutDryBulbTempEMSOverrideValue(SurfNum);
332 : }
333 45010347 : if (state.dataSurface->SurfOutWetBulbTempEMSOverrideOn(SurfNum)) {
334 0 : state.dataSurface->SurfOutWetBulbTemp(SurfNum) = state.dataSurface->SurfOutWetBulbTempEMSOverrideValue(SurfNum);
335 : }
336 45010347 : if (state.dataSurface->SurfWindSpeedEMSOverrideOn(SurfNum)) {
337 0 : state.dataSurface->SurfOutWindSpeed(SurfNum) = state.dataSurface->SurfWindSpeedEMSOverrideValue(SurfNum);
338 : }
339 45010347 : if (state.dataSurface->SurfWindDirEMSOverrideOn(SurfNum)) {
340 0 : state.dataSurface->SurfOutWindDir(SurfNum) = state.dataSurface->SurfWindDirEMSOverrideValue(SurfNum);
341 : }
342 45010347 : if (state.dataSurface->SurfViewFactorGroundEMSOverrideOn(SurfNum)) {
343 0 : state.dataSurface->Surface(SurfNum).ViewFactorGround = state.dataSurface->SurfViewFactorGroundEMSOverrideValue(SurfNum);
344 : }
345 : }
346 : }
347 :
348 : // Do the Begin Simulation initializations
349 2800078 : if (state.dataGlobal->BeginSimFlag) {
350 803 : AllocateSurfaceHeatBalArrays(state); // Allocate the Module Arrays before any inits take place
351 1606 : state.dataHeatBalSurf->InterZoneWindow =
352 803 : std::any_of(state.dataViewFactor->EnclSolInfo.begin(),
353 1606 : state.dataViewFactor->EnclSolInfo.end(),
354 5198 : [](DataViewFactorInformation::EnclosureViewFactorInformation const &e) { return e.HasInterZoneWindow; });
355 : }
356 2800078 : if (state.dataGlobal->BeginSimFlag || state.dataGlobal->AnySurfPropOverridesInModel) {
357 6010 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
358 10426 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
359 5219 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
360 5219 : int const firstSurf = thisSpace.HTSurfaceFirst;
361 5219 : int const lastSurf = thisSpace.HTSurfaceLast;
362 50843 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
363 45624 : int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // SurfActiveConstruction set above
364 45624 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
365 45624 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
366 45624 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
367 45624 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisConstruct.OutsideRoughness;
368 45624 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisConstruct.OutsideAbsorpSolar;
369 45624 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisConstruct.OutsideAbsorpThermal;
370 : }
371 5207 : }
372 : }
373 : }
374 :
375 : // variable thermal solar absorptance overrides
376 2800078 : UpdateVariableAbsorptances(state);
377 :
378 : // Do the Begin Environment initializations
379 2800078 : if (state.dataGlobal->BeginEnvrnFlag) {
380 6396 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
381 803 : DisplayString(state, "Initializing Temperature and Flux Histories");
382 : }
383 6396 : InitThermalAndFluxHistories(state); // Set initial temperature and flux histories
384 : }
385 :
386 : // Calc movable insulation properties
387 2800078 : if (state.dataSurface->AnyMovableInsulation) {
388 10122 : EvalOutsideMovableInsulation(state);
389 10122 : EvalInsideMovableInsulation(state);
390 : }
391 :
392 : // There are no daily initializations done in this portion of the surface heat balance
393 : // There are no hourly initializations done in this portion of the surface heat balance
394 :
395 2800078 : GetGroundSurfacesReflectanceAverage(state);
396 :
397 : // Need to be called each timestep in order to check if surface points to new construction (EMS) and if does then
398 : // complex fenestration needs to be initialized for additional states
399 2800078 : SolarShading::TimestepInitComplexFenestration(state);
400 :
401 : // Calculate exterior-surface multipliers that account for anisotropy of
402 : // sky radiance
403 2800078 : if (state.dataEnvrn->SunIsUp && state.dataEnvrn->DifSolarRad > 0.0) {
404 916956 : SolarShading::AnisoSkyViewFactors(state);
405 : } else {
406 1883122 : state.dataSolarShading->SurfAnisoSkyMult = 0.0;
407 : }
408 :
409 : // Set shading flag for exterior windows (except flags related to daylighting) and
410 : // window construction (unshaded or shaded) to be used in heat balance calculation
411 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
412 803 : DisplayString(state, "Initializing Window Shading");
413 : }
414 :
415 2800078 : SolarShading::WindowShadingManager(state);
416 :
417 2800078 : SolarShading::CheckGlazingShadingStatusChange(state);
418 :
419 : // Calculate factors that are used to determine how much long-wave radiation from internal
420 : // gains is absorbed by interior surfaces
421 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
422 803 : DisplayString(state, "Computing Interior Absorption Factors");
423 : }
424 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
425 803 : HeatBalanceIntRadExchange::InitInteriorRadExchange(state);
426 : }
427 2800078 : ComputeIntThermalAbsorpFactors(state);
428 :
429 : // Calculate factors for diffuse solar absorbed by room surfaces and interior shades
430 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
431 803 : DisplayString(state, "Computing Interior Diffuse Solar Absorption Factors");
432 : }
433 2800078 : ComputeIntSWAbsorpFactors(state);
434 :
435 2800078 : if (state.dataHeatBalSurf->InterZoneWindow) {
436 12147 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
437 6 : DisplayString(state, "Computing Interior Diffuse Solar Exchange through Interzone Windows");
438 : }
439 12147 : ComputeDifSolExcZonesWIZWindows(state);
440 : }
441 :
442 2800078 : Dayltg::initDaylighting(state, state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime);
443 :
444 5600156 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
445 2800078 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, "Main");
446 :
447 2800078 : if (state.dataSurface->AirflowWindows) {
448 4044 : SolarShading::WindowGapAirflowControl(state);
449 : }
450 :
451 : // The order of these initializations is important currently. Over time we hope to
452 : // take the appropriate parts of these inits to the other heat balance managers
453 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
454 803 : DisplayString(state, "Initializing Solar Heat Gains");
455 : }
456 :
457 2800078 : InitSolarHeatGains(state);
458 :
459 2800078 : Dayltg::manageDaylighting(state);
460 :
461 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
462 803 : DisplayString(state, "Initializing Internal Heat Gains");
463 : }
464 2800078 : InternalHeatGains::ManageInternalHeatGains(state, false);
465 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
466 803 : DisplayString(state, "Initializing Interior Solar Distribution");
467 : }
468 2800078 : InitIntSolarDistribution(state);
469 :
470 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
471 803 : DisplayString(state, "Initializing Interior Convection Coefficients");
472 : }
473 2800078 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempInTmp);
474 :
475 2800078 : if (state.dataGlobal->BeginSimFlag) { // Now's the time to report surfaces, if desired
476 : // if (firstTime) CALL DisplayString('Reporting Surfaces')
477 : // CALL ReportSurfaces
478 803 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
479 803 : DisplayString(state, "Gathering Information for Predefined Reporting");
480 : }
481 803 : GatherForPredefinedReport(state);
482 : }
483 :
484 : // Initialize the temperature history terms for conduction through the surfaces
485 2800078 : if (state.dataHeatBal->AnyCondFD) {
486 158532 : HeatBalFiniteDiffManager::InitHeatBalFiniteDiff(state);
487 : }
488 :
489 22623034 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
490 39694512 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
491 19871556 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
492 19871556 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
493 19871556 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
494 167531295 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
495 147659739 : auto const &surface = state.dataSurface->Surface(SurfNum);
496 147659739 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
497 2094168 : surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) {
498 1944150 : continue;
499 : }
500 : // Outside surface temp of "normal" windows not needed in Window5 calculation approach
501 : // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
502 :
503 145715589 : int const ConstrNum = surface.Construction;
504 145715589 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
505 145715589 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) = 0.0;
506 145715589 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) = 0.0;
507 145715589 : if (construct.NumCTFTerms <= 1) {
508 9355335 : continue;
509 : }
510 :
511 1047114040 : for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
512 : // [ l11 ] == ( 1, Term + 1, SurfNum ), [ l12 ] == ( 1, Term + 1, SurfNum )
513 :
514 : // Sign convention for the various terms in the following two equations
515 : // is based on the form of the Conduction Transfer Function equation
516 : // given by:
517 : // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old)
518 : // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old)
519 : // In both equations, flux is positive from outside to inside.
520 :
521 : // Tuned Aliases and linear indexing
522 910753786 : Real64 const ctf_cross(construct.CTFCross[Term]);
523 :
524 910753786 : Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
525 910753786 : Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
526 910753786 : Real64 const QH11(state.dataHeatBalSurf->SurfOutsideFluxHist(Term + 1)(SurfNum));
527 910753786 : Real64 const QH12(state.dataHeatBalSurf->SurfInsideFluxHist(Term + 1)(SurfNum));
528 910753786 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) +=
529 910753786 : ctf_cross * TH11 - construct.CTFInside[Term] * TH12 + construct.CTFFlux[Term] * QH12;
530 :
531 910753786 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) +=
532 910753786 : construct.CTFOutside[Term] * TH11 - ctf_cross * TH12 + construct.CTFFlux[Term] * QH11;
533 : }
534 : }
535 19822956 : }
536 : }
537 2800078 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
538 646938 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
539 976482 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
540 488241 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
541 488241 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
542 488241 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
543 3778335 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
544 3290094 : auto const &surface = state.dataSurface->Surface(SurfNum);
545 3290094 : int const ConstrNum = surface.Construction;
546 3290094 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
547 3290094 : if (!construct.SourceSinkPresent) {
548 2730924 : continue;
549 : }
550 559170 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
551 161478 : surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) {
552 161478 : continue;
553 : }
554 397692 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) = 0.0;
555 397692 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) = 0.0;
556 397692 : if (construct.NumCTFTerms <= 1) {
557 0 : continue;
558 : }
559 4376034 : for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
560 3978342 : Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
561 3978342 : Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
562 3978342 : Real64 const QsrcHist1(state.dataHeatBalSurf->SurfQsrcHist(SurfNum, Term + 1));
563 :
564 3978342 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += construct.CTFSourceIn[Term] * QsrcHist1;
565 :
566 3978342 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += construct.CTFSourceOut[Term] * QsrcHist1;
567 :
568 3978342 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) +=
569 3978342 : construct.CTFTSourceOut[Term] * TH11 + construct.CTFTSourceIn[Term] * TH12 + construct.CTFTSourceQ[Term] * QsrcHist1 +
570 3978342 : construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTsrcHist(SurfNum, Term + 1);
571 :
572 3978342 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) +=
573 3978342 : construct.CTFTUserOut[Term] * TH11 + construct.CTFTUserIn[Term] * TH12 + construct.CTFTUserSource[Term] * QsrcHist1 +
574 3978342 : construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTuserHist(SurfNum, Term + 1);
575 : }
576 : }
577 488241 : } // ...end of surfaces DO loop for initializing temperature history terms for the surface heat balances
578 : }
579 : }
580 :
581 : // Zero out all of the radiant system heat balance coefficient arrays
582 22623034 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
583 39694512 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
584 19871556 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
585 19871556 : int const firstSurf = thisSpace.HTSurfaceFirst;
586 19871556 : int const lastSurf = thisSpace.HTSurfaceLast;
587 189903633 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
588 170032077 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) = 0.0;
589 170032077 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) = 0.0;
590 170032077 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) = 0.0;
591 170032077 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = 0.0;
592 170032077 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = 0.0;
593 170032077 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = 0.0;
594 :
595 170032077 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
596 170032077 : state.dataHeatBalFanSys->QPVSysSource(SurfNum) = 0.0;
597 170032077 : state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = 0.0;
598 170032077 : state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = 0.0;
599 :
600 : } // ...end of Zone Surf loop
601 19822956 : }
602 : } // ...end of Zone loop
603 :
604 3023890 : for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
605 223812 : auto &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
606 223812 : thisSurfQRadFromHVAC.HTRadSys = 0.0;
607 223812 : thisSurfQRadFromHVAC.HWBaseboard = 0.0;
608 223812 : thisSurfQRadFromHVAC.SteamBaseboard = 0.0;
609 223812 : thisSurfQRadFromHVAC.ElecBaseboard = 0.0;
610 223812 : thisSurfQRadFromHVAC.CoolingPanel = 0.0;
611 2800078 : }
612 :
613 2800078 : if (state.dataGlobal->ZoneSizingCalc) {
614 834366 : GatherComponentLoadsSurfAbsFact(state);
615 : }
616 :
617 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
618 803 : DisplayString(state, "Completed Initializing Surface Heat Balance");
619 : }
620 2800078 : state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime = false;
621 2800078 : }
622 :
623 803 : void GatherForPredefinedReport(EnergyPlusData &state)
624 : {
625 :
626 : // SUBROUTINE INFORMATION:
627 : // AUTHOR Jason Glazer
628 : // DATE WRITTEN August 2006
629 :
630 : // PURPOSE OF THIS SUBROUTINE:
631 : // This subroutine reports the information for the predefined reports
632 : // related to envelope components.
633 :
634 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
635 803 : std::string surfName;
636 : Real64 mult;
637 : Real64 curAzimuth;
638 : Real64 curTilt;
639 : Real64 windowArea;
640 : Real64 frameWidth;
641 : Real64 frameArea;
642 : Real64 dividerArea;
643 : // counts for object count report
644 803 : int SurfaceClassCount = int(DataSurfaces::SurfaceClass::Num);
645 803 : Array1D_int numSurfaces(SurfaceClassCount);
646 803 : Array1D_int numExtSurfaces(SurfaceClassCount);
647 : int frameDivNum;
648 : bool isExterior;
649 803 : Array1D<Real64> computedNetArea; // holds the gross wall area minus the window and door areas
650 :
651 : // the following variables are for the CalcNominalWindowCond call but only SHGCSummer is needed
652 : Real64 nomCond;
653 : Real64 SHGCSummer;
654 : Real64 TransSolNorm;
655 : Real64 TransVisNorm;
656 : Real64 nomUfact;
657 : int errFlag;
658 : int curWSC;
659 : // following variables are totals for fenestration table
660 803 : Real64 windowAreaWMult(0.0);
661 803 : Real64 fenTotArea(0.0);
662 803 : Real64 fenTotAreaNorth(0.0);
663 803 : Real64 fenTotAreaNonNorth(0.0);
664 803 : Real64 ufactArea(0.0);
665 803 : Real64 ufactAreaNorth(0.0);
666 803 : Real64 ufactAreaNonNorth(0.0);
667 803 : Real64 shgcArea(0.0);
668 803 : Real64 shgcAreaNorth(0.0);
669 803 : Real64 shgcAreaNonNorth(0.0);
670 803 : Real64 vistranArea(0.0);
671 803 : Real64 vistranAreaNorth(0.0);
672 803 : Real64 vistranAreaNonNorth(0.0);
673 803 : Real64 intFenTotArea(0.0);
674 803 : Real64 intUfactArea(0.0);
675 803 : Real64 intShgcArea(0.0);
676 803 : Real64 intVistranArea(0.0);
677 : bool isNorth;
678 :
679 803 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WinShadingType::Num)> WindowShadingTypeNames = {
680 : "No Shade", // 0
681 : "Shade Off", // 1
682 : "Interior Shade",
683 : "Switchable Glazing",
684 : "Exterior Shade",
685 : "Exterior Screen",
686 : "Interior Blind",
687 : "Exterior Blind",
688 : "Between Glass Shade",
689 : "Between Glass Blind",
690 : };
691 :
692 803 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WindowShadingControlType::Num)> WindowShadingControlTypeNames = {
693 : "Uncontrolled",
694 : "AlwaysOn",
695 : "AlwaysOff",
696 : "OnIfScheduleAllows",
697 : "OnIfHighSolarOnWindow",
698 : "OnIfHighHorizontalSolar",
699 : "OnIfHighOutdoorAirTemperature",
700 : "OnIfHighZoneAirTemperature",
701 : "OnIfHighZoneCooling",
702 : "OnIfHighGlare",
703 : "MeetDaylightIlluminanceSetpoint",
704 : "OnNightIfLowOutdoorTempAndOffDay",
705 : "OnNightIfLowInsideTempAndOffDay",
706 : "OnNightIfHeatingAndOffDay",
707 : "OnNightIfLowOutdoorTempAndOnDayIfCooling",
708 : "OnNightIfHeatingAndOnDayIfCooling",
709 : "OffNightAndOnDayIfCoolingAndHighSolarOnWindow",
710 : "OnNightAndOnDayIfCoolingAndHighSolarOnWindow",
711 : "OnIfHighOutdoorAirTempAndHighSolarOnWindow",
712 : "OnIfHighOutdoorAirTempAndHighHorizontalSolar",
713 : "OnIfHighZoneAirTempAndHighSolarOnWindow",
714 : "OnIfHighZoneAirTempAndHighHorizontalSolar"};
715 :
716 803 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcProductNames = {
717 : "CasementDouble", "CasementSingle", "DualAction",
718 : "Fixed", "Garage", "Greenhouse",
719 : "HingedEscape", "HorizontalSlider", "Jal",
720 : "Pivoted", "ProjectingSingle", "ProjectingDual",
721 : "DoorSidelite", "Skylight", "SlidingPatioDoor",
722 : "CurtainWall", "SpandrelPanel", "SideHingedDoor",
723 : "DoorTransom", "TropicalAwning", "TubularDaylightingDevice",
724 : "VerticalSlider"};
725 :
726 803 : constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcWidth = {
727 : // width in meters from Table 4-3 of NFRC 100-2020
728 : 1.200, 0.600, 1.200, // CasementDouble, CasementSingle, DualAction,
729 : 1.200, 2.134, 1.500, // Fixed, Garage, Greenhouse,
730 : 1.500, 1.500, 1.200, // HingedEscape, HorizontalSlider, Jal,
731 : 1.200, 1.500, 1.500, // Pivoted, ProjectingSingle, ProjectingDual,
732 : 0.600, 1.200, 2.000, // DoorSidelite, Skylight, SlidingPatioDoor,
733 : 2.000, 2.000, 1.920, // CurtainWall, SpandrelPanel, SideHingedDoor,
734 : 2.000, 1.500, 0.350, // DoorTransom, TropicalAwning, TubularDaylightingDevice,
735 : 1.200 // VerticalSlider,
736 : };
737 :
738 803 : constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcHeight = {
739 : // height in meters from Table 4-3 of NFRC 100-2020
740 : 1.500, 1.500, 1.500, // CasementDouble, CasementSingle, DualAction,
741 : 1.500, 2.134, 1.200, // Fixed, Garage, Greenhouse,
742 : 1.200, 1.200, 1.500, // HingedEscape, HorizontalSlider, Jal,
743 : 1.500, 1.200, 0.600, // Pivoted, ProjectingSingle, ProjectingDual,
744 : 2.090, 1.200, 2.000, // DoorSidelite, Skylight, SlidingPatioDoor,
745 : 2.000, 1.200, 2.090, // CurtainWall, SpandrelPanel, SideHingedDoor,
746 : 0.600, 1.200, 0.350, // DoorTransom, TropicalAwning, TubularDaylightingDevice,
747 : 1.500 // VerticalSlider,
748 : };
749 :
750 803 : constexpr std::array<DataSurfaces::NfrcVisionType, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcVision = {
751 : DataSurfaces::NfrcVisionType::DualHorizontal, DataSurfaces::NfrcVisionType::Single,
752 : DataSurfaces::NfrcVisionType::DualVertical, // CasementDouble, CasementSingle, DualAction,
753 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
754 : DataSurfaces::NfrcVisionType::Single, // Fixed, Garage, Greenhouse,
755 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::DualHorizontal,
756 : DataSurfaces::NfrcVisionType::Single, // HingedEscape, HorizontalSlider, Jal,
757 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
758 : DataSurfaces::NfrcVisionType::DualHorizontal, // Pivoted, ProjectingSingle, ProjectingDual,
759 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
760 : DataSurfaces::NfrcVisionType::DualHorizontal, // DoorSidelite, Skylight, SlidingPatioDoor,
761 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
762 : DataSurfaces::NfrcVisionType::Single, // CurtainWall, SpandrelPanel, SideHingedDoor,
763 : DataSurfaces::NfrcVisionType::Single, DataSurfaces::NfrcVisionType::Single,
764 : DataSurfaces::NfrcVisionType::Single, // DoorTransom, TropicalAwning, TubularDaylightingDevice,
765 : DataSurfaces::NfrcVisionType::DualVertical // VerticalSlider
766 : };
767 :
768 803 : numSurfaces = 0;
769 803 : numExtSurfaces = 0;
770 :
771 803 : computedNetArea.allocate(state.dataSurface->TotSurfaces);
772 803 : computedNetArea = 0.0; // start at zero, add wall area and subtract window and door area
773 :
774 : // set up for EIO <FenestrationAssembly> output
775 803 : if (state.dataHeatBal->TotFrameDivider > 0 && state.dataGeneral->Constructions) {
776 18 : print(state.files.eio,
777 : "{}\n",
778 : "! <FenestrationAssembly>,Construction Name,Frame and Divider Name,NFRC Product Type,"
779 : "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
780 : }
781 : static constexpr std::string_view FenestrationAssemblyFormat("FenestrationAssembly,{},{},{},{:.3R},{:.3R},{:.3R}\n");
782 803 : std::vector<std::pair<int, int>> uniqConsFrame;
783 803 : std::pair<int, int> consAndFrame;
784 :
785 : // set up for EIO <FenestrationShadedState> output
786 803 : bool fenestrationShadedStateHeaderShown(false);
787 : static constexpr std::string_view FenestrationShadedStateFormat("FenestrationShadedState,{},{:.3R},{:.3R},{:.3R},{},{},{:.3R},{:.3R},{:.3R}\n");
788 803 : std::vector<std::pair<int, int>> uniqShdConsFrame;
789 803 : std::pair<int, int> shdConsAndFrame;
790 :
791 48135 : for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
792 47332 : auto &surface = state.dataSurface->Surface(iSurf);
793 47332 : surfName = surface.Name;
794 : // only exterior surfaces including underground
795 47332 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
796 25201 : (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
797 22355 : isExterior = true;
798 22355 : switch (surface.Class) {
799 13915 : case DataSurfaces::SurfaceClass::Wall:
800 : case DataSurfaces::SurfaceClass::Floor:
801 : case DataSurfaces::SurfaceClass::Roof: {
802 13915 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
803 13915 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
804 13915 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
805 13915 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
806 13915 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpCons, surfName, construct.Name);
807 13915 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpZone, surfName, thisZone.Name);
808 13915 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpSpace, surfName, thisSpace.Name);
809 13915 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
810 13915 : OutputReportPredefined::PreDefTableEntry(
811 13915 : state, state.dataOutRptPredefined->pdchOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
812 13915 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpGrArea, surfName, surface.GrossArea * mult);
813 13915 : computedNetArea(iSurf) += surface.GrossArea * mult;
814 13915 : curAzimuth = surface.Azimuth;
815 : // Round to two decimals, like the display in tables
816 : // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
817 13915 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
818 13915 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpAzimuth, surfName, curAzimuth);
819 13915 : curTilt = surface.Tilt;
820 13915 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpTilt, surfName, curTilt);
821 13915 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
822 9277 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
823 2389 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "N");
824 6888 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
825 2204 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "E");
826 4684 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
827 2413 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "S");
828 2271 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
829 2271 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "W");
830 : }
831 : }
832 13915 : } break;
833 6349 : case DataSurfaces::SurfaceClass::Window:
834 : case DataSurfaces::SurfaceClass::TDD_Dome: {
835 6349 : auto &construct = state.dataConstruction->Construct(surface.Construction);
836 6349 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
837 6349 : mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
838 6349 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
839 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenCons, surfName, construct.Name);
840 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenZone, surfName, thisZone.Name);
841 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSpace, surfName, thisSpace.Name);
842 : // if the construction report is requested the SummerSHGC is already calculated
843 6349 : if (construct.SummerSHGC != 0) {
844 5681 : SHGCSummer = construct.SummerSHGC;
845 5681 : TransVisNorm = construct.VisTransNorm;
846 : } else {
847 : // must calculate Summer SHGC
848 668 : if (!construct.WindowTypeEQL) {
849 668 : Window::CalcNominalWindowCond(state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
850 668 : construct.SummerSHGC = SHGCSummer;
851 668 : construct.VisTransNorm = TransVisNorm;
852 668 : construct.SolTransNorm = TransSolNorm;
853 : }
854 : }
855 : // include the frame area if present
856 6349 : windowArea = surface.GrossArea;
857 6349 : frameArea = 0.0;
858 6349 : dividerArea = 0.0;
859 6349 : frameDivNum = surface.FrameDivider;
860 6349 : if (frameDivNum != 0) {
861 381 : auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
862 381 : frameWidth = frameDivider.FrameWidth;
863 381 : frameArea = (surface.Height + 2.0 * frameWidth) * (surface.Width + 2.0 * frameWidth) - (surface.Height * surface.Width);
864 381 : windowArea += frameArea;
865 381 : dividerArea = frameDivider.DividerWidth * (frameDivider.HorDividers * surface.Width + frameDivider.VertDividers * surface.Height -
866 381 : frameDivider.HorDividers * frameDivider.VertDividers * frameDivider.DividerWidth);
867 381 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameDivName, surfName, frameDivider.Name);
868 381 : OutputReportPredefined::PreDefTableEntry(
869 381 : state, state.dataOutRptPredefined->pdchFenFrameConductance, surfName, frameDivider.FrameConductance, 3);
870 381 : OutputReportPredefined::PreDefTableEntry(
871 381 : state, state.dataOutRptPredefined->pdchFenDividerConductance, surfName, frameDivider.DividerConductance, 3);
872 :
873 : // report the selected NRFC product type (specific sizes) and the NFRC rating for the assembly (glass + frame + divider)
874 381 : std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
875 381 : const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
876 381 : const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
877 381 : const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
878 :
879 381 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemNfrcType, surfName, NFRCname);
880 :
881 381 : Real64 uValueAssembly = 0.0;
882 381 : Real64 shgcAssembly = 0.0;
883 381 : Real64 vtAssembly = 0.0;
884 :
885 381 : Window::GetWindowAssemblyNfrcForReport(
886 : state, iSurf, surface.Construction, windowWidth, windowHeight, vision, uValueAssembly, shgcAssembly, vtAssembly);
887 381 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
888 0 : state.dataHeatBal->NominalU(surface.Construction) =
889 0 : Window::GetIGUUValueForNFRCReport(state, iSurf, surface.Construction, windowWidth, windowHeight);
890 0 : SHGCSummer = Window::GetSHGCValueForNFRCReporting(state, iSurf, surface.Construction, windowWidth, windowHeight);
891 : }
892 381 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemUfact, surfName, uValueAssembly, 3);
893 381 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemSHGC, surfName, shgcAssembly, 3);
894 381 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemVisTr, surfName, vtAssembly, 3);
895 :
896 : // output EIO <FenestrationAssembly> for each unique combination of construction and frame/divider
897 381 : if (state.dataGeneral->Constructions) {
898 340 : consAndFrame = std::make_pair(surface.Construction, frameDivNum);
899 340 : if (std::find(uniqConsFrame.begin(), uniqConsFrame.end(), consAndFrame) == uniqConsFrame.end()) {
900 30 : uniqConsFrame.push_back(consAndFrame);
901 30 : print(state.files.eio,
902 : FenestrationAssemblyFormat,
903 30 : construct.Name,
904 30 : frameDivider.Name,
905 : NFRCname,
906 : uValueAssembly,
907 : shgcAssembly,
908 : vtAssembly);
909 : }
910 : }
911 : }
912 6349 : windowAreaWMult = windowArea * mult;
913 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAreaOf1, surfName, windowArea);
914 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameAreaOf1, surfName, frameArea);
915 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDividerAreaOf1, surfName, dividerArea);
916 12698 : OutputReportPredefined::PreDefTableEntry(
917 6349 : state, state.dataOutRptPredefined->pdchFenGlassAreaOf1, surfName, windowArea - (frameArea + dividerArea));
918 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, surfName, windowAreaWMult);
919 6349 : computedNetArea(surface.BaseSurf) -= windowAreaWMult;
920 6349 : nomUfact = state.dataHeatBal->NominalU(surface.Construction);
921 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, surfName, nomUfact, 3);
922 :
923 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, surfName, SHGCSummer, 3);
924 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, surfName, TransVisNorm, 3);
925 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenParent, surfName, surface.BaseSurfName);
926 6349 : curAzimuth = surface.Azimuth;
927 : // Round to two decimals, like the display in tables
928 6349 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
929 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAzimuth, surfName, curAzimuth);
930 6349 : isNorth = false;
931 6349 : curTilt = surface.Tilt;
932 6349 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenTilt, surfName, curTilt);
933 6349 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
934 5952 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
935 1479 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "N");
936 1479 : isNorth = true;
937 4473 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
938 1089 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "E");
939 3384 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
940 2298 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "S");
941 1086 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
942 1086 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "W");
943 : }
944 : }
945 :
946 : // Report table for every shading control state
947 6349 : const unsigned int totalStates = surface.windowShadingControlList.size();
948 6349 : if (frameDivNum != 0) {
949 381 : auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
950 422 : for (unsigned int i = 0; i < totalStates; ++i) {
951 41 : const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
952 41 : const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
953 41 : const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
954 :
955 41 : const int stateConstrNum = surface.shadedConstructionList[i];
956 41 : const Real64 stateUValue = Window::GetIGUUValueForNFRCReport(state, iSurf, stateConstrNum, windowWidth, windowHeight);
957 41 : const Real64 stateSHGC = Window::GetSHGCValueForNFRCReporting(state, iSurf, stateConstrNum, windowWidth, windowHeight);
958 41 : std::string const &constructionName = state.dataConstruction->Construct(stateConstrNum).Name;
959 :
960 82 : OutputReportPredefined::PreDefTableEntry(
961 41 : state, state.dataOutRptPredefined->pdchFenShdFrameDiv, constructionName, frameDivider.Name);
962 82 : OutputReportPredefined::PreDefTableEntry(
963 82 : state, state.dataOutRptPredefined->pdchFenShdUfact, constructionName, stateUValue, 3);
964 41 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenShdSHGC, constructionName, stateSHGC, 3);
965 41 : OutputReportPredefined::PreDefTableEntry(state,
966 41 : state.dataOutRptPredefined->pdchFenShdVisTr,
967 : constructionName,
968 41 : state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
969 41 : 3);
970 :
971 41 : Real64 stateAssemblyUValue{0.0};
972 41 : Real64 stateAssemblySHGC{0.0};
973 41 : Real64 stateAssemblyVT{0.0};
974 :
975 41 : Window::GetWindowAssemblyNfrcForReport(
976 : state, iSurf, stateConstrNum, windowWidth, windowHeight, vision, stateAssemblyUValue, stateAssemblySHGC, stateAssemblyVT);
977 :
978 41 : std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
979 82 : OutputReportPredefined::PreDefTableEntry(
980 41 : state, state.dataOutRptPredefined->pdchFenShdAssemNfrcType, constructionName, NFRCname);
981 :
982 82 : OutputReportPredefined::PreDefTableEntry(
983 82 : state, state.dataOutRptPredefined->pdchFenShdAssemUfact, constructionName, stateAssemblyUValue, 3);
984 82 : OutputReportPredefined::PreDefTableEntry(
985 82 : state, state.dataOutRptPredefined->pdchFenShdAssemSHGC, constructionName, stateAssemblySHGC, 3);
986 82 : OutputReportPredefined::PreDefTableEntry(
987 82 : state, state.dataOutRptPredefined->pdchFenShdAssemVisTr, constructionName, stateAssemblyVT, 3);
988 :
989 41 : if (state.dataGeneral->Constructions) {
990 23 : if (!fenestrationShadedStateHeaderShown) {
991 4 : print(state.files.eio,
992 : "{}\n",
993 : "! <FenestrationShadedState>,Construction Name,Glass U-Factor {W/m2-K},"
994 : "Glass SHGC, Glass Visible Transmittance, Frame and Divider Name,NFRC Product Type,"
995 : "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
996 4 : fenestrationShadedStateHeaderShown = true;
997 : }
998 :
999 23 : shdConsAndFrame = std::make_pair(stateConstrNum, frameDivNum);
1000 23 : if (std::find(uniqShdConsFrame.begin(), uniqShdConsFrame.end(), shdConsAndFrame) == uniqShdConsFrame.end()) {
1001 14 : uniqShdConsFrame.push_back(shdConsAndFrame);
1002 14 : print(state.files.eio,
1003 : FenestrationShadedStateFormat,
1004 : constructionName,
1005 : stateUValue,
1006 : stateSHGC,
1007 14 : state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
1008 14 : frameDivider.Name,
1009 : NFRCname,
1010 : stateAssemblyUValue,
1011 : stateAssemblySHGC,
1012 : stateAssemblyVT);
1013 : }
1014 : }
1015 : }
1016 : }
1017 :
1018 6349 : curWSC = surface.activeWindowShadingControl;
1019 : // compute totals for area weighted averages
1020 6349 : fenTotArea += windowAreaWMult;
1021 6349 : ufactArea += nomUfact * windowAreaWMult;
1022 6349 : shgcArea += SHGCSummer * windowAreaWMult;
1023 6349 : vistranArea += TransVisNorm * windowAreaWMult;
1024 6349 : if (isNorth) {
1025 1479 : fenTotAreaNorth += windowAreaWMult;
1026 1479 : ufactAreaNorth += nomUfact * windowAreaWMult;
1027 1479 : shgcAreaNorth += SHGCSummer * windowAreaWMult;
1028 1479 : vistranAreaNorth += TransVisNorm * windowAreaWMult;
1029 : } else {
1030 4870 : fenTotAreaNonNorth += windowAreaWMult;
1031 4870 : ufactAreaNonNorth += nomUfact * windowAreaWMult;
1032 4870 : shgcAreaNonNorth += SHGCSummer * windowAreaWMult;
1033 4870 : vistranAreaNonNorth += TransVisNorm * windowAreaWMult;
1034 : }
1035 : // shading
1036 6349 : if (surface.HasShadeControl) {
1037 151 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "Yes");
1038 302 : OutputReportPredefined::PreDefTableEntry(
1039 302 : state, state.dataOutRptPredefined->pdchWscName, surfName, state.dataSurface->WindowShadingControl(curWSC).Name);
1040 : // shading report
1041 302 : OutputReportPredefined::PreDefTableEntry(
1042 : state,
1043 151 : state.dataOutRptPredefined->pdchWscShading,
1044 : surfName,
1045 151 : WindowShadingTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).ShadingType)]);
1046 302 : OutputReportPredefined::PreDefTableEntry(
1047 : state,
1048 151 : state.dataOutRptPredefined->pdchWscControl,
1049 : surfName,
1050 151 : WindowShadingControlTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).shadingControlType)]);
1051 :
1052 : // output list of all possible shading constructions for shaded windows including those with storms
1053 151 : std::string names;
1054 306 : for (int construction : surface.shadedConstructionList) {
1055 155 : if (!names.empty()) {
1056 4 : names.append("; ");
1057 : }
1058 155 : names.append(state.dataConstruction->Construct(construction).Name);
1059 151 : }
1060 151 : for (int construction : surface.shadedStormWinConstructionList) {
1061 0 : if (!names.empty()) {
1062 0 : names.append("; ");
1063 : }
1064 0 : names.append(state.dataConstruction->Construct(construction).Name);
1065 151 : }
1066 151 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscShadCons, surfName, names);
1067 :
1068 151 : if (state.dataSurface->WindowShadingControl(curWSC).GlareControlIsActive) {
1069 30 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "Yes");
1070 : } else {
1071 121 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "No");
1072 : }
1073 151 : } else {
1074 6198 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "No");
1075 : }
1076 6349 : } break;
1077 401 : case DataSurfaces::SurfaceClass::Door: {
1078 401 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1079 401 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1080 401 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1081 802 : OutputReportPredefined::PreDefTableEntry(
1082 802 : state, state.dataOutRptPredefined->pdchDrCons, surfName, state.dataConstruction->Construct(surface.Construction).Name);
1083 401 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrZone, surfName, thisZone.Name);
1084 401 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrSpace, surfName, thisSpace.Name);
1085 401 : OutputReportPredefined::PreDefTableEntry(
1086 401 : state, state.dataOutRptPredefined->pdchDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1087 401 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrGrArea, surfName, surface.GrossArea * mult);
1088 401 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrParent, surfName, surface.BaseSurfName);
1089 401 : computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
1090 401 : } break;
1091 1690 : default:
1092 1690 : break;
1093 : }
1094 22355 : } else {
1095 : // interior surfaces
1096 24977 : isExterior = false;
1097 24977 : if ((surface.Class == DataSurfaces::SurfaceClass::Wall) || (surface.Class == DataSurfaces::SurfaceClass::Floor) ||
1098 6320 : (surface.Class == DataSurfaces::SurfaceClass::Roof) || (surface.Class == DataSurfaces::SurfaceClass::IntMass)) {
1099 24883 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1100 24883 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1101 24883 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1102 24883 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1103 24883 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpCons, surfName, construct.Name);
1104 24883 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpZone, surfName, thisZone.Name);
1105 24883 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpSpace, surfName, thisSpace.Name);
1106 24883 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAdjSurf, surfName, surface.ExtBoundCondName);
1107 49766 : OutputReportPredefined::PreDefTableEntry(
1108 24883 : state, state.dataOutRptPredefined->pdchIntOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
1109 24883 : OutputReportPredefined::PreDefTableEntry(
1110 24883 : state, state.dataOutRptPredefined->pdchIntOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1111 24883 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpGrArea, surfName, surface.GrossArea * mult);
1112 24883 : computedNetArea(iSurf) += surface.GrossArea * mult;
1113 24883 : curAzimuth = surface.Azimuth;
1114 : // Round to two decimals, like the display in tables
1115 : // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
1116 24883 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
1117 24883 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAzimuth, surfName, curAzimuth);
1118 24883 : curTilt = surface.Tilt;
1119 24883 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpTilt, surfName, curTilt);
1120 24883 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
1121 16511 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
1122 6101 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "N");
1123 10410 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
1124 3423 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "E");
1125 6987 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
1126 3567 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "S");
1127 3420 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
1128 3420 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "W");
1129 : }
1130 : }
1131 : // interior window report
1132 24977 : } else if ((surface.Class == DataSurfaces::SurfaceClass::Window) || (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)) {
1133 14 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1134 14 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1135 14 : mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
1136 14 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1137 14 : if (!has_prefix(surface.Name,
1138 : "iz-")) { // don't count created interzone surfaces that are mirrors of other surfaces
1139 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenCons, surfName, construct.Name);
1140 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenZone, surfName, thisZone.Name);
1141 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSpace, surfName, thisSpace.Name);
1142 : // include the frame area if present
1143 12 : windowArea = surface.GrossArea;
1144 12 : if (surface.FrameDivider != 0) {
1145 0 : frameWidth = state.dataSurface->FrameDivider(surface.FrameDivider).FrameWidth;
1146 0 : frameArea = (surface.Height + 2 * frameWidth) * (surface.Width + 2 * frameWidth) - (surface.Height * surface.Width);
1147 0 : windowArea += frameArea;
1148 : }
1149 12 : windowAreaWMult = windowArea * mult;
1150 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenAreaOf1, surfName, windowArea);
1151 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, surfName, windowAreaWMult);
1152 12 : computedNetArea(surface.BaseSurf) -= windowAreaWMult;
1153 12 : nomUfact = state.dataHeatBal->NominalU(surface.Construction);
1154 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, surfName, nomUfact, 3);
1155 12 : if (!construct.TypeIsAirBoundary) {
1156 : // Solar properties not applicable for air boundary surfaces
1157 : // if the construction report is requested the SummerSHGC is already calculated
1158 12 : if (construct.SummerSHGC != 0) {
1159 12 : SHGCSummer = construct.SummerSHGC;
1160 12 : TransVisNorm = construct.VisTransNorm;
1161 : } else {
1162 : // must calculate Summer SHGC
1163 0 : if (!construct.WindowTypeEQL) {
1164 0 : Window::CalcNominalWindowCond(
1165 : state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
1166 : }
1167 : }
1168 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, surfName, SHGCSummer, 3);
1169 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, surfName, TransVisNorm, 3);
1170 : // compute totals for area weighted averages
1171 12 : intShgcArea += SHGCSummer * windowAreaWMult;
1172 12 : intVistranArea += TransVisNorm * windowAreaWMult;
1173 : }
1174 12 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenParent, surfName, surface.BaseSurfName);
1175 : // compute totals for area weighted averages
1176 12 : intFenTotArea += windowAreaWMult;
1177 12 : intUfactArea += nomUfact * windowAreaWMult;
1178 : }
1179 94 : } else if (surface.Class == DataSurfaces::SurfaceClass::Door) {
1180 80 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1181 80 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1182 80 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1183 80 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1184 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrCons, surfName, construct.Name);
1185 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrZone, surfName, thisZone.Name);
1186 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrSpace, surfName, thisSpace.Name);
1187 80 : OutputReportPredefined::PreDefTableEntry(
1188 80 : state, state.dataOutRptPredefined->pdchIntDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1189 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrGrArea, surfName, surface.GrossArea * mult);
1190 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrParent, surfName, surface.BaseSurfName);
1191 80 : computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
1192 : }
1193 : }
1194 47332 : int currSurfaceClass = int(surface.Class);
1195 47332 : assert(currSurfaceClass < int(DataSurfaces::SurfaceClass::Num));
1196 47332 : assert(currSurfaceClass > int(DataSurfaces::SurfaceClass::None));
1197 47332 : ++numSurfaces(currSurfaceClass);
1198 47332 : if (isExterior) {
1199 22355 : ++numExtSurfaces(currSurfaceClass);
1200 : }
1201 47332 : if (surface.Class == DataSurfaces::SurfaceClass::Window) {
1202 6361 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::GlassDoor || surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
1203 543 : ++numSurfaces((int)surface.OriginalClass);
1204 543 : if (isExterior) {
1205 541 : ++numExtSurfaces((int)surface.OriginalClass);
1206 : }
1207 : }
1208 : }
1209 803 : }
1210 : // for fins and overhangs just add them explicitly since not otherwise classified
1211 803 : int totOverhangs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang") +
1212 803 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang:Projection");
1213 803 : numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
1214 803 : numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
1215 803 : int totFins = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin") +
1216 803 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin:Projection");
1217 803 : numSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
1218 803 : numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
1219 : // go through all the surfaces again and this time insert the net area results
1220 48135 : for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
1221 47332 : auto const &surface = state.dataSurface->Surface(iSurf);
1222 47332 : DataSurfaces::SurfaceClass const SurfaceClass(surface.Class);
1223 : // exterior surfaces including underground
1224 47332 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
1225 25201 : (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
1226 22355 : if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
1227 : (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
1228 13915 : surfName = surface.Name;
1229 13915 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpNetArea, surfName, computedNetArea(iSurf));
1230 : }
1231 : } else {
1232 24977 : if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
1233 : (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
1234 22346 : surfName = surface.Name;
1235 22346 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpNetArea, surfName, computedNetArea(iSurf));
1236 : }
1237 : } // interior surfaces
1238 803 : }
1239 : // total
1240 803 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Total or Average", fenTotArea);
1241 803 : if (fenTotArea > 0.0) {
1242 706 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", ufactArea / fenTotArea, 3);
1243 706 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", shgcArea / fenTotArea, 3);
1244 706 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", vistranArea / fenTotArea, 3);
1245 : } else {
1246 97 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", "-");
1247 97 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", "-");
1248 97 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", "-");
1249 : }
1250 : // north
1251 803 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "North Total or Average", fenTotAreaNorth);
1252 803 : if (fenTotAreaNorth > 0.0) {
1253 818 : OutputReportPredefined::PreDefTableEntry(
1254 818 : state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", ufactAreaNorth / fenTotAreaNorth, 3);
1255 818 : OutputReportPredefined::PreDefTableEntry(
1256 818 : state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", shgcAreaNorth / fenTotAreaNorth, 3);
1257 818 : OutputReportPredefined::PreDefTableEntry(
1258 1227 : state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", vistranAreaNorth / fenTotAreaNorth, 3);
1259 : } else {
1260 394 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", "-");
1261 394 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", "-");
1262 394 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", "-");
1263 : }
1264 : // non-north
1265 803 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Non-North Total or Average", fenTotAreaNonNorth);
1266 803 : if (fenTotAreaNonNorth > 0.0) {
1267 1410 : OutputReportPredefined::PreDefTableEntry(
1268 1410 : state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", ufactAreaNonNorth / fenTotAreaNonNorth, 3);
1269 1410 : OutputReportPredefined::PreDefTableEntry(
1270 1410 : state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", shgcAreaNonNorth / fenTotAreaNonNorth, 3);
1271 1410 : OutputReportPredefined::PreDefTableEntry(
1272 2115 : state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", vistranAreaNonNorth / fenTotAreaNonNorth, 3);
1273 : } else {
1274 98 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", "-");
1275 98 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", "-");
1276 98 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", "-");
1277 : }
1278 : // interior fenestration totals
1279 803 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, "Total or Average", intFenTotArea);
1280 803 : if (intFenTotArea > 0.0) {
1281 12 : OutputReportPredefined::PreDefTableEntry(
1282 12 : state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", intUfactArea / intFenTotArea, 3);
1283 12 : OutputReportPredefined::PreDefTableEntry(
1284 12 : state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", intShgcArea / intFenTotArea, 3);
1285 12 : OutputReportPredefined::PreDefTableEntry(
1286 18 : state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", intVistranArea / intFenTotArea, 3);
1287 : } else {
1288 797 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", "-");
1289 797 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", "-");
1290 797 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", "-");
1291 : }
1292 : // counts
1293 803 : OutputReportPredefined::PreDefTableEntry(
1294 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Wall", numSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
1295 803 : OutputReportPredefined::PreDefTableEntry(
1296 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Wall", numExtSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
1297 803 : OutputReportPredefined::PreDefTableEntry(
1298 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Floor", numSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
1299 803 : OutputReportPredefined::PreDefTableEntry(
1300 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Floor", numExtSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
1301 803 : OutputReportPredefined::PreDefTableEntry(
1302 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Roof", numSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
1303 803 : OutputReportPredefined::PreDefTableEntry(
1304 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Roof", numExtSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
1305 803 : OutputReportPredefined::PreDefTableEntry(
1306 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Internal Mass", numSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
1307 803 : OutputReportPredefined::PreDefTableEntry(
1308 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Internal Mass", numExtSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
1309 803 : OutputReportPredefined::PreDefTableEntry(
1310 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Building Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
1311 803 : OutputReportPredefined::PreDefTableEntry(
1312 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Building Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
1313 803 : OutputReportPredefined::PreDefTableEntry(
1314 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Fixed Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
1315 803 : OutputReportPredefined::PreDefTableEntry(
1316 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Fixed Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
1317 803 : OutputReportPredefined::PreDefTableEntry(
1318 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Window", numSurfaces(int(DataSurfaces::SurfaceClass::Window)));
1319 803 : OutputReportPredefined::PreDefTableEntry(
1320 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Window", numExtSurfaces(int(DataSurfaces::SurfaceClass::Window)));
1321 803 : OutputReportPredefined::PreDefTableEntry(
1322 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Door", numSurfaces(int(DataSurfaces::SurfaceClass::Door)));
1323 803 : OutputReportPredefined::PreDefTableEntry(
1324 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::Door)));
1325 803 : OutputReportPredefined::PreDefTableEntry(
1326 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Glass Door", numSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
1327 803 : OutputReportPredefined::PreDefTableEntry(
1328 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Glass Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
1329 803 : OutputReportPredefined::PreDefTableEntry(
1330 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
1331 803 : OutputReportPredefined::PreDefTableEntry(
1332 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
1333 803 : OutputReportPredefined::PreDefTableEntry(
1334 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Overhang", numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
1335 803 : OutputReportPredefined::PreDefTableEntry(
1336 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Overhang", numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
1337 803 : OutputReportPredefined::PreDefTableEntry(
1338 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Fin", numSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
1339 803 : OutputReportPredefined::PreDefTableEntry(
1340 803 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Fin", numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
1341 803 : OutputReportPredefined::PreDefTableEntry(
1342 803 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Tubular Daylighting Device Dome", numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
1343 803 : OutputReportPredefined::PreDefTableEntry(state,
1344 803 : state.dataOutRptPredefined->pdchSurfCntExt,
1345 : "Tubular Daylighting Device Dome",
1346 803 : numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
1347 803 : OutputReportPredefined::PreDefTableEntry(state,
1348 803 : state.dataOutRptPredefined->pdchSurfCntTot,
1349 : "Tubular Daylighting Device Diffuser",
1350 803 : numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
1351 803 : OutputReportPredefined::PreDefTableEntry(state,
1352 803 : state.dataOutRptPredefined->pdchSurfCntExt,
1353 : "Tubular Daylighting Device Diffuser",
1354 803 : numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
1355 803 : }
1356 :
1357 803 : void AllocateSurfaceHeatBalArrays(EnergyPlusData &state)
1358 : {
1359 :
1360 : // SUBROUTINE INFORMATION:
1361 : // AUTHOR Richard Liesen
1362 : // DATE WRITTEN February 1998
1363 :
1364 : // METHODOLOGY EMPLOYED:
1365 : // Uses the status flags to trigger variable allocation.
1366 :
1367 : // Use the total number of surfaces to allocate variables to avoid a surface number limit
1368 803 : state.dataHeatBalSurf->SurfCTFConstInPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1369 803 : state.dataHeatBalSurf->SurfCTFConstOutPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1370 803 : state.dataHeatBalSurf->SurfCTFCross0.dimension(state.dataSurface->TotSurfaces, 0.0);
1371 803 : state.dataHeatBalSurf->SurfCTFInside0.dimension(state.dataSurface->TotSurfaces, 0.0);
1372 803 : state.dataHeatBalSurf->SurfTempOutHist.dimension(state.dataSurface->TotSurfaces, 0.0);
1373 803 : state.dataHeatBalSurf->SurfCTFSourceIn0.dimension(state.dataSurface->TotSurfaces, 0.0);
1374 803 : state.dataHeatBalSurf->SurfQSourceSinkHist.dimension(state.dataSurface->TotSurfaces, 0.0);
1375 803 : state.dataHeatBalSurf->SurfIsAdiabatic.dimension(state.dataSurface->TotSurfaces, 0);
1376 803 : state.dataHeatBalSurf->SurfIsSourceOrSink.dimension(state.dataSurface->TotSurfaces, 0);
1377 803 : state.dataHeatBalSurf->SurfIsOperatingPool.dimension(state.dataSurface->TotSurfaces, 0);
1378 803 : state.dataHeatBalSurf->SurfTempTerm.dimension(state.dataSurface->TotSurfaces, 0);
1379 803 : state.dataHeatBalSurf->SurfTempDiv.dimension(state.dataSurface->TotSurfaces, 0);
1380 803 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
1381 36 : state.dataHeatBalFanSys->CTFTsrcConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1382 36 : state.dataHeatBalFanSys->CTFTuserConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1383 : }
1384 :
1385 803 : state.dataHeatBal->SurfTempEffBulkAir.dimension(state.dataSurface->TotSurfaces, DataHeatBalance::ZoneInitialTemp);
1386 803 : state.dataHeatBalSurf->SurfHConvInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1387 803 : state.dataHeatBalSurf->SurfHConvExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1388 803 : state.dataHeatBalSurf->SurfHAirExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1389 803 : state.dataHeatBalSurf->SurfHSkyExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1390 803 : state.dataHeatBalSurf->SurfHGrdExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1391 803 : state.dataHeatBalSurf->SurfHSrdSurfExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1392 :
1393 803 : state.dataHeatBalSurf->SurfTempIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1394 803 : state.dataHeatBalSurf->SurfTempInsOld.dimension(state.dataSurface->TotSurfaces, 0.0);
1395 803 : state.dataHeatBalSurf->SurfTempInTmp.dimension(state.dataSurface->TotSurfaces, 0.0);
1396 803 : state.dataHeatBalSurfMgr->RefAirTemp.dimension(state.dataSurface->TotSurfaces, 0.0);
1397 803 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs.dimension(state.dataSurface->TotSurfaces, 0.0);
1398 :
1399 803 : state.dataHeatBal->SurfWinQRadSWwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL + 1, 0.0);
1400 803 : state.dataHeatBal->SurfWinInitialDifSolwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL, 0.0);
1401 803 : state.dataHeatBalSurf->SurfQRadSWOutMvIns.dimension(state.dataSurface->TotSurfaces, 0.0);
1402 803 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1403 803 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside.dimension(state.dataSurface->TotSurfaces, 0.0);
1404 803 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside.dimension(state.dataSurface->TotSurfaces, 0.0);
1405 :
1406 803 : state.dataHeatBalSurf->SurfInsideTempHist.allocate(Construction::MaxCTFTerms);
1407 803 : state.dataHeatBalSurf->SurfOutsideTempHist.allocate(Construction::MaxCTFTerms);
1408 803 : state.dataHeatBalSurf->SurfInsideFluxHist.allocate(Construction::MaxCTFTerms);
1409 803 : state.dataHeatBalSurf->SurfOutsideFluxHist.allocate(Construction::MaxCTFTerms);
1410 16060 : for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
1411 15257 : state.dataHeatBalSurf->SurfInsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1412 15257 : state.dataHeatBalSurf->SurfOutsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1413 15257 : state.dataHeatBalSurf->SurfInsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1414 15257 : state.dataHeatBalSurf->SurfOutsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1415 : }
1416 :
1417 803 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
1418 140 : state.dataHeatBalSurf->SurfCurrNumHist.dimension(state.dataSurface->TotSurfaces, 0);
1419 :
1420 140 : state.dataHeatBalSurf->SurfInsideTempHistMaster.allocate(Construction::MaxCTFTerms);
1421 140 : state.dataHeatBalSurf->SurfOutsideTempHistMaster.allocate(Construction::MaxCTFTerms);
1422 140 : state.dataHeatBalSurf->SurfInsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
1423 140 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
1424 :
1425 2800 : for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
1426 2660 : state.dataHeatBalSurf->SurfInsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1427 2660 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1428 2660 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1429 2660 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1430 : }
1431 : }
1432 :
1433 803 : state.dataHeatBalSurf->SurfTempOut.dimension(state.dataSurface->TotSurfaces, 0.0);
1434 803 : state.dataHeatBalSurf->SurfTempInMovInsRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1435 803 : state.dataHeatBalSurf->SurfQConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1436 803 : state.dataHeatBalSurf->SurfQdotConvInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1437 803 : state.dataHeatBalSurf->SurfQdotConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1438 :
1439 803 : state.dataHeatBalSurf->SurfQRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1440 803 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1441 :
1442 803 : state.dataHeatBalSurf->SurfQRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1443 803 : state.dataHeatBalSurf->SurfQdotRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1444 803 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1445 :
1446 803 : state.dataHeatBalSurf->SurfQRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1447 803 : state.dataHeatBalSurf->SurfQdotRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1448 :
1449 803 : state.dataHeatBalSurf->SurfQRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1450 803 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1451 :
1452 803 : state.dataHeatBalSurf->SurfQRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1453 803 : state.dataHeatBalSurf->SurfQdotRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1454 803 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1455 :
1456 803 : state.dataHeatBalSurf->SurfQConvOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1457 803 : state.dataHeatBalSurf->SurfQdotConvOutPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1458 803 : state.dataHeatBalSurf->SurfQdotConvOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1459 :
1460 803 : state.dataHeatBalSurf->SurfQdotRadOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1461 803 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1462 803 : state.dataHeatBalSurf->SurfQRadOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1463 :
1464 803 : state.dataHeatBalSurf->SurfQAirExtReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1465 803 : state.dataHeatBalSurf->SurfQHeatEmiReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1466 :
1467 803 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1468 803 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1469 :
1470 803 : state.dataHeatBalSurf->SurfOpaqInsFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1471 803 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1472 803 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1473 803 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1474 803 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1475 :
1476 803 : state.dataHeatBalSurf->SurfOpaqOutFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1477 803 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1478 803 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1479 803 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1480 803 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1481 :
1482 803 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1483 803 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1484 803 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1485 803 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1486 803 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1487 :
1488 803 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1489 803 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1490 803 : state.dataHeatBalSurf->SurfOpaqStorageCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1491 803 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1492 803 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1493 :
1494 803 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed.dimension(state.dataSurface->TotSurfaces, 0.0);
1495 :
1496 803 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1497 803 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1498 :
1499 803 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1500 803 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
1501 803 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
1502 :
1503 803 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1504 803 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1505 :
1506 803 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
1507 36 : state.dataHeatBalSurf->SurfTempSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1508 36 : state.dataHeatBalSurf->SurfTempUserLoc.dimension(state.dataSurface->TotSurfaces, 0.0);
1509 36 : state.dataHeatBalSurf->SurfTsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1510 36 : state.dataHeatBalSurf->SurfTuserHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1511 36 : state.dataHeatBalSurf->SurfQsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1512 36 : state.dataHeatBalSurf->SurfTsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1513 36 : state.dataHeatBalSurf->SurfTuserHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1514 36 : state.dataHeatBalSurf->SurfQsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1515 : }
1516 :
1517 803 : state.dataHeatBalFanSys->RadSysTiHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1518 803 : state.dataHeatBalFanSys->RadSysTiHBToutCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1519 803 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1520 803 : state.dataHeatBalFanSys->RadSysToHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1521 803 : state.dataHeatBalFanSys->RadSysToHBTinCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1522 803 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1523 803 : state.dataHeatBalFanSys->QRadSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1524 803 : state.dataHeatBalFanSys->TCondFDSourceNode.dimension(state.dataSurface->TotSurfaces, 15.0);
1525 803 : state.dataHeatBalFanSys->surfQRadFromHVAC.allocate(state.dataSurface->TotSurfaces);
1526 803 : state.dataHeatBalFanSys->QRadSurfAFNDuct.dimension(state.dataSurface->TotSurfaces, 0.0);
1527 :
1528 : // allocate terms used for pool surface heat balance
1529 803 : state.dataHeatBalFanSys->QPoolSurfNumerator.dimension(state.dataSurface->TotSurfaces, 0.0);
1530 803 : state.dataHeatBalFanSys->PoolHeatTransCoefs.dimension(state.dataSurface->TotSurfaces, 0.0);
1531 :
1532 : // allocate term used as sink for PV electricity
1533 803 : state.dataHeatBalFanSys->QPVSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1534 :
1535 : // Allocate the moisture balance arrays
1536 803 : state.dataMstBal->TempOutsideAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1537 803 : state.dataMstBal->RhoVaporAirOut.dimension(state.dataSurface->TotSurfaces, 0.0);
1538 803 : state.dataMstBal->RhoVaporSurfIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1539 803 : state.dataMstBal->RhoVaporAirIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1540 803 : state.dataMstBal->HConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1541 803 : state.dataMstBal->HMassConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1542 803 : state.dataMstBal->HConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1543 803 : state.dataMstBal->HMassConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1544 803 : state.dataMstBal->HSkyFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1545 803 : state.dataMstBal->HGrndFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1546 803 : state.dataMstBal->HAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1547 803 : state.dataMstBal->HSurrFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1548 :
1549 803 : state.dataSurface->SurfSkySolarInc.dimension(state.dataSurface->TotSurfaces, 0);
1550 803 : state.dataSurface->SurfGndSolarInc.dimension(state.dataSurface->TotSurfaces, 0);
1551 :
1552 803 : state.dataHeatBalSurf->SurfAbsSolarExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1553 803 : state.dataHeatBalSurf->SurfAbsThermalExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1554 803 : state.dataHeatBalSurf->SurfRoughnessExt.dimension(state.dataSurface->TotSurfaces, Material::SurfaceRoughness::Invalid);
1555 803 : state.dataHeatBalSurf->SurfAbsSolarInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1556 803 : state.dataHeatBalSurf->SurfAbsThermalInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1557 :
1558 803 : DisplayString(state, "Setting up Surface Reporting Variables");
1559 : // Setup surface report variables CurrentModuleObject='Opaque Surfaces'
1560 48135 : for (int loop = 1; loop <= state.dataSurface->TotSurfaces; ++loop) {
1561 47332 : auto &surface = state.dataSurface->Surface(loop);
1562 47332 : if (!surface.HeatTransSurf) {
1563 1707 : continue;
1564 : }
1565 91250 : SetupOutputVariable(state,
1566 : "Surface Inside Face Temperature",
1567 : Constant::Units::C,
1568 45625 : state.dataHeatBalSurf->SurfTempIn(loop),
1569 : OutputProcessor::TimeStepType::Zone,
1570 : OutputProcessor::StoreType::Average,
1571 45625 : surface.Name);
1572 91250 : SetupOutputVariable(state,
1573 : "Surface Inside Face Interior Movable Insulation Temperature",
1574 : Constant::Units::C,
1575 45625 : state.dataHeatBalSurf->SurfTempInMovInsRep(loop),
1576 : OutputProcessor::TimeStepType::Zone,
1577 : OutputProcessor::StoreType::Average,
1578 45625 : surface.Name);
1579 :
1580 45625 : if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
1581 91170 : SetupOutputVariable(state,
1582 : "Surface Outside Face Temperature",
1583 : Constant::Units::C,
1584 45585 : state.dataHeatBalSurf->SurfTempOut(loop),
1585 : OutputProcessor::TimeStepType::Zone,
1586 : OutputProcessor::StoreType::Average,
1587 45585 : surface.Name);
1588 : }
1589 :
1590 91250 : SetupOutputVariable(state,
1591 : "Surface Inside Face Adjacent Air Temperature",
1592 : Constant::Units::C,
1593 45625 : state.dataHeatBal->SurfTempEffBulkAir(loop),
1594 : OutputProcessor::TimeStepType::Zone,
1595 : OutputProcessor::StoreType::Average,
1596 45625 : surface.Name);
1597 91250 : SetupOutputVariable(state,
1598 : "Surface Inside Face Convection Heat Transfer Coefficient",
1599 : Constant::Units::W_m2K,
1600 45625 : state.dataHeatBalSurf->SurfHConvInt(loop),
1601 : OutputProcessor::TimeStepType::Zone,
1602 : OutputProcessor::StoreType::Average,
1603 45625 : surface.Name);
1604 91250 : SetupOutputVariable(state,
1605 : "Surface Inside Face Convection Heat Gain Rate",
1606 : Constant::Units::W,
1607 45625 : state.dataHeatBalSurf->SurfQdotConvInRep(loop),
1608 : OutputProcessor::TimeStepType::Zone,
1609 : OutputProcessor::StoreType::Average,
1610 45625 : surface.Name);
1611 91250 : SetupOutputVariable(state,
1612 : "Surface Inside Face Convection Heat Gain Rate per Area",
1613 : Constant::Units::W_m2,
1614 45625 : state.dataHeatBalSurf->SurfQdotConvInPerArea(loop),
1615 : OutputProcessor::TimeStepType::Zone,
1616 : OutputProcessor::StoreType::Average,
1617 45625 : surface.Name);
1618 91250 : SetupOutputVariable(state,
1619 : "Surface Inside Face Convection Heat Gain Energy",
1620 : Constant::Units::J,
1621 45625 : state.dataHeatBalSurf->SurfQConvInRep(loop),
1622 : OutputProcessor::TimeStepType::Zone,
1623 : OutputProcessor::StoreType::Sum,
1624 45625 : surface.Name);
1625 :
1626 91250 : SetupOutputVariable(state,
1627 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate",
1628 : Constant::Units::W,
1629 45625 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(loop),
1630 : OutputProcessor::TimeStepType::Zone,
1631 : OutputProcessor::StoreType::Average,
1632 45625 : surface.Name);
1633 91250 : SetupOutputVariable(state,
1634 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate per Area",
1635 : Constant::Units::W_m2,
1636 45625 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(loop),
1637 : OutputProcessor::TimeStepType::Zone,
1638 : OutputProcessor::StoreType::Average,
1639 45625 : surface.Name);
1640 91250 : SetupOutputVariable(state,
1641 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy",
1642 : Constant::Units::J,
1643 45625 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(loop),
1644 : OutputProcessor::TimeStepType::Zone,
1645 : OutputProcessor::StoreType::Sum,
1646 45625 : surface.Name);
1647 :
1648 45625 : if (surface.Class != DataSurfaces::SurfaceClass::Window) {
1649 78528 : SetupOutputVariable(state,
1650 : "Surface Inside Face Solar Radiation Heat Gain Rate",
1651 : Constant::Units::W,
1652 39264 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(loop),
1653 : OutputProcessor::TimeStepType::Zone,
1654 : OutputProcessor::StoreType::Average,
1655 39264 : surface.Name);
1656 78528 : SetupOutputVariable(state,
1657 : "Surface Inside Face Solar Radiation Heat Gain Rate per Area",
1658 : Constant::Units::W_m2,
1659 39264 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(loop),
1660 : OutputProcessor::TimeStepType::Zone,
1661 : OutputProcessor::StoreType::Average,
1662 39264 : surface.Name);
1663 78528 : SetupOutputVariable(state,
1664 : "Surface Inside Face Solar Radiation Heat Gain Energy",
1665 : Constant::Units::J,
1666 39264 : state.dataHeatBalSurf->SurfQRadSolarInRep(loop),
1667 : OutputProcessor::TimeStepType::Zone,
1668 : OutputProcessor::StoreType::Sum,
1669 39264 : surface.Name);
1670 :
1671 78528 : SetupOutputVariable(state,
1672 : "Surface Inside Face Lights Radiation Heat Gain Rate",
1673 : Constant::Units::W,
1674 39264 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(loop),
1675 : OutputProcessor::TimeStepType::Zone,
1676 : OutputProcessor::StoreType::Average,
1677 39264 : surface.Name);
1678 78528 : SetupOutputVariable(state,
1679 : "Surface Inside Face Lights Radiation Heat Gain Rate per Area",
1680 : Constant::Units::W_m2,
1681 39264 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(loop),
1682 : OutputProcessor::TimeStepType::Zone,
1683 : OutputProcessor::StoreType::Average,
1684 39264 : surface.Name);
1685 78528 : SetupOutputVariable(state,
1686 : "Surface Inside Face Lights Radiation Heat Gain Energy",
1687 : Constant::Units::J,
1688 39264 : state.dataHeatBalSurf->SurfQRadLightsInRep(loop),
1689 : OutputProcessor::TimeStepType::Zone,
1690 : OutputProcessor::StoreType::Sum,
1691 39264 : surface.Name);
1692 : }
1693 :
1694 91250 : SetupOutputVariable(state,
1695 : "Surface Inside Face Internal Gains Radiation Heat Gain Rate",
1696 : Constant::Units::W,
1697 45625 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(loop),
1698 : OutputProcessor::TimeStepType::Zone,
1699 : OutputProcessor::StoreType::Average,
1700 45625 : surface.Name);
1701 91250 : SetupOutputVariable(state,
1702 : "Surface Inside Face Internal Gains Radiation Heat Gain Rate per Area",
1703 : Constant::Units::W_m2,
1704 45625 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(loop),
1705 : OutputProcessor::TimeStepType::Zone,
1706 : OutputProcessor::StoreType::Average,
1707 45625 : surface.Name);
1708 91250 : SetupOutputVariable(state,
1709 : "Surface Inside Face Internal Gains Radiation Heat Gain Energy",
1710 : Constant::Units::J,
1711 45625 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(loop),
1712 : OutputProcessor::TimeStepType::Zone,
1713 : OutputProcessor::StoreType::Sum,
1714 45625 : surface.Name);
1715 :
1716 91250 : SetupOutputVariable(state,
1717 : "Surface Inside Face System Radiation Heat Gain Rate",
1718 : Constant::Units::W,
1719 45625 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(loop),
1720 : OutputProcessor::TimeStepType::Zone,
1721 : OutputProcessor::StoreType::Average,
1722 45625 : surface.Name);
1723 91250 : SetupOutputVariable(state,
1724 : "Surface Inside Face System Radiation Heat Gain Rate per Area",
1725 : Constant::Units::W_m2,
1726 45625 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(loop),
1727 : OutputProcessor::TimeStepType::Zone,
1728 : OutputProcessor::StoreType::Average,
1729 45625 : surface.Name);
1730 91250 : SetupOutputVariable(state,
1731 : "Surface Inside Face System Radiation Heat Gain Energy",
1732 : Constant::Units::J,
1733 45625 : state.dataHeatBalSurf->SurfQRadHVACInRep(loop),
1734 : OutputProcessor::TimeStepType::Zone,
1735 : OutputProcessor::StoreType::Sum,
1736 45625 : surface.Name);
1737 :
1738 45625 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment || state.dataGlobal->DisplayAdvancedReportVariables) {
1739 36912 : SetupOutputVariable(state,
1740 : "Surface Outside Face Outdoor Air Drybulb Temperature",
1741 : Constant::Units::C,
1742 18456 : state.dataSurface->SurfOutDryBulbTemp(loop),
1743 : OutputProcessor::TimeStepType::Zone,
1744 : OutputProcessor::StoreType::Average,
1745 18456 : surface.Name);
1746 36912 : SetupOutputVariable(state,
1747 : "Surface Outside Face Outdoor Air Wetbulb Temperature",
1748 : Constant::Units::C,
1749 18456 : state.dataSurface->SurfOutWetBulbTemp(loop),
1750 : OutputProcessor::TimeStepType::Zone,
1751 : OutputProcessor::StoreType::Average,
1752 18456 : surface.Name);
1753 36912 : SetupOutputVariable(state,
1754 : "Surface Outside Face Outdoor Air Wind Speed",
1755 : Constant::Units::m_s,
1756 18456 : state.dataSurface->SurfOutWindSpeed(loop),
1757 : OutputProcessor::TimeStepType::Zone,
1758 : OutputProcessor::StoreType::Average,
1759 18456 : surface.Name);
1760 36912 : SetupOutputVariable(state,
1761 : "Surface Outside Face Outdoor Air Wind Direction",
1762 : Constant::Units::deg,
1763 18456 : state.dataSurface->SurfOutWindDir(loop),
1764 : OutputProcessor::TimeStepType::Zone,
1765 : OutputProcessor::StoreType::Average,
1766 18456 : surface.Name);
1767 36912 : SetupOutputVariable(state,
1768 : "Surface Outside Face Convection Heat Gain Rate",
1769 : Constant::Units::W,
1770 18456 : state.dataHeatBalSurf->SurfQdotConvOutRep(loop),
1771 : OutputProcessor::TimeStepType::Zone,
1772 : OutputProcessor::StoreType::Average,
1773 18456 : surface.Name);
1774 36912 : SetupOutputVariable(state,
1775 : "Surface Outside Face Convection Heat Gain Rate per Area",
1776 : Constant::Units::W_m2,
1777 18456 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(loop),
1778 : OutputProcessor::TimeStepType::Zone,
1779 : OutputProcessor::StoreType::Average,
1780 18456 : surface.Name);
1781 36912 : SetupOutputVariable(state,
1782 : "Surface Outside Face Convection Heat Gain Energy",
1783 : Constant::Units::J,
1784 18456 : state.dataHeatBalSurf->SurfQConvOutReport(loop),
1785 : OutputProcessor::TimeStepType::Zone,
1786 : OutputProcessor::StoreType::Sum,
1787 18456 : surface.Name);
1788 36912 : SetupOutputVariable(state,
1789 : "Surface Outside Face Convection Heat Transfer Coefficient",
1790 : Constant::Units::W_m2K,
1791 18456 : state.dataHeatBalSurf->SurfHConvExt(loop),
1792 : OutputProcessor::TimeStepType::Zone,
1793 : OutputProcessor::StoreType::Average,
1794 18456 : surface.Name);
1795 36912 : SetupOutputVariable(state,
1796 : "Surface Outside Face Net Thermal Radiation Heat Gain Rate",
1797 : Constant::Units::W,
1798 18456 : state.dataHeatBalSurf->SurfQdotRadOutRep(loop),
1799 : OutputProcessor::TimeStepType::Zone,
1800 : OutputProcessor::StoreType::Average,
1801 18456 : surface.Name);
1802 36912 : SetupOutputVariable(state,
1803 : "Surface Outside Face Net Thermal Radiation Heat Gain Rate per Area",
1804 : Constant::Units::W_m2,
1805 18456 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(loop),
1806 : OutputProcessor::TimeStepType::Zone,
1807 : OutputProcessor::StoreType::Average,
1808 18456 : surface.Name);
1809 36912 : SetupOutputVariable(state,
1810 : "Surface Outside Face Net Thermal Radiation Heat Gain Energy",
1811 : Constant::Units::J,
1812 18456 : state.dataHeatBalSurf->SurfQRadOutReport(loop),
1813 : OutputProcessor::TimeStepType::Zone,
1814 : OutputProcessor::StoreType::Sum,
1815 18456 : surface.Name);
1816 36912 : SetupOutputVariable(state,
1817 : "Surface Outside Face Thermal Radiation to Air Heat Transfer Coefficient",
1818 : Constant::Units::W_m2K,
1819 18456 : state.dataHeatBalSurf->SurfHAirExt(loop),
1820 : OutputProcessor::TimeStepType::Zone,
1821 : OutputProcessor::StoreType::Average,
1822 18456 : surface.Name);
1823 36912 : SetupOutputVariable(state,
1824 : "Surface Outside Face Thermal Radiation to Sky Heat Transfer Coefficient",
1825 : Constant::Units::W_m2K,
1826 18456 : state.dataHeatBalSurf->SurfHSkyExt(loop),
1827 : OutputProcessor::TimeStepType::Zone,
1828 : OutputProcessor::StoreType::Average,
1829 18456 : surface.Name);
1830 36912 : SetupOutputVariable(state,
1831 : "Surface Outside Face Thermal Radiation to Ground Heat Transfer Coefficient",
1832 : Constant::Units::W_m2K,
1833 18456 : state.dataHeatBalSurf->SurfHGrdExt(loop),
1834 : OutputProcessor::TimeStepType::Zone,
1835 : OutputProcessor::StoreType::Average,
1836 18456 : surface.Name);
1837 36912 : SetupOutputVariable(state,
1838 : "Surface Outside Face Thermal Radiation to Air Heat Transfer Rate",
1839 : Constant::Units::W,
1840 18456 : state.dataHeatBalSurf->SurfQAirExtReport(loop),
1841 : OutputProcessor::TimeStepType::Zone,
1842 : OutputProcessor::StoreType::Average,
1843 18456 : surface.Name);
1844 36912 : SetupOutputVariable(state,
1845 : "Surface Outside Face Heat Emission to Air Rate",
1846 : Constant::Units::W,
1847 18456 : state.dataHeatBalSurf->SurfQHeatEmiReport(loop),
1848 : OutputProcessor::TimeStepType::Zone,
1849 : OutputProcessor::StoreType::Average,
1850 18456 : surface.Name);
1851 :
1852 18456 : if (surface.Class != DataSurfaces::SurfaceClass::Window) {
1853 24218 : SetupOutputVariable(state,
1854 : "Surface Outside Face Solar Radiation Heat Gain Rate",
1855 : Constant::Units::W,
1856 12109 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(loop),
1857 : OutputProcessor::TimeStepType::Zone,
1858 : OutputProcessor::StoreType::Average,
1859 12109 : surface.Name);
1860 24218 : SetupOutputVariable(state,
1861 : "Surface Outside Face Solar Radiation Heat Gain Rate per Area",
1862 : Constant::Units::W_m2,
1863 12109 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(loop),
1864 : OutputProcessor::TimeStepType::Zone,
1865 : OutputProcessor::StoreType::Average,
1866 12109 : surface.Name);
1867 24218 : SetupOutputVariable(state,
1868 : "Surface Outside Face Solar Radiation Heat Gain Energy",
1869 : Constant::Units::J,
1870 12109 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(loop),
1871 : OutputProcessor::TimeStepType::Zone,
1872 : OutputProcessor::StoreType::Sum,
1873 12109 : surface.Name);
1874 : }
1875 : }
1876 45625 : if (surface.Class == DataSurfaces::SurfaceClass::Floor || surface.Class == DataSurfaces::SurfaceClass::Wall ||
1877 15346 : surface.Class == DataSurfaces::SurfaceClass::IntMass || surface.Class == DataSurfaces::SurfaceClass::Roof ||
1878 6845 : surface.Class == DataSurfaces::SurfaceClass::Door) {
1879 : // IF (DisplayAdvancedReportVariables) THEN !CurrentModuleObject='Opaque Surfaces(Advanced)'
1880 78522 : SetupOutputVariable(state,
1881 : "Surface Inside Face Conduction Heat Transfer Rate",
1882 : Constant::Units::W,
1883 39261 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(loop),
1884 : OutputProcessor::TimeStepType::Zone,
1885 : OutputProcessor::StoreType::Average,
1886 39261 : surface.Name);
1887 78522 : SetupOutputVariable(state,
1888 : "Surface Inside Face Conduction Heat Gain Rate",
1889 : Constant::Units::W,
1890 39261 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(loop),
1891 : OutputProcessor::TimeStepType::Zone,
1892 : OutputProcessor::StoreType::Average,
1893 39261 : surface.Name);
1894 78522 : SetupOutputVariable(state,
1895 : "Surface Inside Face Conduction Heat Loss Rate",
1896 : Constant::Units::W,
1897 39261 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(loop),
1898 : OutputProcessor::TimeStepType::Zone,
1899 : OutputProcessor::StoreType::Average,
1900 39261 : surface.Name);
1901 78522 : SetupOutputVariable(state,
1902 : "Surface Inside Face Conduction Heat Transfer Rate per Area",
1903 : Constant::Units::W_m2,
1904 39261 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(loop),
1905 : OutputProcessor::TimeStepType::Zone,
1906 : OutputProcessor::StoreType::Average,
1907 39261 : surface.Name);
1908 78522 : SetupOutputVariable(state,
1909 : "Surface Inside Face Conduction Heat Transfer Energy",
1910 : Constant::Units::J,
1911 39261 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(loop),
1912 : OutputProcessor::TimeStepType::Zone,
1913 : OutputProcessor::StoreType::Sum,
1914 39261 : surface.Name);
1915 :
1916 39261 : if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
1917 78442 : SetupOutputVariable(state,
1918 : "Surface Outside Face Conduction Heat Transfer Rate",
1919 : Constant::Units::W,
1920 39221 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(loop),
1921 : OutputProcessor::TimeStepType::Zone,
1922 : OutputProcessor::StoreType::Average,
1923 39221 : surface.Name);
1924 78442 : SetupOutputVariable(state,
1925 : "Surface Outside Face Conduction Heat Gain Rate",
1926 : Constant::Units::W,
1927 39221 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(loop),
1928 : OutputProcessor::TimeStepType::Zone,
1929 : OutputProcessor::StoreType::Average,
1930 39221 : surface.Name);
1931 78442 : SetupOutputVariable(state,
1932 : "Surface Outside Face Conduction Heat Loss Rate",
1933 : Constant::Units::W,
1934 39221 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(loop),
1935 : OutputProcessor::TimeStepType::Zone,
1936 : OutputProcessor::StoreType::Average,
1937 39221 : surface.Name);
1938 78442 : SetupOutputVariable(state,
1939 : "Surface Outside Face Conduction Heat Transfer Rate per Area",
1940 : Constant::Units::W_m2,
1941 39221 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(loop),
1942 : OutputProcessor::TimeStepType::Zone,
1943 : OutputProcessor::StoreType::Average,
1944 39221 : surface.Name);
1945 78442 : SetupOutputVariable(state,
1946 : "Surface Outside Face Conduction Heat Transfer Energy",
1947 : Constant::Units::J,
1948 39221 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(loop),
1949 : OutputProcessor::TimeStepType::Zone,
1950 : OutputProcessor::StoreType::Sum,
1951 39221 : surface.Name);
1952 :
1953 78442 : SetupOutputVariable(state,
1954 : "Surface Average Face Conduction Heat Transfer Rate",
1955 : Constant::Units::W,
1956 39221 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(loop),
1957 : OutputProcessor::TimeStepType::Zone,
1958 : OutputProcessor::StoreType::Average,
1959 39221 : surface.Name);
1960 78442 : SetupOutputVariable(state,
1961 : "Surface Average Face Conduction Heat Gain Rate",
1962 : Constant::Units::W,
1963 39221 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(loop),
1964 : OutputProcessor::TimeStepType::Zone,
1965 : OutputProcessor::StoreType::Average,
1966 39221 : surface.Name);
1967 78442 : SetupOutputVariable(state,
1968 : "Surface Average Face Conduction Heat Loss Rate",
1969 : Constant::Units::W,
1970 39221 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(loop),
1971 : OutputProcessor::TimeStepType::Zone,
1972 : OutputProcessor::StoreType::Average,
1973 39221 : surface.Name);
1974 78442 : SetupOutputVariable(state,
1975 : "Surface Average Face Conduction Heat Transfer Rate per Area",
1976 : Constant::Units::W_m2,
1977 39221 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(loop),
1978 : OutputProcessor::TimeStepType::Zone,
1979 : OutputProcessor::StoreType::Average,
1980 39221 : surface.Name);
1981 78442 : SetupOutputVariable(state,
1982 : "Surface Average Face Conduction Heat Transfer Energy",
1983 : Constant::Units::J,
1984 39221 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(loop),
1985 : OutputProcessor::TimeStepType::Zone,
1986 : OutputProcessor::StoreType::Sum,
1987 39221 : surface.Name);
1988 :
1989 78442 : SetupOutputVariable(state,
1990 : "Surface Heat Storage Rate",
1991 : Constant::Units::W,
1992 39221 : state.dataHeatBalSurf->SurfOpaqStorageCond(loop),
1993 : OutputProcessor::TimeStepType::Zone,
1994 : OutputProcessor::StoreType::Average,
1995 39221 : surface.Name);
1996 78442 : SetupOutputVariable(state,
1997 : "Surface Heat Storage Gain Rate",
1998 : Constant::Units::W,
1999 39221 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(loop),
2000 : OutputProcessor::TimeStepType::Zone,
2001 : OutputProcessor::StoreType::Average,
2002 39221 : surface.Name);
2003 78442 : SetupOutputVariable(state,
2004 : "Surface Heat Storage Loss Rate",
2005 : Constant::Units::W,
2006 39221 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(loop),
2007 : OutputProcessor::TimeStepType::Zone,
2008 : OutputProcessor::StoreType::Average,
2009 39221 : surface.Name);
2010 78442 : SetupOutputVariable(state,
2011 : "Surface Heat Storage Rate per Area",
2012 : Constant::Units::W_m2,
2013 39221 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux(loop),
2014 : OutputProcessor::TimeStepType::Zone,
2015 : OutputProcessor::StoreType::Average,
2016 39221 : surface.Name);
2017 78442 : SetupOutputVariable(state,
2018 : "Surface Heat Storage Energy",
2019 : Constant::Units::J,
2020 39221 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(loop),
2021 : OutputProcessor::TimeStepType::Zone,
2022 : OutputProcessor::StoreType::Sum,
2023 39221 : surface.Name);
2024 : }
2025 :
2026 : // ENDIF
2027 : // CurrentModuleObject='Opaque Surfaces'
2028 :
2029 78522 : SetupOutputVariable(state,
2030 : "Surface Inside Face Beam Solar Radiation Heat Gain Rate",
2031 : Constant::Units::W,
2032 39261 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(loop),
2033 : OutputProcessor::TimeStepType::Zone,
2034 : OutputProcessor::StoreType::Average,
2035 39261 : surface.Name);
2036 : }
2037 45625 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
2038 284 : SetupOutputVariable(state,
2039 : "Surface Internal Source Location Temperature",
2040 : Constant::Units::C,
2041 142 : state.dataHeatBalSurf->SurfTempSource(loop),
2042 : OutputProcessor::TimeStepType::Zone,
2043 : OutputProcessor::StoreType::Average,
2044 142 : surface.Name);
2045 284 : SetupOutputVariable(state,
2046 : "Surface Internal User Specified Location Temperature",
2047 : Constant::Units::C,
2048 142 : state.dataHeatBalSurf->SurfTempUserLoc(loop),
2049 : OutputProcessor::TimeStepType::Zone,
2050 : OutputProcessor::StoreType::Average,
2051 142 : surface.Name);
2052 : }
2053 :
2054 45625 : if (surface.Class == DataSurfaces::SurfaceClass::Window) { // CurrentModuleObject='Windows'
2055 6361 : auto &surfShade = state.dataSurface->surfShades(loop);
2056 12722 : SetupOutputVariable(state,
2057 : "Surface Shading Device Is On Time Fraction",
2058 : Constant::Units::None,
2059 6361 : state.dataSurface->SurfWinFracTimeShadingDeviceOn(loop),
2060 : OutputProcessor::TimeStepType::Zone,
2061 : OutputProcessor::StoreType::Average,
2062 6361 : surface.Name);
2063 6361 : SetupOutputVariable(state,
2064 : "Surface Storm Window On Off Status",
2065 : Constant::Units::None,
2066 6361 : state.dataSurface->SurfWinStormWinFlag(loop),
2067 : OutputProcessor::TimeStepType::Zone,
2068 : OutputProcessor::StoreType::Average,
2069 6361 : surface.Name);
2070 12722 : SetupOutputVariable(state,
2071 : "Surface Window Blind Slat Angle",
2072 : Constant::Units::deg,
2073 6361 : surfShade.blind.slatAngDeg,
2074 : OutputProcessor::TimeStepType::Zone,
2075 : OutputProcessor::StoreType::Average,
2076 6361 : surface.Name);
2077 : }
2078 : // IF (DisplayAdvancedReportVariables) THEN !CurrentModuleObject='Opaque Surfaces(Advanced)'
2079 45625 : SetupOutputVariable(state,
2080 : "Surface Inside Face Convection Classification Index",
2081 : Constant::Units::None,
2082 45625 : state.dataSurface->surfIntConv(loop).convClassRpt,
2083 : OutputProcessor::TimeStepType::Zone,
2084 : OutputProcessor::StoreType::Average,
2085 45625 : surface.Name);
2086 45625 : SetupOutputVariable(state,
2087 : "Surface Inside Face Convection Model Equation Index",
2088 : Constant::Units::None,
2089 45625 : state.dataSurface->surfIntConv(loop).hcModelEqRpt,
2090 : OutputProcessor::TimeStepType::Zone,
2091 : OutputProcessor::StoreType::Average,
2092 45625 : surface.Name);
2093 45625 : SetupOutputVariable(state,
2094 : "Surface Inside Face Convection Reference Air Index",
2095 : Constant::Units::None,
2096 45625 : state.dataSurface->SurfTAirRefRpt(loop),
2097 : OutputProcessor::TimeStepType::Zone,
2098 : OutputProcessor::StoreType::Average,
2099 45625 : surface.Name);
2100 45625 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
2101 18196 : SetupOutputVariable(state,
2102 : "Surface Outside Face Convection Classification Index",
2103 : Constant::Units::None,
2104 18196 : state.dataSurface->surfExtConv(loop).convClassRpt,
2105 : OutputProcessor::TimeStepType::Zone,
2106 : OutputProcessor::StoreType::Average,
2107 18196 : surface.Name);
2108 18196 : SetupOutputVariable(state,
2109 : "Surface Outside Face Forced Convection Model Equation Index",
2110 : Constant::Units::None,
2111 18196 : state.dataSurface->surfExtConv(loop).hfModelEqRpt,
2112 : OutputProcessor::TimeStepType::Zone,
2113 : OutputProcessor::StoreType::Average,
2114 18196 : surface.Name);
2115 18196 : SetupOutputVariable(state,
2116 : "Surface Outside Face Natural Convection Model Equation Index",
2117 : Constant::Units::None,
2118 18196 : state.dataSurface->surfExtConv(loop).hnModelEqRpt,
2119 : OutputProcessor::TimeStepType::Zone,
2120 : OutputProcessor::StoreType::Average,
2121 18196 : surface.Name);
2122 : }
2123 :
2124 91250 : SetupOutputVariable(state,
2125 : "Surface Inside Face Heat Source Gain Rate per Area",
2126 : Constant::Units::W_m2,
2127 45625 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(loop),
2128 : OutputProcessor::TimeStepType::Zone,
2129 : OutputProcessor::StoreType::Average,
2130 45625 : surface.Name);
2131 91250 : SetupOutputVariable(state,
2132 : "Surface Outside Face Heat Source Gain Rate per Area",
2133 : Constant::Units::W_m2,
2134 45625 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(loop),
2135 : OutputProcessor::TimeStepType::Zone,
2136 : OutputProcessor::StoreType::Average,
2137 45625 : surface.Name);
2138 :
2139 : // ENDIF
2140 45625 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
2141 596 : SetupOutputVariable(state,
2142 : "Surface Construction Index",
2143 : Constant::Units::None,
2144 596 : surface.Construction,
2145 : OutputProcessor::TimeStepType::Zone,
2146 : OutputProcessor::StoreType::Average,
2147 596 : surface.Name);
2148 : }
2149 : }
2150 3212 : SetupOutputVariable(state,
2151 : "Site Total Surface Heat Emission to Air",
2152 : Constant::Units::J,
2153 803 : state.dataHeatBalSurf->SumSurfaceHeatEmission,
2154 : OutputProcessor::TimeStepType::Zone,
2155 : OutputProcessor::StoreType::Sum,
2156 : "Environment");
2157 803 : }
2158 :
2159 6396 : void InitThermalAndFluxHistories(EnergyPlusData &state)
2160 : {
2161 :
2162 : // SUBROUTINE INFORMATION:
2163 : // AUTHOR George Walton
2164 : // DATE WRITTEN March 1978
2165 : // RE-ENGINEERED Feb98 (RKS)
2166 :
2167 : // PURPOSE OF THIS SUBROUTINE:
2168 : // This subroutine sets the initial temperature and flux histories
2169 : // needed for a stable and reasonable heat balance solution starting
2170 : // point.
2171 :
2172 : // METHODOLOGY EMPLOYED:
2173 : // This subroutine assumes that the simulation is at steady state at
2174 : // the beginning and then begins to vary. Thus, the temperatures, the
2175 : // fluxes. and their histories can all be set to the same value. Some
2176 : // of the initializations depend on the surface characteristics. This
2177 : // requires a DO loop to perform the proper calculation.
2178 :
2179 : // REFERENCES:
2180 : // (I)BLAST legacy routine INITTH
2181 :
2182 : // First do the "bulk" initializations of arrays sized to NumOfZones
2183 54578 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2184 48182 : new (&state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum)) ZoneTempPredictorCorrector::ZoneHeatBalanceData();
2185 : // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
2186 48182 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
2187 48182 : thisZoneHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
2188 48182 : thisZoneHB.airHumRat = state.dataEnvrn->OutHumRat;
2189 48182 : state.dataHeatBalFanSys->TempTstatAir(zoneNum) = DataHeatBalance::ZoneInitialTemp;
2190 : }
2191 54568 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
2192 48172 : thisEnclosure.MRT = DataHeatBalance::ZoneInitialTemp;
2193 6396 : }
2194 : // Reset spaceHeatBalance even if doSpaceHeatBalance is false, because spaceHB is used to gether zoneHB in some cases
2195 54722 : for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
2196 48326 : new (&thisSpaceHB) ZoneTempPredictorCorrector::SpaceHeatBalanceData();
2197 : // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
2198 48326 : thisSpaceHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
2199 48326 : thisSpaceHB.airHumRat = state.dataEnvrn->OutHumRat;
2200 6396 : }
2201 :
2202 : // "Bulk" initializations of arrays sized to TotSurfaces
2203 54578 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2204 96508 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2205 48326 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2206 48326 : int const firstSurf = thisSpace.HTSurfaceFirst;
2207 48326 : int const lastSurf = thisSpace.HTSurfaceLast;
2208 467845 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2209 419519 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = DataHeatBalance::SurfInitialTemp;
2210 419519 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp; // module level array
2211 419519 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = DataHeatBalance::SurfInitialTemp; // module level array
2212 419519 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) = DataHeatBalance::SurfInitialConvCoeff; // module level array
2213 419519 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
2214 419519 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
2215 419519 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
2216 419519 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
2217 419519 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) = 0.0;
2218 419519 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = 0.0;
2219 419519 : state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = 0.0;
2220 419519 : state.dataHeatBalSurf->SurfQConvInRep(SurfNum) = 0.0;
2221 419519 : state.dataHeatBalSurf->SurfQdotConvInRep(SurfNum) = 0.0;
2222 419519 : state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum) = 0.0;
2223 419519 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(SurfNum) = 0.0;
2224 419519 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(SurfNum) = 0.0;
2225 419519 : state.dataHeatBalSurf->SurfQRadSolarInRep(SurfNum) = 0.0;
2226 419519 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(SurfNum) = 0.0;
2227 419519 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(SurfNum) = 0.0;
2228 419519 : state.dataHeatBalSurf->SurfQRadLightsInRep(SurfNum) = 0.0;
2229 419519 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(SurfNum) = 0.0;
2230 419519 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(SurfNum) = 0.0;
2231 419519 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(SurfNum) = 0.0;
2232 419519 : state.dataHeatBalSurf->SurfQRadHVACInRep(SurfNum) = 0.0;
2233 419519 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(SurfNum) = 0.0;
2234 419519 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) = 0.0;
2235 419519 : state.dataHeatBalSurf->SurfQConvOutReport(SurfNum) = 0.0;
2236 419519 : state.dataHeatBalSurf->SurfQdotConvOutRep(SurfNum) = 0.0;
2237 419519 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = 0.0;
2238 419519 : state.dataHeatBalSurf->SurfQRadOutReport(SurfNum) = 0.0;
2239 419519 : state.dataHeatBalSurf->SurfQdotRadOutRep(SurfNum) = 0.0;
2240 419519 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = 0.0;
2241 419519 : state.dataHeatBalSurf->SurfQAirExtReport(SurfNum) = 0.0;
2242 419519 : state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) = 0.0;
2243 : } // end of Surf array
2244 48326 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
2245 48326 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
2246 48326 : if (firstSurfOpaq >= 0) {
2247 411048 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
2248 362722 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = 0.0;
2249 362722 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 0.0;
2250 362722 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(SurfNum) = 0.0;
2251 362722 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
2252 : } // end of Zone Surf
2253 : }
2254 48326 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2255 48326 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2256 48326 : if (firstSurfWin >= 0) {
2257 105113 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2258 : // Initialize window frame and divider temperatures
2259 56787 : state.dataSurface->SurfWinFrameTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
2260 56787 : state.dataSurface->SurfWinFrameTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
2261 56787 : state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
2262 56787 : state.dataSurface->SurfWinDividerTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
2263 56787 : state.dataSurface->SurfWinDividerTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
2264 56787 : state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
2265 :
2266 : // Initialize previous-timestep shading indicators
2267 56787 : state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) = DataSurfaces::WinShadingType::NoShade;
2268 56787 : state.dataSurface->SurfWinShadingFlag(SurfNum) = DataSurfaces::WinShadingType::NoShade;
2269 : } // end of Zone Surf
2270 : }
2271 48182 : }
2272 : } // end of Zone
2273 :
2274 : // "Bulk" initializations of temperature arrays with dimensions (TotSurface,MaxCTFTerms,2)
2275 54578 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2276 96508 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2277 48326 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2278 48326 : int const firstSurf = thisSpace.HTSurfaceFirst;
2279 48326 : int const lastSurf = thisSpace.HTSurfaceLast;
2280 966520 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2281 8889055 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2282 7970861 : state.dataHeatBalSurf->SurfInsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2283 7970861 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2284 7970861 : state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
2285 7970861 : state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
2286 : }
2287 : }
2288 48182 : }
2289 : }
2290 6396 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
2291 17040 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2292 31740 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2293 15918 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2294 15918 : int const firstSurf = thisSpace.HTSurfaceFirst;
2295 15918 : int const lastSurf = thisSpace.HTSurfaceLast;
2296 162951 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2297 147033 : state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
2298 : }
2299 318360 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2300 3096069 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2301 2793627 : state.dataHeatBalSurf->SurfInsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2302 2793627 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2303 2793627 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
2304 2793627 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
2305 : }
2306 : }
2307 15822 : }
2308 : }
2309 : }
2310 6396 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
2311 1170 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2312 1770 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2313 885 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2314 885 : int const firstSurf = thisSpace.HTSurfaceFirst;
2315 885 : int const lastSurf = thisSpace.HTSurfaceLast;
2316 7313 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2317 128560 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2318 122132 : state.dataHeatBalSurf->SurfTsrcHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2319 122132 : state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2320 122132 : state.dataHeatBalSurf->SurfTuserHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2321 122132 : state.dataHeatBalSurf->SurfTuserHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2322 122132 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, CTFTermNum) = 0.0;
2323 122132 : state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, CTFTermNum) = 0.0;
2324 : }
2325 : }
2326 885 : }
2327 : }
2328 : }
2329 6396 : state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
2330 :
2331 : // Perform other initializations that depend on the surface characteristics
2332 71311 : for (int CTFTermNum = 1; CTFTermNum <= state.dataHeatBal->MaxCTFTerms + 1; ++CTFTermNum) {
2333 4639732 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2334 4574817 : auto &surface = state.dataSurface->Surface(SurfNum);
2335 : // Reset outside boundary conditions if necessary
2336 4574817 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
2337 1725165 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
2338 2849652 : } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
2339 214317 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
2340 214317 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
2341 2635335 : } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
2342 16720 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
2343 16720 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
2344 : }
2345 : // Initialize the flux histories
2346 4574817 : state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) =
2347 4574817 : state.dataConstruction->Construct(surface.Construction).UValue *
2348 4574817 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum));
2349 4574817 : state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2350 64915 : }
2351 : }
2352 425920 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2353 419524 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
2354 30 : state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TbaffleLast = 20.0;
2355 30 : state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TairLast = 20.0;
2356 : }
2357 6396 : }
2358 : // Initialize Kiva convection algorithms
2359 6660 : for (int SurfNum : state.dataSurface->AllHTKivaSurfaceList) {
2360 264 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = KIVA_CONST_CONV(3.076);
2361 264 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].f = KIVA_HF_DEF;
2362 264 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].out = KIVA_CONST_CONV(0.0);
2363 6396 : }
2364 6396 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
2365 148251 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2366 147033 : auto &surface = state.dataSurface->Surface(SurfNum);
2367 147033 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
2368 1061560 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2369 1008482 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
2370 : }
2371 147033 : } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
2372 86160 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2373 81852 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
2374 81852 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
2375 : }
2376 89647 : } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
2377 36600 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2378 34770 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
2379 34770 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
2380 : }
2381 : }
2382 916550 : for (int CTFTermNum = 2; CTFTermNum <= state.dataConstruction->Construct(surface.Construction).NumCTFTerms + 1; ++CTFTermNum) {
2383 769517 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2384 769517 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2385 : }
2386 1218 : }
2387 : }
2388 :
2389 6396 : if (state.dataSurface->TotOSCM >= 1) {
2390 292 : for (int OSCMnum = 1; OSCMnum <= state.dataSurface->TotOSCM; ++OSCMnum) {
2391 202 : auto &thisOSC = state.dataSurface->OSCM(OSCMnum);
2392 202 : thisOSC.TConv = 20.0;
2393 202 : thisOSC.HConv = 4.0;
2394 202 : thisOSC.TRad = 20.0;
2395 202 : thisOSC.HRad = 4.0;
2396 : }
2397 : }
2398 6396 : }
2399 :
2400 10122 : void EvalOutsideMovableInsulation(EnergyPlusData &state)
2401 : {
2402 : // This subroutine determines whether or not outside movable insulation on opaque surfaces is present at the current time.
2403 10122 : auto &s_mat = state.dataMaterial;
2404 10122 : auto &s_surf = state.dataSurface;
2405 :
2406 14169 : for (int SurfNum : s_surf->extMovInsulSurfNums) {
2407 4047 : auto &movInsul = s_surf->extMovInsuls(SurfNum);
2408 4047 : Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
2409 4047 : if (MovInsulSchedVal <= 0) { // Movable insulation not present at current time
2410 0 : movInsul.present = false;
2411 0 : int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
2412 0 : auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
2413 0 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisMaterial->AbsorpSolar;
2414 0 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisMaterial->AbsorpThermal;
2415 0 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisMaterial->Roughness;
2416 0 : continue;
2417 0 : }
2418 :
2419 4047 : auto const *mat = s_mat->materials(movInsul.matNum);
2420 4047 : movInsul.present = true;
2421 4047 : movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
2422 4047 : if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) {
2423 2022 : auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
2424 2022 : assert(matGlass != nullptr);
2425 2022 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
2426 2022 : } else {
2427 2025 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = mat->AbsorpSolar;
2428 : }
2429 4047 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = mat->AbsorpThermal;
2430 4047 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = mat->Roughness;
2431 10122 : }
2432 10122 : }
2433 :
2434 10122 : void EvalInsideMovableInsulation(EnergyPlusData &state)
2435 : {
2436 10122 : auto &s_mat = state.dataMaterial;
2437 10122 : auto &s_surf = state.dataSurface;
2438 : // This subroutine determines whether or not inside movable insulation is present at the current time.
2439 16197 : for (int SurfNum : s_surf->intMovInsulSurfNums) {
2440 6075 : auto &movInsul = s_surf->intMovInsuls(SurfNum);
2441 6075 : Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
2442 6075 : if (MovInsulSchedVal <= 0.0) { // Movable insulation not present at current time
2443 0 : movInsul.present = false;
2444 0 : int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
2445 0 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
2446 0 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
2447 0 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
2448 0 : continue;
2449 0 : }
2450 :
2451 6075 : auto const *mat = s_mat->materials(movInsul.matNum);
2452 :
2453 6075 : movInsul.present = true;
2454 6075 : movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
2455 6075 : if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) { // Glass is insulating?
2456 0 : auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
2457 0 : assert(matGlass != nullptr);
2458 0 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
2459 0 : } else {
2460 6075 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = mat->AbsorpSolar;
2461 : }
2462 6075 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = mat->AbsorpThermal;
2463 10122 : }
2464 10122 : }
2465 :
2466 2800078 : void InitSolarHeatGains(EnergyPlusData &state)
2467 : {
2468 :
2469 : // SUBROUTINE INFORMATION:
2470 : // AUTHOR Anonymous
2471 : // DATE WRITTEN July 1977
2472 : // MODIFIED Mar99 (FW): handle movable interior shades and
2473 : // switchable glazing
2474 : // Oct99 (FW): account for Window5 glass calculation approach
2475 : // May01 (FW): handle interior and exterior blinds
2476 : // Sep03 (FW): initialize SurfaceWindow%FrameQRadOutAbs
2477 : // May06 (RR): handle exterior window screens
2478 : // RE-ENGINEERED Feb98 (RKS)
2479 :
2480 : // PURPOSE OF THIS SUBROUTINE:
2481 : // This subroutine initializes the arrays associated with solar heat
2482 : // gains for both individual surfaces and for zones. As a result,
2483 : // this routine sets the following variable arrays:
2484 : // QBV(unused), QDV, QC, QD; SurfOpaqQRadSWOutAbs and SurfOpaqQRadSWInAbs (for opaque surfaces);
2485 : // SurfWinQRadSWwinAbs (for windows)
2486 :
2487 : // METHODOLOGY EMPLOYED:
2488 : // If the sun is down, all of the pertinent arrays are zeroed. If the
2489 : // sun is up, various calculations are made.
2490 :
2491 : // REFERENCES:
2492 : // (I)BLAST legacy routine QSUN
2493 :
2494 2800078 : auto &s_mat = state.dataMaterial;
2495 2800078 : auto &Surface = state.dataSurface->Surface;
2496 :
2497 : // Using/Aliasing
2498 : using Dayltg::TransTDD;
2499 : using SolarShading::CalcInteriorSolarDistribution;
2500 : using namespace DataWindowEquivalentLayer;
2501 : using SolarShading::SurfaceScheduledSolarInc;
2502 : using SolarShading::WindowScheduledSolarAbs;
2503 :
2504 : // Why are these globals?
2505 2800078 : auto &AbsDiffWin = state.dataHeatBalSurfMgr->AbsDiffWin;
2506 2800078 : auto &AbsDiffWinGnd = state.dataHeatBalSurfMgr->AbsDiffWinGnd;
2507 2800078 : auto &AbsDiffWinSky = state.dataHeatBalSurfMgr->AbsDiffWinSky;
2508 :
2509 22623034 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2510 19822956 : state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = 0.0;
2511 19822956 : state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = 0.0;
2512 19822956 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = 0.0;
2513 19822956 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = 0.0;
2514 19822956 : state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) = 0.0;
2515 19822956 : state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) = 0.0;
2516 :
2517 19822956 : state.dataHeatBal->ZoneWinHeatGain(zoneNum) = 0.0;
2518 19822956 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = 0.0;
2519 19822956 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = 0.0;
2520 19822956 : state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) = 0.0;
2521 19822956 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = 0.0;
2522 19822956 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = 0.0;
2523 19822956 : state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) = 0.0;
2524 19822956 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = 0.0;
2525 19822956 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = 0.0;
2526 : }
2527 22618990 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2528 19818912 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0;
2529 : }
2530 22623034 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2531 39694512 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2532 19871556 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2533 19871556 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
2534 19871556 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
2535 167531295 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
2536 147659739 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = 0.0;
2537 147659739 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = 0.0;
2538 147659739 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) = 0.0;
2539 147659739 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) = 0.0;
2540 147659739 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = 0.0;
2541 147659739 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum) = 0.0;
2542 147659739 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
2543 147659739 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(SurfNum) = 0.0;
2544 147659739 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(SurfNum) = 0.0;
2545 : }
2546 :
2547 19871556 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2548 19871556 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2549 42239844 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2550 : // Faster "inline" than calling SurfaceWindow( SurfNum ).InitSolarHeatGains()
2551 22368288 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = 0.0;
2552 22368288 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = 0.0;
2553 22368288 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = 0.0;
2554 22368288 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = 0.0;
2555 22368288 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = 0.0;
2556 22368288 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = 0.0;
2557 22368288 : state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) = 0.0;
2558 22368288 : state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = 0.0;
2559 22368288 : state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = 0.0;
2560 22368288 : state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0;
2561 : }
2562 :
2563 42239844 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2564 22368288 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0;
2565 22368288 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0;
2566 22368288 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0;
2567 22368288 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0;
2568 22368288 : state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0;
2569 22368288 : state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0;
2570 22368288 : state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
2571 22368288 : state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0;
2572 22368288 : state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
2573 : }
2574 42239844 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2575 22368288 : state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0;
2576 22368288 : state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0;
2577 22368288 : state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0;
2578 22368288 : state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0;
2579 22368288 : state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0;
2580 22368288 : state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
2581 22368288 : state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0;
2582 : }
2583 158972448 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
2584 295678908 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2585 156578016 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = 0.0;
2586 : }
2587 : }
2588 19822956 : }
2589 : }
2590 2800078 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
2591 48135 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2592 47332 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
2593 47332 : state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
2594 : }
2595 : }
2596 : bool currSolRadPositive =
2597 2800078 : state.dataEnvrn->SunIsUp && (state.dataEnvrn->BeamSolarRad + state.dataEnvrn->GndSolarRad + state.dataEnvrn->DifSolarRad > 0.0);
2598 2800078 : bool sunset = (!currSolRadPositive) && state.dataEnvrn->PreviousSolRadPositive;
2599 2800078 : bool sunIsUpNoRad = state.dataEnvrn->SunIsUp && (!currSolRadPositive);
2600 2800078 : bool resetSolar = state.dataGlobal->BeginEnvrnFlag || sunIsUpNoRad ||
2601 2800078 : sunset; // Reset at (1) Beginning of simulation (2) sunset time, and SunIsUp but not solar time.
2602 2800078 : state.dataEnvrn->PreviousSolRadPositive = currSolRadPositive;
2603 :
2604 2800078 : if (currSolRadPositive || resetSolar) {
2605 90518687 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2606 89100243 : state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
2607 89100243 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) = 0.0;
2608 89100243 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) = 0.0;
2609 89100243 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) = 0.0;
2610 89100243 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
2611 :
2612 89100243 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) = 0.0;
2613 89100243 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = 0.0;
2614 89100243 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = 0.0;
2615 89100243 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = 0.0;
2616 :
2617 89100243 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) = 0.0;
2618 89100243 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) = 0.0;
2619 89100243 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = 0.0;
2620 89100243 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) = 0.0;
2621 89100243 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = 0.0;
2622 :
2623 89100243 : state.dataSurface->SurfSkySolarInc(SurfNum) = 0.0;
2624 89100243 : state.dataSurface->SurfGndSolarInc(SurfNum) = 0.0;
2625 : }
2626 11504192 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2627 10085748 : state.dataHeatBal->ZoneTransSolar(enclNum) = 0.0;
2628 10085748 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclNum) = 0.0;
2629 10085748 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclNum) = 0.0;
2630 10085748 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclNum) = 0.0;
2631 10085748 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclNum) = 0.0;
2632 10085748 : state.dataHeatBal->ZoneTransSolarEnergy(enclNum) = 0.0;
2633 10085748 : state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclNum) = 0.0;
2634 10085748 : state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclNum) = 0.0;
2635 10085748 : state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclNum) = 0.0;
2636 10085748 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0;
2637 : }
2638 11506260 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2639 20200472 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2640 10112656 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2641 10112656 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2642 10112656 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2643 21545846 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2644 11433190 : state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = 0.0;
2645 11433190 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = 0.0;
2646 11433190 : state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = 0.0;
2647 11433190 : state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum) = 0.0;
2648 11433190 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
2649 11433190 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0;
2650 11433190 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0;
2651 11433190 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum) = 0.0;
2652 11433190 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum) = 0.0;
2653 11433190 : state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0;
2654 : }
2655 21545846 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2656 11433190 : state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = 0.0;
2657 11433190 : state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = 0.0;
2658 11433190 : state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = 0.0;
2659 11433190 : state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = 0.0;
2660 11433190 : state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = 0.0;
2661 11433190 : state.dataSurface->SurfWinScTsolBmBm(SurfNum) = 0.0;
2662 11433190 : state.dataSurface->SurfWinScTsolBmDif(SurfNum) = 0.0;
2663 11433190 : state.dataSurface->SurfWinScTsolDifDif(SurfNum) = 0.0;
2664 11433190 : state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = 0.0;
2665 11433190 : state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = 0.0;
2666 11433190 : state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = 0.0;
2667 11433190 : state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = 0.0;
2668 11433190 : state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = 0.0;
2669 : }
2670 21545846 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2671 11433190 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfNum) = 0.0;
2672 11433190 : state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
2673 11433190 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
2674 11433190 : state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
2675 11433190 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
2676 11433190 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
2677 11433190 : state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
2678 11433190 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
2679 11433190 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
2680 : }
2681 21545846 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2682 11433190 : state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
2683 11433190 : state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
2684 11433190 : state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
2685 11433190 : state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
2686 11433190 : state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
2687 11433190 : state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
2688 11433190 : state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfNum) = 0.0;
2689 11433190 : state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0;
2690 11433190 : state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0;
2691 : }
2692 :
2693 21545846 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2694 11433190 : state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0;
2695 11433190 : state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0;
2696 11433190 : state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0;
2697 11433190 : state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0;
2698 11433190 : state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0;
2699 11433190 : state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0;
2700 11433190 : state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0;
2701 11433190 : state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0;
2702 11433190 : state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0;
2703 11433190 : state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0;
2704 11433190 : state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = 0;
2705 11433190 : state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) = 0.0;
2706 11433190 : state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = 0.0;
2707 : }
2708 80943441 : for (int Lay = 1; Lay <= state.dataHeatBal->MaxSolidWinLayers; Lay++) {
2709 150940110 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2710 80109325 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = 0.0;
2711 : }
2712 : }
2713 70788592 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL; Lay++) {
2714 129275076 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2715 68599140 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay) = 0.0;
2716 : }
2717 : }
2718 10087816 : }
2719 : }
2720 : }
2721 2800078 : if (resetSolar) {
2722 4220743 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
2723 3719433 : state.dataHeatBal->EnclSolQD(enclosureNum) = 0.0;
2724 3719433 : state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) = 0.0;
2725 : }
2726 :
2727 : // TTD domes are currently not considered in the window list of a zone
2728 501310 : if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) {
2729 1233 : for (auto &e : state.dataDaylightingDevicesData->TDDPipe) {
2730 822 : e.TransSolBeam = 0.0;
2731 822 : e.TransSolDiff = 0.0;
2732 822 : e.TransVisBeam = 0.0;
2733 822 : e.TransVisDiff = 0.0;
2734 822 : e.TransmittedSolar = 0.0;
2735 822 : int SurfDome = e.Dome;
2736 822 : state.dataSurface->SurfWinTransSolar(SurfDome) = 0.0;
2737 822 : state.dataHeatBal->SurfQRadSWOutIncident(SurfDome) = 0.0;
2738 822 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfDome) = 0.0;
2739 6576 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
2740 5754 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfDome, Lay) = 0.0;
2741 : }
2742 : }
2743 : }
2744 :
2745 501310 : if (state.dataSurface->CalcSolRefl) {
2746 30175 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2747 27084 : state.dataSurface->SurfBmToBmReflFacObs(SurfNum) = 0.0;
2748 27084 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) = 0.0;
2749 27084 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = 0.0;
2750 : }
2751 : }
2752 33493802 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2753 32992492 : state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0;
2754 32992492 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = 0.0;
2755 32992492 : state.dataHeatBal->SurfSWInAbsTotalReport(SurfNum) = 0.0;
2756 32992492 : state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0;
2757 32992492 : state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0;
2758 32992492 : state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
2759 32992492 : state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
2760 : }
2761 : }
2762 2800078 : if (currSolRadPositive) { // Sun is up, calculate solar quantities
2763 917134 : assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
2764 : state.dataSurface->SurfReflFacBmToDiffSolObs)); // For linear indexing
2765 917134 : assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
2766 : state.dataSurface->SurfReflFacBmToDiffSolGnd)); // For linear indexing
2767 917134 : Real64 GndReflSolarRad = 0.0;
2768 917134 : Real64 GndSolarRadInc = max(state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad, 0.0);
2769 :
2770 57024885 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2771 56107751 : state.dataSurface->Surface(SurfNum).IncSolMultiplier = GetSurfIncidentSolarMultiplier(state, SurfNum);
2772 : }
2773 57024885 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2774 56107751 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2775 56107751 : state.dataSurface->SurfSkySolarInc(SurfNum) =
2776 56107751 : state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2777 56107751 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2778 9408 : GndReflSolarRad = GndSolarRadInc * SurfIncSolarMultiplier *
2779 4704 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2780 4704 : Surface(SurfNum).GndReflSolarRad = GndReflSolarRad;
2781 : } else {
2782 56103047 : GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
2783 : }
2784 56107751 : state.dataSurface->SurfGndSolarInc(SurfNum) = GndReflSolarRad * Surface(SurfNum).ViewFactorGround;
2785 56107751 : state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2786 56107751 : state.dataSurface->SurfWinBmGndSolarInc(SurfNum) = 0.0;
2787 : }
2788 917134 : if (state.dataSurface->CalcSolRefl) {
2789 : // [ lSH ] == ( HourOfDay, SurfNum ) // [ lSP ] == ( PreviousHour, SurfNum )
2790 22984 : Array1D<Real64>::size_type lSH = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->HourOfDay, 1) - 1;
2791 22984 : Array1D<Real64>::size_type lSP = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->PreviousHour, 1) - 1;
2792 : // For Complex Fenestrations:
2793 313999 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2794 291015 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2795 :
2796 291015 : Real64 GndSurfReflectance = 0.0;
2797 291015 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2798 0 : GndSurfReflectance =
2799 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2800 : } else {
2801 291015 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2802 : }
2803 291015 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2804 291015 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2805 291015 : state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) =
2806 291015 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2807 291015 : state.dataSurface->SurfWinBmGndSolarInc(SurfNum) =
2808 291015 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2809 291015 : state.dataSurface->SurfBmToBmReflFacObs(SurfNum) =
2810 291015 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToBmSolObs[lSH + SurfNum] +
2811 291015 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToBmSolObs[lSP + SurfNum];
2812 291015 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) =
2813 291015 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolObs[lSH + SurfNum] +
2814 291015 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolObs[lSP + SurfNum];
2815 291015 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) =
2816 291015 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSH + SurfNum] +
2817 291015 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSP + SurfNum];
2818 : // TH2 CR 9056
2819 291015 : state.dataSurface->SurfSkySolarInc(SurfNum) +=
2820 291015 : currBeamSolarRad * (state.dataSurface->SurfBmToBmReflFacObs(SurfNum) + state.dataSurface->SurfBmToDiffReflFacObs(SurfNum)) +
2821 291015 : currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
2822 291015 : state.dataSurface->SurfGndSolarInc(SurfNum) =
2823 291015 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) +
2824 291015 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2825 291015 : state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2826 : }
2827 : }
2828 :
2829 917134 : SolarShading::CalcWindowProfileAngles(state);
2830 :
2831 917134 : if (state.dataHeatBal->CalcWindowRevealReflection) {
2832 826 : SolarShading::CalcBeamSolarOnWinRevealSurface(state);
2833 : }
2834 :
2835 917134 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() && state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
2836 826 : SolarShading::CalcAbsorbedOnExteriorOpaqueSurfaces(state);
2837 826 : if (state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
2838 826 : SolarShading::CalcInteriorSolarDistributionWCESimple(state);
2839 : }
2840 : } else {
2841 916308 : SolarShading::CalcInteriorSolarDistribution(state);
2842 : }
2843 :
2844 7283449 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
2845 :
2846 : // TH 3/24/2010 - QBV is not used!
2847 : // unused QBV(ZoneNum) = (CBZone(ZoneNum) + EnclSolDB(ZoneNum))*BeamSolarRad
2848 :
2849 : // RJH 08/30/07 - QDV does not seem to ever be used. NOT USED!
2850 : // QDV(ZoneNum) = EnclSolDS(ZoneNum)*DifSolarRad &
2851 : // +EnclSolDG(ZoneNum)*GndSolarRad
2852 :
2853 : // Original QD calc used only for EnclSolQSDifSol and daylighting calcs
2854 : // QDforDaylight(ZoneNum) = EnclSolDB(ZoneNum)*BeamSolarRad &
2855 : // +EnclSolDS(ZoneNum)*DifSolarRad &
2856 : // +EnclSolDG(ZoneNum)*GndSolarRad
2857 :
2858 : // Beam from interior windows (EnclSolDBIntWin) reflected from floor is counted in DayltgInterReflIllFrIntWins,
2859 : // EnclSolDB needs to subtract this part since it is already counted in EnclSolDB.
2860 : // Use EnclSolInitialDifSolReflW (Rob's previous work) as it better counts initial distribution of
2861 : // diffuse solar rather than using weighted area*absorptance
2862 6366315 : state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) =
2863 6366315 : (state.dataHeatBal->EnclSolDB(enclosureNum) - state.dataHeatBal->EnclSolDBIntWin(enclosureNum)) * state.dataEnvrn->BeamSolarRad +
2864 6366315 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) + state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
2865 :
2866 : // to exclude diffuse solar now absorbed/transmitted in CalcWinTransDifSolInitialDistribution
2867 : // EnclSolDB(ZoneNum) is Diffuse Solar from beam reflected from interior surfaces
2868 : // and transmitted through interior windows
2869 : // EnclSolDB is a factor that when multiplied by BeamSolarRad [W/m2] gives Watts
2870 : // QD(ZoneNum) = EnclSolDB(ZoneNum)*BeamSolarRad &
2871 : // +EnclSolDS(ZoneNum)*DifSolarRad &
2872 : // +EnclSolDG(ZoneNum)*GndSolarRad
2873 12732630 : state.dataHeatBal->EnclSolQD(enclosureNum) = state.dataHeatBal->EnclSolDB(enclosureNum) * state.dataEnvrn->BeamSolarRad +
2874 6366315 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) +
2875 6366315 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
2876 : }
2877 :
2878 : // Flux of diffuse solar in each zone
2879 :
2880 7283449 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2881 6366315 : state.dataHeatBal->EnclSolQSDifSol(enclNum) = state.dataHeatBal->EnclSolQDforDaylight(enclNum);
2882 : }
2883 :
2884 917134 : if (state.dataHeatBalSurf->InterZoneWindow) {
2885 18955 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2886 15164 : if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclNum)) {
2887 7582 : Real64 EnclSolQSDifSol_sum(0.0); // Accumulator
2888 7582 : int lZone(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.index(enclNum,
2889 7582 : 1)); // Tuned Linear indexing
2890 37910 : for (int otherEnclNum = 1; otherEnclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++otherEnclNum, ++lZone) {
2891 30328 : if ((otherEnclNum != enclNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(otherEnclNum))) {
2892 7582 : EnclSolQSDifSol_sum += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[lZone] *
2893 7582 : state.dataHeatBal->EnclSolQDforDaylight(otherEnclNum); // [ lZone ] == ( enclNum, otherEnclNum )
2894 : }
2895 : }
2896 7582 : state.dataHeatBal->EnclSolQSDifSol(enclNum) += EnclSolQSDifSol_sum;
2897 : }
2898 : }
2899 : }
2900 :
2901 7283449 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2902 6366315 : if (state.dataHeatBalSurf->InterZoneWindow) {
2903 15164 : state.dataHeatBal->EnclSolQSDifSol(enclNum) *=
2904 15164 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclNum, enclNum) * state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
2905 : } else {
2906 6351151 : state.dataHeatBal->EnclSolQSDifSol(enclNum) *= state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
2907 : }
2908 : }
2909 :
2910 : // RJH - 09-12-07 commented out report variable calcs here since they refer to old distribution method
2911 : // DO SurfNum = 1, TotSurfaces
2912 : // IF (.NOT. Surface(SurfNum)%HeatTransSurf) CYCLE
2913 : //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
2914 : // IF (Surface(SurfNum)%Class == SurfaceClass::Shading) CYCLE
2915 : // ZoneNum = Surface(SurfNum)%Zone
2916 : // Diffuse solar entering zone through exterior windows is assumed to be uniformly
2917 : // distributed on inside face of surfaces of zone
2918 : // DifIncInsSurfIntensRep(SurfNum) = (EnclSolDS(ZoneNum)*DifSolarRad + EnclSolDG(ZoneNum)*GndSolarRad) / &
2919 : // Zone(ZoneNum)%TotalSurfArea
2920 : // DifIncInsSurfAmountRep(SurfNum) = (Surface(SurfNum)%Area + SurfaceWindow(SurfNum)%DividerArea) * &
2921 : // DifIncInsSurfIntensRep(SurfNum)
2922 : // DifIncInsSurfAmountRepEnergy(SurfNum) = DifIncInsSurfAmountRep(SurfNum) * TimeStepZoneSec
2923 : // END DO
2924 :
2925 : // Calculate Exterior Incident Short Wave (i.e. Solar) Radiation on shading surfaces
2926 917134 : if (state.dataSurface->BuildingShadingCount || state.dataSurface->FixedShadingCount || state.dataSurface->AttachedShadingCount) {
2927 2084499 : for (int SurfNum = state.dataSurface->ShadingSurfaceFirst; SurfNum <= state.dataSurface->ShadingSurfaceLast; SurfNum++) {
2928 1780334 : Real64 GndSurfReflectance = 0.0;
2929 1780334 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2930 0 : GndSurfReflectance =
2931 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2932 : } else {
2933 1780334 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2934 : }
2935 : // Cosine of incidence angle and solar incident on outside of surface, for reporting
2936 1780334 : Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
2937 1780334 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = CosInc;
2938 1780334 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2939 1780334 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2940 1780334 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2941 : // Incident direct (unreflected) beam
2942 1780334 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
2943 1780334 : currBeamSolarRad * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) * CosInc;
2944 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
2945 1780334 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2946 : // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
2947 1780334 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2948 : // Incident diffuse solar from beam-to-diffuse reflection from ground
2949 1780334 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
2950 1780334 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2951 : // Incident diffuse solar from sky diffuse reflection from ground
2952 1780334 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
2953 1780334 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
2954 : // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
2955 : // in SkySolarInc.
2956 1780334 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
2957 1780334 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
2958 1780334 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
2959 : }
2960 : }
2961 :
2962 917134 : Array1D<Real64> currBeamSolar(state.dataSurface->TotSurfaces); // Local variable for BeamSolarRad
2963 :
2964 23421354 : for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
2965 22504220 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2966 : // Regular surface
2967 22504220 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2968 22504220 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2969 : // Cosine of incidence angle and solar incident on outside of surface, for reporting
2970 22504220 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
2971 22504220 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
2972 :
2973 : // Report variables for various incident solar quantities
2974 : // Incident direct (unreflected) beam
2975 22504220 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
2976 22504220 : currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
2977 22504220 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum);
2978 :
2979 22504220 : Real64 GndSurfReflectance = 0.0;
2980 22504220 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2981 3528 : GndSurfReflectance =
2982 3528 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2983 : } else {
2984 22500692 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2985 : }
2986 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
2987 22504220 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2988 : // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
2989 22504220 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2990 : // Incident diffuse solar from beam-to-diffuse reflection from ground
2991 22504220 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
2992 22504220 : currBeamSolar(SurfNum) * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2993 :
2994 : // Incident diffuse solar from sky diffuse reflection from ground
2995 22504220 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
2996 22504220 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
2997 : // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
2998 : // in SkySolarInc.
2999 : // SurfQRadSWOutIncident(SurfNum) = SurfQRadSWOutIncidentBeam(SurfNum) + SkySolarInc + GndSolarInc
3000 : // TH2 CR 9056
3001 22504220 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
3002 22504220 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
3003 22504220 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
3004 :
3005 22504220 : if (state.dataSurface->CalcSolRefl) {
3006 : // Incident beam solar from beam-to-beam (specular) reflection from obstructions
3007 173799 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = state.dataSurface->SurfBmToBmReflFacObs(SurfNum) * currBeamSolar(SurfNum);
3008 : // Incident diffuse solar from beam-to-diffuse reflection from obstructions
3009 173799 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) =
3010 173799 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) * currBeamSolar(SurfNum);
3011 : // Incident diffuse solar from sky diffuse reflection from obstructions
3012 173799 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
3013 : // TH2 CR 9056: Add reflections from obstructions to the total incident
3014 347598 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) += state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) +
3015 173799 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) +
3016 173799 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum);
3017 : }
3018 917134 : }
3019 918366 : for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
3020 1232 : int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser; // TDD: Diffuser object number
3021 1232 : int const SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
3022 1232 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3023 1232 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3024 :
3025 : // Reconstruct the beam, sky, and ground radiation transmittance of just the TDD:DOME and TDD pipe
3026 : // by dividing out diffuse solar transmittance of TDD:DIFFUSER
3027 1232 : Real64 ConInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
3028 :
3029 1232 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = ConInc;
3030 1232 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3031 1232 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier *
3032 1232 : TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarBeam) / thisConstruct.TransDiff;
3033 :
3034 2464 : state.dataSurface->SurfSkySolarInc(SurfNum) = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier *
3035 1232 : state.dataSolarShading->SurfAnisoSkyMult(SurfNum2) *
3036 1232 : TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarAniso) / thisConstruct.TransDiff;
3037 :
3038 2464 : state.dataSurface->SurfGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum2) *
3039 1232 : state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolIso / thisConstruct.TransDiff;
3040 : // Incident direct (unreflected) beam
3041 2464 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = currBeamSolar(SurfNum) *
3042 2464 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay,
3043 1232 : state.dataGlobal->TimeStep,
3044 1232 : SurfNum2) *
3045 : ConInc; // NOTE: sunlit and coninc array set to SurfNum2
3046 :
3047 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
3048 1232 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = state.dataSurface->SurfSkySolarInc(SurfNum);
3049 1232 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
3050 1232 : (state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
3051 1232 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum));
3052 : }
3053 :
3054 917750 : for (int ShelfNum = 1; ShelfNum <= (int)state.dataDaylightingDevicesData->Shelf.size(); ++ShelfNum) {
3055 616 : int SurfNum = state.dataDaylightingDevicesData->Shelf(ShelfNum).Window; // Daylighting shelf object number
3056 616 : int OutShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf; // Outside daylighting shelf present if > 0
3057 616 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
3058 616 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
3059 616 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3060 616 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3061 : // Shelf diffuse solar radiation
3062 : Real64 ShelfSolarRad =
3063 616 : (currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) *
3064 616 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) +
3065 616 : state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(OutShelfSurf)) *
3066 616 : state.dataDaylightingDevicesData->Shelf(ShelfNum).OutReflectSol;
3067 :
3068 616 : GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
3069 616 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
3070 0 : GndReflSolarRad = state.dataSurface->Surface(SurfNum).GndReflSolarRad;
3071 : }
3072 : // Add all reflected solar from the outside shelf to the ground solar
3073 : // NOTE: If the shelf blocks part of the view to the ground, the user must reduce the ground view factor!!
3074 616 : state.dataSurface->SurfGndSolarInc(SurfNum) =
3075 616 : GndReflSolarRad * Surface(SurfNum).ViewFactorGround + ShelfSolarRad * state.dataDaylightingDevicesData->Shelf(ShelfNum).ViewFactor;
3076 : }
3077 :
3078 : // Calculate Exterior and Interior Absorbed Short Wave Radiation
3079 7284688 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3080 12749976 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3081 6382422 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
3082 6382422 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
3083 6382422 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
3084 53383723 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
3085 47001301 : int const ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
3086 47001301 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3087 47001301 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3088 47001301 : if (Surface(SurfNum).ExtSolar) {
3089 : Real64 AbsExt =
3090 13429814 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); // Absorptivity of outer most layer (or movable insulation if present)
3091 13429814 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
3092 13429814 : state.dataSurface->SurfOpaqAO(SurfNum) * currBeamSolar(SurfNum) +
3093 13429814 : AbsExt * (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum));
3094 : }
3095 47001301 : if (ConstrNum > 0) {
3096 47001301 : int SurfSolIncPtr = SolarShading::SurfaceScheduledSolarInc(state, SurfNum, ConstrNum);
3097 47001301 : if (SurfSolIncPtr == 0) {
3098 47000713 : if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Opaque surface
3099 47000713 : int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum); // Daylighting shelf object number
3100 47000713 : int InShelfSurf = 0; // Inside daylighting shelf surface number
3101 47000713 : if (ShelfNum > 0) {
3102 0 : InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf; // Inside daylighting shelf present if > 0
3103 : }
3104 47000713 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +=
3105 47000713 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum);
3106 47000713 : if (InShelfSurf > 0) { // Inside daylighting shelf
3107 : // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init)
3108 0 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
3109 0 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * (0.5 * Surface(SurfNum).Area);
3110 : } else { // Regular surface
3111 47000713 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
3112 47000713 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * Surface(SurfNum).Area;
3113 : }
3114 : }
3115 : } else {
3116 588 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum);
3117 : }
3118 : }
3119 : }
3120 6382422 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
3121 6382422 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
3122 13685004 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
3123 7302582 : auto &surf = state.dataSurface->Surface(SurfNum);
3124 7302582 : auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
3125 7302582 : if (surf.ExtSolar || surf.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
3126 : // Exclude special shading surfaces which required SurfOpaqQRadSWOut calculations above
3127 7294072 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3128 7294072 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3129 7294072 : Real64 CosInc = state.dataHeatBal->SurfCosIncidenceAngle(SurfNum); // Cosine of incidence angle of beam solar on glass
3130 7294072 : Real64 BeamSolar = currBeamSolar(SurfNum); // Local variable for BeamSolarRad
3131 7294072 : Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum); // Sky diffuse solar incident on a surface
3132 7294072 : Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum); // Ground diffuse solar incident on a surface
3133 :
3134 7294072 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
3135 :
3136 14573423 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed &&
3137 7279351 : !state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
3138 7278525 : int TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
3139 16644687 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3140 9366162 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
3141 : }
3142 :
3143 7278525 : if (IS_SHADED(ShadeFlag)) { // Shaded window
3144 :
3145 184702 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); // Shaded window construction
3146 184702 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3147 :
3148 184702 : if (ANY_SHADE_SCREEN(ShadeFlag)) { // Shade/screen on
3149 116218 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3150 74732 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = constructionSh.AbsDiff(Lay);
3151 : }
3152 41486 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = constructionSh.AbsDiffShade * (SkySolarInc + GndSolarInc);
3153 :
3154 143216 : } else if (ANY_BLIND(ShadeFlag)) { // Blind on
3155 71430 : auto &surfShade = state.dataSurface->surfShades(SurfNum);
3156 71430 : int slatIdxLo = surfShade.blind.slatAngIdxLo;
3157 71430 : int slatIdxHi = surfShade.blind.slatAngIdxHi;
3158 71430 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3159 : Real64 AbsDiffBlind;
3160 :
3161 : // For constructions, have to do interpolation whether we have movable slats or not
3162 147298 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3163 75868 : auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
3164 75868 : auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
3165 :
3166 75868 : AbsDiffWin(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.Abs, dfAbsSlatHi.Sol.Ft.Df.Abs, interpFac);
3167 75868 : AbsDiffWinGnd(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3168 75868 : AbsDiffWinSky(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3169 : }
3170 :
3171 71430 : auto const &tarSlatLo = constructionSh.blindTARs[slatIdxLo];
3172 71430 : auto const &tarSlatHi = constructionSh.blindTARs[slatIdxHi];
3173 71430 : AbsDiffBlind = Interp(tarSlatLo.Sol.Ft.Df.Abs, tarSlatHi.Sol.Ft.Df.Abs, interpFac);
3174 :
3175 71430 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = AbsDiffBlind * (SkySolarInc + GndSolarInc);
3176 :
3177 71430 : auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
3178 71430 : if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
3179 71430 : Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt);
3180 :
3181 : // Need to do these interpolations unless we want to cache this in surfShade.blind.
3182 71430 : Real64 AbsDiffBlindGnd = Interp(tarSlatLo.Sol.Ft.Df.AbsGnd, tarSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3183 71430 : Real64 AbsDiffBlindSky = Interp(tarSlatLo.Sol.Ft.Df.AbsSky, tarSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3184 :
3185 71430 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) =
3186 71430 : SkySolarInc * (0.5 * ACosTlt * AbsDiffBlindGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffBlindSky) +
3187 71430 : GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffBlindGnd + 0.5 * ACosTlt * AbsDiffBlindSky);
3188 : }
3189 : }
3190 :
3191 : // Correct for shadowing of divider onto interior shading device (note that dividers are
3192 : // not allowed in windows with between-glass shade/blind)
3193 :
3194 184702 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
3195 742 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) *= surfWin.glazedFrac;
3196 : }
3197 :
3198 184702 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3199 71786 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for switchable glazing
3200 215358 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3201 143572 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) =
3202 143572 : Window::InterpSw(SwitchFac, state.dataHeatBalSurfMgr->AbsDiffWin(Lay), constructionSh.AbsDiff(Lay));
3203 : }
3204 : }
3205 :
3206 : } // End of check if window has shading device on
3207 :
3208 7278525 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3209 16644687 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3210 9366162 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3211 9366162 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc) +
3212 9366162 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3213 : // SurfWinA is from InteriorSolarDistribution
3214 9366162 : if (ANY_BLIND(ShadeFlag)) {
3215 75868 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3216 75868 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3217 75868 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3218 75868 : auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
3219 75868 : if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
3220 :
3221 75868 : Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); // Absolute value of cosine of surface tilt angle
3222 :
3223 75868 : int slatIdxLo = surfShade.blind.slatAngIdxLo;
3224 75868 : int slatIdxHi = surfShade.blind.slatAngIdxLo;
3225 75868 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3226 75868 : auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
3227 75868 : auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
3228 :
3229 75868 : Real64 AbsDiffGlassLayGnd = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3230 75868 : Real64 AbsDiffGlassLaySky = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3231 :
3232 75868 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3233 75868 : SkySolarInc * (0.5 * ACosTlt * AbsDiffGlassLayGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffGlassLaySky) +
3234 151736 : GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffGlassLayGnd + 0.5 * ACosTlt * AbsDiffGlassLaySky) +
3235 75868 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3236 : }
3237 : }
3238 : // Total solar absorbed in solid layer (W), for reporting
3239 9366162 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3240 9366162 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3241 :
3242 : // Total solar absorbed in all glass layers (W), for reporting
3243 9366162 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3244 : }
3245 7278525 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3246 7278525 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3247 : // Need to do it this way for now because of scheduled surface gains. They do work only with
3248 : // BSDF windows and overwriting absorbtances will work only for ordinary windows
3249 : // } else if ( SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: BSDF &&
3250 : // SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: EQL &&
3251 : // inExtWindowModel->isExternalLibraryModel() ) {
3252 : // TotSolidLay = Construct( ConstrNum ).TotSolidLayers;
3253 : // for ( Lay = 1; Lay <= TotSolidLay; ++Lay ) {
3254 : // SurfWinQRadSWwinAbs( Lay, SurfNum ) = SurfWinA( Lay, SurfNum ) *
3255 : // ( SurfQRadSWOutIncident( SurfNum ) + QS( Surface( SurfNum ).Zone ) );
3256 : // }
3257 15547 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
3258 12243 : int TotSolidLay = state.dataConstruction->Construct(ConstrNum).TotSolidLayers;
3259 : // Number of solid layers in fenestration system (glass + shading)
3260 12243 : int CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState;
3261 : // Current state for Complex Fenestration
3262 : // Examine for schedule surface gain
3263 12243 : Real64 SurfSolAbs = SolarShading::WindowScheduledSolarAbs(
3264 : state,
3265 : SurfNum,
3266 12243 : ConstrNum); // Pointer to scheduled surface gains object for fenestration systems
3267 :
3268 46277 : for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
3269 34034 : if (SurfSolAbs != 0) {
3270 294 : state.dataSurface->SurfWinA(SurfNum, Lay) =
3271 294 : state.dataSurface->FenLayAbsSSG(SurfSolAbs).scheds(Lay)->getCurrentVal();
3272 : // ABWin(Lay) = SurfWinA(SurfNum,Lay)
3273 294 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = state.dataSurface->SurfWinA(SurfNum, Lay);
3274 : } else {
3275 : // Several notes about this equation. First part is accounting for diffuse solar radiation for the ground
3276 : // and from the sky. Second item (SurfWinA(SurfNum,Lay) * BeamSolar) is accounting for absorbed solar
3277 : // radiation originating from beam on exterior side. Third item (SurfWinACFOverlap(SurfNum,Lay)) is
3278 : // accounting for absorptances from beam hitting back of the window which passes through rest of exterior
3279 : // windows
3280 33740 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3281 33740 : state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyFtAbs(Lay) * SkySolarInc +
3282 33740 : state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyGndAbs(Lay) * GndSolarInc +
3283 33740 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
3284 33740 : state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * BeamSolar;
3285 : }
3286 : // Total solar absorbed in solid layer (W), for reporting
3287 34034 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3288 34034 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3289 :
3290 : // Total solar absorbed in all glass layers (W), for reporting
3291 34034 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3292 : }
3293 12243 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3294 12243 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3295 :
3296 3304 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
3297 2478 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3298 : // EQLNum = Construct(Surface(SurfNum)%Construction)%EQLConsPtr
3299 : int TotSolidLay =
3300 2478 : state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(Surface(SurfNum).Construction).EQLConsPtr).NL;
3301 11564 : for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
3302 : // Absorbed window components include:
3303 : // (1) beam solar radiation absorbed by all layers in the fenestration
3304 : // (2) sky and ground reflected diffuse solar radiation absorbed by all layers
3305 : // (3) diffuse short wave incident on the inside face of the fenestration. The short wave internal sources
3306 : // include light, ...
3307 9086 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay);
3308 9086 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3309 9086 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
3310 9086 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc);
3311 :
3312 : // Total solar absorbed in solid layer (W), for reporting
3313 9086 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3314 9086 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3315 :
3316 : // Total solar absorbed in all glass layers (W), for reporting
3317 9086 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3318 : }
3319 :
3320 2478 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3321 2478 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3322 826 : } else if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
3323 826 : int SurfNum2 = SurfNum;
3324 826 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
3325 0 : SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
3326 : }
3327 :
3328 : std::pair<Real64, Real64> incomingAngle =
3329 826 : Window::getSunWCEAngles(state, SurfNum2, SingleLayerOptics::BSDFDirection::Incoming);
3330 826 : Real64 Theta = incomingAngle.first;
3331 826 : Real64 Phi = incomingAngle.second;
3332 :
3333 : std::shared_ptr<MultiLayerOptics::CMultiLayerScattered> aLayer =
3334 826 : Window::CWindowConstructionsSimplified::instance(state).getEquivalentLayer(
3335 826 : state, FenestrationCommon::WavelengthRange::Solar, ConstrNum);
3336 :
3337 826 : size_t totLayers = aLayer->getNumOfLayers();
3338 1652 : for (size_t Lay = 1; Lay <= totLayers; ++Lay) {
3339 826 : Real64 AbWinDiff = aLayer->getAbsorptanceLayer(
3340 : Lay, FenestrationCommon::Side::Front, FenestrationCommon::ScatteringSimple::Diffuse, Theta, Phi);
3341 :
3342 826 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3343 826 : AbWinDiff * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3344 :
3345 : // Total solar absorbed in solid layer (W), for reporting
3346 826 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3347 826 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3348 :
3349 : // Total solar absorbed in all glass layers (W), for reporting
3350 826 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3351 : }
3352 826 : }
3353 :
3354 : // Solar absorbed by window frame and dividers
3355 7294072 : int FrDivNum = Surface(SurfNum).FrameDivider; // Frame/divider number
3356 7294072 : if (FrDivNum > 0) {
3357 304322 : Real64 FrArea = state.dataSurface->SurfWinFrameArea(SurfNum); // Frame, divider area (m2)
3358 304322 : Real64 FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut; // Frame, divider outside projection (m)
3359 304322 : Real64 FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn;
3360 304322 : Real64 DivArea = state.dataSurface->SurfWinDividerArea(SurfNum);
3361 304322 : Real64 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
3362 304322 : Real64 DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut;
3363 304322 : Real64 DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn;
3364 304322 : Real64 CosIncAngHorProj = 0.0; // Cosine of incidence angle of sun on horizontal faces of a frame or divider projection
3365 304322 : Real64 CosIncAngVertProj = 0.0; // Cosine of incidence angle of sun on vertical faces of a frame or divider projection
3366 304322 : Real64 FracSunLit = 0.0; // Fraction of window sunlit this time step
3367 : Real64 BeamFaceInc; // Beam solar incident window plane this time step (W/m2)
3368 : Real64 DifSolarFaceInc; // Diffuse solar incident on window plane this time step (W/m2)
3369 304322 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3370 304322 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3371 304322 : if (FrArea > 0.0 || DivArea > 0.0) {
3372 185302 : FracSunLit = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
3373 185302 : BeamFaceInc = currBeamSolarRad *
3374 185302 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
3375 : CosInc;
3376 185302 : DifSolarFaceInc = SkySolarInc + GndSolarInc;
3377 : }
3378 304322 : if (FracSunLit > 0.0) {
3379 128315 : if ((FrArea > 0.0 && (FrProjOut > 0.0 || FrProjIn > 0.0)) ||
3380 19572 : (DivArea > 0.0 && (DivProjOut > 0.0 || DivProjIn > 0.0))) {
3381 : // Dot products used to calculate beam solar incident on faces of
3382 : // frame and divider perpendicular to the glass surface.
3383 : // Note that SOLCOS is the current timestep's solar direction cosines.
3384 : // PhiWin = ASIN(WALCOS(3,SurfNum))
3385 : Real64 PhiWin =
3386 100049 : std::asin(Surface(SurfNum).OutNormVec(3)); // Altitude and azimuth angle of outward window normal (radians)
3387 100049 : Real64 ThWin = std::atan2(Surface(SurfNum).OutNormVec(2), Surface(SurfNum).OutNormVec(1));
3388 100049 : Real64 PhiSun = std::asin(state.dataEnvrn->SOLCOS(3)); // Altitude and azimuth angle of sun (radians)
3389 100049 : Real64 ThSun = std::atan2(state.dataEnvrn->SOLCOS(2), state.dataEnvrn->SOLCOS(1));
3390 100049 : Real64 const cos_PhiWin(std::cos(PhiWin));
3391 100049 : Real64 const cos_PhiSun(std::cos(PhiSun));
3392 : CosIncAngHorProj =
3393 100049 : std::abs(std::sin(PhiWin) * cos_PhiSun * std::cos(ThWin - ThSun) - cos_PhiWin * std::sin(PhiSun));
3394 100049 : CosIncAngVertProj = std::abs(cos_PhiWin * cos_PhiSun * std::sin(ThWin - ThSun));
3395 : }
3396 : }
3397 : // Frame solar
3398 : // (A window shade or blind, if present, is assumed to not shade the frame, so no special
3399 : // treatment of frame solar needed if window has an exterior shade or blind.)
3400 304322 : if (FrArea > 0.0) {
3401 185302 : Real64 FrIncSolarOut = BeamFaceInc; // Total solar incident on outside of frame including solar
3402 185302 : Real64 FrIncSolarIn = 0.0; // Total solar incident on inside of frame including solar on frame projection (W/m2)
3403 185302 : Real64 TransDiffGl = 0.0; // Diffuse solar transmittance
3404 185302 : if (FrProjOut > 0.0 || FrProjIn > 0.0) {
3405 : Real64 BeamFrHorFaceInc =
3406 261364 : currBeamSolarRad * CosIncAngHorProj *
3407 130682 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit /
3408 130682 : FrArea;
3409 : Real64 BeamFrVertFaceInc =
3410 261364 : currBeamSolarRad * CosIncAngVertProj *
3411 130682 : (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
3412 130682 : FrArea;
3413 : // Beam solar on outside of frame
3414 130682 : FrIncSolarOut += (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjOut;
3415 130682 : if (FrProjIn > 0.0) {
3416 130682 : Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
3417 130682 : TransDiffGl = thisConstruct.TransDiff;
3418 130682 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3419 71044 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3420 71044 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3421 71044 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3422 71044 : Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
3423 71044 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3424 71044 : Real64 TransDiffGlSh = constructionSh.TransDiff;
3425 71044 : TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
3426 : }
3427 : // Beam solar on inside of frame
3428 130682 : FrIncSolarIn = (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjIn * TransGl;
3429 : }
3430 : }
3431 : // Beam plus diffuse solar on outside of frame
3432 185302 : FrIncSolarOut += DifSolarFaceInc * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum));
3433 185302 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) =
3434 185302 : FrIncSolarOut * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3435 : // Add diffuse from beam reflected from window outside reveal surfaces
3436 185302 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) += currBeamSolarRad *
3437 185302 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) *
3438 185302 : state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3439 :
3440 : // Beam plus diffuse solar on inside of frame
3441 185302 : FrIncSolarIn += DifSolarFaceInc * TransDiffGl * 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum);
3442 185302 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = FrIncSolarIn * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3443 : // Add diffuse from beam reflected from window inside reveal surfaces
3444 185302 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += currBeamSolarRad *
3445 185302 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) *
3446 185302 : state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3447 : }
3448 :
3449 : // Divider solar
3450 : // (An exterior shade or blind, when in place, is assumed to completely cover the divider.
3451 : // Dividers are not allowed on windows with between-glass shade/blind so DivProjOut and
3452 : // DivProjIn will be zero in this case.)
3453 304322 : if (DivArea > 0.0) { // Solar absorbed by window divider
3454 140236 : Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
3455 140236 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
3456 : // Suspended (between-glass) divider; account for effect glass on outside of divider
3457 : // (note that outside and inside projection for this type of divider are both zero)
3458 8004 : int MatNumGl = thisConstruct.LayerPoint(1); // Outer glass layer material number
3459 8004 : auto const *thisMaterial = dynamic_cast<Material::MaterialFen *>(s_mat->materials(MatNumGl));
3460 8004 : assert(thisMaterial != nullptr);
3461 8004 : Real64 TransGl = thisMaterial->Trans; // Outer glass layer material number, switched construction
3462 8004 : Real64 ReflGl = thisMaterial->ReflectSolBeamFront;
3463 8004 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
3464 8004 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3465 8004 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3466 8004 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3467 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3468 0 : Real64 MatNumGlSh = constructionSh.LayerPoint(1);
3469 0 : auto const *thisMaterialSh = dynamic_cast<Material::MaterialGlass *>(s_mat->materials(MatNumGlSh));
3470 0 : assert(thisMaterialSh != nullptr);
3471 0 : Real64 TransGlSh = thisMaterialSh->Trans;
3472 0 : Real64 ReflGlSh = thisMaterialSh->ReflectSolBeamFront;
3473 0 : Real64 AbsGlSh = 1.0 - TransGlSh - ReflGlSh;
3474 0 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3475 0 : ReflGl = Window::InterpSw(SwitchFac, ReflGl, ReflGlSh);
3476 0 : AbsGl = Window::InterpSw(SwitchFac, AbsGl, AbsGlSh);
3477 : }
3478 8004 : Real64 DividerRefl = 1.0 - DividerAbs; // Window divider solar reflectance
3479 8004 : DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
3480 : }
3481 :
3482 140236 : Real64 BeamDivHorFaceInc = 0.0; // Beam solar on divider's horizontal outside projection faces (W/m2)
3483 140236 : Real64 BeamDivVertFaceInc = 0.0; // Beam solar on divider's vertical outside projection faces (W/m2)
3484 : // Beam incident on horizontal and vertical projection faces of divider if no exterior shading
3485 140236 : if (DivProjOut > 0.0 && !DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3486 95784 : BeamDivHorFaceInc = currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers *
3487 95784 : DivProjOut *
3488 95784 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
3489 : FracSunLit / DivArea;
3490 95784 : BeamDivVertFaceInc =
3491 95784 : currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivProjOut *
3492 95784 : (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
3493 : DivArea;
3494 : }
3495 140236 : Real64 DivIncSolarOutBm =
3496 : 0.0; // Diffuse solar incident on outside of divider including beam on divider projection (W/m2)
3497 140236 : Real64 DivIncSolarOutDif =
3498 : 0.0; // Diffuse solar incident on outside of divider including diffuse on divider projection (W/m2)
3499 140236 : Real64 DivIncSolarInBm =
3500 : 0.0; // Diffuse solar incident on inside of divider including beam on divider projection (W/m2)
3501 140236 : Real64 DivIncSolarInDif =
3502 : 0.0; // Diffuse solar incident on inside of divider including diffuse on divider projection (W/m2)
3503 271912 : if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) &&
3504 131676 : !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { // No exterior or between-glass shading
3505 131676 : DivIncSolarOutBm = BeamFaceInc + BeamDivHorFaceInc + BeamDivVertFaceInc;
3506 131676 : DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3507 131676 : if (DivProjIn > 0.0) {
3508 95784 : Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
3509 95784 : Real64 TransDiffGl = thisConstruct.TransDiff; // Diffuse solar transmittance
3510 95784 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3511 71044 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3512 71044 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3513 71044 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3514 :
3515 71044 : Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
3516 : // Outer glass solar trans, refl, absorptance if switched
3517 71044 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3518 71044 : Real64 TransDiffGlSh = constructionSh.TransDiff;
3519 : // Diffuse solar transmittance, switched construction
3520 71044 : TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
3521 : }
3522 : // Beam plus diffuse solar on inside of divider
3523 : // BeamDivHorFaceIncIn - Beam solar on divider's horizontal inside projection faces (W/m2)
3524 : // BeamDivVertFaceIncIn - Beam solar on divider's vertical inside projection faces (W/m2)
3525 : Real64 BeamDivHorFaceIncIn =
3526 95784 : currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivProjIn *
3527 95784 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
3528 95784 : FracSunLit / DivArea;
3529 : Real64 BeamDivVertFaceIncIn =
3530 95784 : currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers *
3531 95784 : DivProjIn * (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) *
3532 95784 : FracSunLit / DivArea;
3533 95784 : DivIncSolarInBm = TransGl * (BeamDivHorFaceIncIn + BeamDivVertFaceIncIn);
3534 95784 : DivIncSolarInDif = TransDiffGl * DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum);
3535 : }
3536 : } else { // Exterior shade, screen or blind present
3537 :
3538 8560 : DivIncSolarOutBm = BeamFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3539 8560 : DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3540 8560 : DivIncSolarInBm = BeamFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
3541 8560 : DivIncSolarInDif = DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
3542 : }
3543 :
3544 140236 : if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
3545 : // No exterior or between-glass shade, screen or blind
3546 131676 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = DividerAbs * (DivIncSolarOutBm + DivIncSolarOutDif);
3547 131676 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = DividerAbs * (DivIncSolarInBm + DivIncSolarInDif);
3548 : // Exterior shade, screen or blind
3549 :
3550 8560 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) { // Exterior blind
3551 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3552 :
3553 0 : int profIdxLo = surfShade.blind.profAngIdxLo;
3554 0 : int profIdxHi = surfShade.blind.profAngIdxHi;
3555 0 : Real64 profInterpFac = surfShade.blind.profAngInterpFac;
3556 :
3557 0 : auto const &btarLo = surfShade.blind.TAR.Sol.Ft.Bm[profIdxLo];
3558 0 : auto const &btarHi = surfShade.blind.TAR.Sol.Ft.Bm[profIdxHi];
3559 :
3560 0 : Real64 FrontDiffTrans = surfShade.blind.TAR.Sol.Ft.Df.Tra;
3561 0 : Real64 TBlBmDif = Interp(btarLo.DfTra, btarHi.DfTra, profInterpFac);
3562 :
3563 : // TBlBmBm - Blind beam-beam solar transmittance
3564 0 : Real64 TBlBmBm = surfShade.blind.bmBmTrans;
3565 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3566 0 : DividerAbs * (DivIncSolarOutBm * (TBlBmBm + TBlBmDif) + DivIncSolarOutDif * FrontDiffTrans);
3567 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3568 0 : DividerAbs * (DivIncSolarInBm * (TBlBmBm + TBlBmDif) + DivIncSolarInDif * FrontDiffTrans);
3569 :
3570 8560 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtShade) { // Exterior shade
3571 8560 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3572 8560 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3573 8560 : auto const *matFen = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(constructionSh.LayerPoint(1)));
3574 8560 : assert(matFen != nullptr);
3575 8560 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3576 8560 : DividerAbs * matFen->Trans * (DivIncSolarOutBm + DivIncSolarOutDif);
3577 8560 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3578 8560 : DividerAbs * matFen->Trans * (DivIncSolarInBm + DivIncSolarInDif);
3579 :
3580 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtScreen) { // Exterior screen
3581 0 : int screenNum = surfWin.screenNum;
3582 0 : auto const *screen = dynamic_cast<Material::MaterialScreen const *>(s_mat->materials(screenNum));
3583 0 : assert(screen != nullptr);
3584 :
3585 0 : auto &surf = state.dataSurface->Surface(SurfNum);
3586 : Real64 phi, theta;
3587 0 : Material::GetRelativePhiTheta(
3588 0 : surf.Tilt * Constant::DegToRad, surf.Azimuth * Constant::DegToRad, state.dataEnvrn->SOLCOS, phi, theta);
3589 : #ifdef PRECALC_INTERP_SCREEN
3590 : int ip1, ip2, it1, it2; // hi/lo phi and theta map indices
3591 : BilinearInterpCoeffs coeffs;
3592 0 : Material::GetPhiThetaIndices(phi, theta, screen->dPhi, screen->dTheta, ip1, ip2, it1, it2);
3593 0 : GetBilinearInterpCoeffs(
3594 0 : phi, theta, ip1 * screen->dPhi, ip2 * screen->dPhi, it1 * screen->dTheta, it2 * screen->dTheta, coeffs);
3595 0 : auto const &b11 = screen->btars[ip1][it1];
3596 0 : auto const &b12 = screen->btars[ip1][it2];
3597 0 : auto const &b21 = screen->btars[ip2][it1];
3598 0 : auto const &b22 = screen->btars[ip2][it2];
3599 0 : Real64 BmDfTrans = BilinearInterp(b11.DfTrans, b12.DfTrans, b21.DfTrans, b22.DfTrans, coeffs);
3600 0 : Real64 BmBmTrans = BilinearInterp(b11.BmTrans, b12.BmTrans, b21.BmTrans, b22.BmTrans, coeffs);
3601 :
3602 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3603 0 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
3604 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3605 0 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
3606 : #else // !PRECALC_INTERP_SCREEN
3607 : Material::ScreenBmTransAbsRef btar;
3608 :
3609 : Material::CalcScreenTransmittance(state, screen, phi, theta, btar);
3610 : Real64 BmDfTrans = btar.DfTrans;
3611 : Real64 BmBmTrans = btar.BmTrans;
3612 :
3613 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3614 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
3615 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3616 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
3617 : #endif // PRECALC_INTERP_SCREEN
3618 : }
3619 : }
3620 : }
3621 : } // Surface(SurfNum)%ExtSolar
3622 : } // end of surface window loop
3623 6367554 : } // end of space loop
3624 : } // end of zone loop
3625 918366 : for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
3626 1232 : int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
3627 1232 : int const ConstrNum = Surface(SurfNum).Construction;
3628 1232 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3629 1232 : int const TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
3630 1232 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3631 2464 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3632 1232 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
3633 1232 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3634 1232 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) *
3635 1232 : (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum)) +
3636 1232 : state.dataSurface->SurfWinA(SurfNum, Lay) * currBeamSolar(SurfNum);
3637 1232 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3638 1232 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3639 1232 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3640 1232 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3641 1232 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3642 : }
3643 : }
3644 :
3645 : // Average absorbed solar for representative surfaces
3646 917134 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
3647 4606 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3648 9016 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3649 4508 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
3650 4508 : int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
3651 4508 : int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
3652 43806 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
3653 39298 : auto &surface = state.dataSurface->Surface(surfNum);
3654 39298 : if (surface.ConstituentSurfaceNums.size() > 1) {
3655 1470 : Real64 QoutAtot = 0.0;
3656 1470 : Real64 QinAtot = 0.0;
3657 1470 : Real64 Atot = 0.0;
3658 4606 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3659 3136 : QoutAtot += state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
3660 3136 : QinAtot += state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
3661 3136 : Atot += state.dataSurface->Surface(constSurfNum).Area;
3662 1470 : }
3663 :
3664 1470 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = QoutAtot / Atot;
3665 1470 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = QinAtot / Atot;
3666 : }
3667 : }
3668 4508 : firstSurf = thisSpace.WindowSurfaceFirst;
3669 4508 : lastSurf = thisSpace.WindowSurfaceLast;
3670 21952 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
3671 17444 : auto const &surface = state.dataSurface->Surface(surfNum);
3672 17444 : if (surface.ExtSolar && surface.ConstituentSurfaceNums.size() > 1) {
3673 : // Absorbed in glazing
3674 : int totalGlassLayers =
3675 1862 : state.dataConstruction->Construct(state.dataSurface->SurfActiveConstruction(surfNum)).TotGlassLayers;
3676 5586 : for (int layer = 1; layer <= totalGlassLayers; ++layer) {
3677 3724 : Real64 QAtot = 0.0;
3678 3724 : Real64 Atot = 0.0;
3679 29792 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3680 26068 : QAtot +=
3681 26068 : state.dataHeatBal->SurfWinQRadSWwinAbs(constSurfNum, layer) * state.dataSurface->Surface(constSurfNum).Area;
3682 26068 : Atot += state.dataSurface->Surface(constSurfNum).Area;
3683 3724 : }
3684 :
3685 3724 : state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, layer) = QAtot / Atot;
3686 : }
3687 :
3688 : // Absorbed by frame and dividers
3689 1862 : if (surface.FrameDivider > 0) {
3690 196 : if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
3691 0 : Real64 QoutAtot = 0.0;
3692 0 : Real64 QinAtot = 0.0;
3693 0 : Real64 Atot = 0.0;
3694 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3695 0 : QoutAtot += state.dataSurface->SurfWinFrameQRadOutAbs(constSurfNum) *
3696 0 : state.dataSurface->SurfWinFrameArea(constSurfNum);
3697 0 : QinAtot += state.dataSurface->SurfWinFrameQRadInAbs(constSurfNum) *
3698 0 : state.dataSurface->SurfWinFrameArea(constSurfNum);
3699 0 : Atot += state.dataSurface->SurfWinFrameArea(constSurfNum);
3700 0 : }
3701 :
3702 0 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = QoutAtot / Atot;
3703 0 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = QinAtot / Atot;
3704 : }
3705 196 : if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
3706 0 : Real64 QoutAtot = 0.0;
3707 0 : Real64 QinAtot = 0.0;
3708 0 : Real64 Atot = 0.0;
3709 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3710 0 : QoutAtot += state.dataSurface->SurfWinDividerQRadOutAbs(constSurfNum) *
3711 0 : state.dataSurface->SurfWinDividerArea(constSurfNum);
3712 0 : QinAtot += state.dataSurface->SurfWinDividerQRadInAbs(constSurfNum) *
3713 0 : state.dataSurface->SurfWinDividerArea(constSurfNum);
3714 0 : Atot += state.dataSurface->SurfWinDividerArea(constSurfNum);
3715 0 : }
3716 :
3717 0 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = QoutAtot / Atot;
3718 0 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = QinAtot / Atot;
3719 : }
3720 : }
3721 : }
3722 : }
3723 4508 : }
3724 : }
3725 : }
3726 917134 : } // End of sun-up check
3727 2800078 : }
3728 :
3729 2800078 : void InitIntSolarDistribution(EnergyPlusData &state)
3730 : {
3731 :
3732 : // SUBROUTINE INFORMATION:
3733 : // AUTHOR Anonymous
3734 : // DATE WRITTEN July 1977
3735 : // MODIFIED Oct 1999 (FW) to handle movable shades
3736 : // May 2000 (FW) to handle window frame and dividers
3737 : // May 2001 (FW) to handle window blinds
3738 : // Jan 2002 (FW) mods for between-glass shade/blind
3739 : // May 2006 (RR) to handle exterior window screens
3740 : // RE-ENGINEERED Mar98 (RKS)
3741 :
3742 : // PURPOSE OF THIS SUBROUTINE:
3743 : // This subroutine initializes the arrays associated with solar heat
3744 : // gains for both individual surfaces and for zones.
3745 :
3746 : // METHODOLOGY EMPLOYED:
3747 : // If the sun is down, all of the pertinent arrays are zeroed. If the
3748 : // sun is up, various calculations are made.
3749 :
3750 : // REFERENCES:
3751 : // (I)BLAST legacy routine QSUN
3752 :
3753 : using Dayltg::DistributeTDDAbsorbedSolar;
3754 : using namespace DataWindowEquivalentLayer;
3755 :
3756 2800078 : auto &s_mat = state.dataMaterial;
3757 : // COMPUTE TOTAL SHORT-WAVE RADIATION ORIGINATING IN ZONE.
3758 : // Note: If sun is not up, QS is only internal gains
3759 22618990 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3760 19818912 : Real64 sumSpaceQLTSW = 0.0;
3761 39690468 : for (int spaceNum : state.dataViewFactor->EnclSolInfo(enclosureNum).spaceNums) {
3762 19871556 : sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
3763 19818912 : }
3764 19818912 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) = state.dataHeatBal->EnclSolQD(enclosureNum) + sumSpaceQLTSW;
3765 19818912 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) = sumSpaceQLTSW;
3766 : }
3767 :
3768 2800078 : if (state.dataHeatBalSurf->InterZoneWindow) { // DO INTERZONE DISTRIBUTION.
3769 :
3770 60735 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3771 :
3772 48588 : if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclosureNum)) {
3773 :
3774 120960 : for (int OtherenclosureNum = 1; OtherenclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++OtherenclosureNum) {
3775 :
3776 96768 : if ((OtherenclosureNum != enclosureNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(OtherenclosureNum))) {
3777 24192 : Real64 sumSpaceQLTSW = 0.0;
3778 48384 : for (int spaceNum : state.dataViewFactor->EnclSolInfo(OtherenclosureNum).spaceNums) {
3779 24192 : sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
3780 24192 : }
3781 24192 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) +=
3782 24192 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
3783 24192 : (state.dataHeatBal->EnclSolQD(OtherenclosureNum) + sumSpaceQLTSW);
3784 24192 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) +=
3785 24192 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) * sumSpaceQLTSW;
3786 24192 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) +=
3787 24192 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
3788 24192 : state.dataHeatBal->EnclSolQD(OtherenclosureNum);
3789 24192 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclosureNum) =
3790 24192 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec;
3791 : }
3792 : }
3793 : }
3794 : }
3795 : }
3796 :
3797 : // Beam and diffuse solar on inside surfaces from interior windows (for reporting)
3798 :
3799 2800078 : if (state.dataEnvrn->SunIsUp) {
3800 86680127 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
3801 85280782 : auto const &surface = state.dataSurface->Surface(SurfNum);
3802 : //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
3803 85280782 : if (surface.Class == DataSurfaces::SurfaceClass::Shading) {
3804 1129 : continue;
3805 : }
3806 85279653 : int const enclosureNum = surface.SolarEnclIndex;
3807 85279653 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) =
3808 85279653 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) / state.dataViewFactor->EnclSolInfo(enclosureNum).TotalSurfArea;
3809 85279653 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) =
3810 85279653 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) * (surface.Area + state.dataSurface->SurfWinDividerArea(SurfNum));
3811 85279653 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) =
3812 85279653 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3813 1399345 : }
3814 : }
3815 :
3816 : // COMPUTE CONVECTIVE GAINS AND ZONE FLUX DENSITY.
3817 22618990 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3818 19818912 : auto const &thisSolEnclosure = state.dataViewFactor->EnclSolInfo(enclosureNum);
3819 19818912 : if (state.dataHeatBalSurf->InterZoneWindow) {
3820 48588 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) *=
3821 48588 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
3822 : // CR 8695, VMULT not based on visible
3823 48588 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *=
3824 48588 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
3825 : } else {
3826 19770324 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) *= thisSolEnclosure.solVMULT;
3827 19770324 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *= thisSolEnclosure.solVMULT;
3828 : }
3829 : }
3830 :
3831 : // COMPUTE RADIANT GAINS ON SURFACES
3832 22623034 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3833 39694512 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3834 19871556 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
3835 19871556 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
3836 19871556 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
3837 167531295 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
3838 147659739 : auto const &surface = state.dataSurface->Surface(SurfNum);
3839 147659739 : int const solEnclosureNum = surface.SolarEnclIndex;
3840 147659739 : int const ConstrNum = surface.Construction;
3841 147659739 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3842 :
3843 147659739 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum);
3844 : // TODO - AbsIntSurfVis = InsideAbsorpSolar instead of InsideAbsorpVis?
3845 147659739 : Real64 AbsIntSurfVis = thisConstruct.InsideAbsorpSolar; // Inside opaque surface visible absorptance to fix CR 8695 change to
3846 :
3847 147659739 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsIntSurf;
3848 147659739 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) += state.dataHeatBal->EnclSolQSWRadLights(solEnclosureNum) * AbsIntSurfVis;
3849 :
3850 : // Calculate absorbed solar on outside if movable exterior insulation in place
3851 147659739 : if (state.dataSurface->AnyMovableInsulation) {
3852 60732 : auto &movInsul = state.dataSurface->extMovInsuls(SurfNum);
3853 60732 : if (movInsul.present) {
3854 4047 : Real64 AbsExt = state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum);
3855 4047 : auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
3856 4047 : state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) =
3857 4047 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) * AbsExt / thisMaterial->AbsorpSolar;
3858 : // For transparent insulation, allow some sunlight to get through the movable insulation.
3859 : // The equation below is derived by taking what is transmitted through the layer and applying
3860 : // the fraction that is absorbed plus the back reflected portion (first order reflection only)
3861 : // to the plane between the transparent insulation and the exterior surface face.
3862 4047 : auto const *matMovInsul = s_mat->materials(movInsul.matNum);
3863 4047 : auto const *matFenMovInsul = dynamic_cast<Material::MaterialFen const *>(matMovInsul);
3864 4047 : Real64 transMovInsul = (matFenMovInsul != nullptr) ? matFenMovInsul->Trans : 0.0;
3865 :
3866 4047 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
3867 4047 : transMovInsul * state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) *
3868 4047 : ((thisMaterial->AbsorpSolar / AbsExt) + (1 - thisMaterial->AbsorpSolar));
3869 : }
3870 : }
3871 : // RJH 08/30/07 - Add SurfWinInitialDifSolInAbs, SurfWinInitialDifSolwinAbs, and SurfWinInitialDifSolAbsByShade
3872 : // calced in CalcWinTransDifSolInitialDistribution to SurfOpaqQRadSWInAbs, SurfWinQRadSWwinAbs, and SurfWinIntSWAbsByShade here
3873 147659739 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum);
3874 : } // end of opaque
3875 :
3876 19871556 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
3877 19871556 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
3878 42239844 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { // Window
3879 22368288 : auto const &surface = state.dataSurface->Surface(SurfNum);
3880 22368288 : auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
3881 22368288 : int const radEnclosureNum = surface.RadEnclIndex;
3882 22368288 : int const solEnclosureNum = surface.SolarEnclIndex;
3883 22368288 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3884 22368288 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3885 :
3886 22368288 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) {
3887 22360179 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
3888 :
3889 22360179 : int TotGlassLayers = thisConstruct.TotGlassLayers;
3890 22360179 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
3891 :
3892 : // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
3893 22360179 : Real64 pulseMultipler = 0.01; // use to create a pulse for the load component report computations, the W/sqft pulse for the zone
3894 22360179 : if (!state.dataGlobal->doLoadComponentPulseNow) {
3895 22359779 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
3896 22359779 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3897 22359779 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
3898 : } else {
3899 : // radiant value prior to adjustment for pulse for load component report
3900 400 : Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
3901 : // for the loads component report during the special sizing run increase the radiant portion
3902 : // a small amount to create a "pulse" of heat that is used for the
3903 : // radiant value including adjustment for pulse for load component report
3904 400 : Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
3905 : // ITABSF is the Inside Thermal Absorptance
3906 : // EnclRadThermAbsMult is a multiplier for each zone/enclosure
3907 : // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
3908 400 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
3909 400 : adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
3910 400 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
3911 : }
3912 :
3913 22360179 : if (NOT_SHADED(ShadeFlag)) { // No window shading
3914 50254476 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
3915 28181098 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3916 28181098 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
3917 : }
3918 286801 : } else if (ConstrNumSh != 0 && ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
3919 : // Interior, exterior or between-glass shade, screen or blind in place
3920 188978 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
3921 433866 : for (int IGlass = 1; IGlass <= constrSh.TotGlassLayers; ++IGlass) {
3922 244888 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
3923 93965 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3924 93965 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBack(IGlass);
3925 150923 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind || ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) {
3926 129219 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3927 129219 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3928 129219 : auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxLo];
3929 129219 : auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxHi];
3930 : // Glass layer back diffuse solar absorptance when blind in place
3931 129219 : Real64 BlAbsDiffBk = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
3932 :
3933 129219 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3934 129219 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * BlAbsDiffBk;
3935 : }
3936 : }
3937 188978 : if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
3938 44850 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3939 44850 : constrSh.ShadeAbsorpThermal *
3940 22425 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
3941 166553 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
3942 128113 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3943 128113 : Real64 EffBlEmiss = surfShade.effShadeEmi; // Blind emissivity (thermal absorptance) as part of glazing system
3944 256226 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3945 128113 : EffBlEmiss *
3946 128113 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
3947 : }
3948 :
3949 188978 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
3950 50929 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) =
3951 50929 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBackShade;
3952 138049 : } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
3953 138049 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3954 138049 : auto const &btarLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
3955 138049 : auto const &btarHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
3956 138049 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3957 138049 : Real64 AbsDiffBkBl = Interp(btarLo.Sol.Bk.Df.Abs, btarHi.Sol.Bk.Df.Abs, interpFac);
3958 :
3959 138049 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsDiffBkBl;
3960 : }
3961 : // Correct for divider shadowing
3962 188978 : if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3963 21522 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) *= surfWin.glazedFrac;
3964 : }
3965 :
3966 286801 : } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3967 71786 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh); // What was here before?
3968 215358 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
3969 :
3970 143572 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3971 143572 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
3972 143572 : Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
3973 143572 : thisConstruct.AbsDiffBack(IGlass),
3974 143572 : constructionSh.AbsDiffBack(IGlass));
3975 : }
3976 :
3977 : } // End of shading flag check
3978 :
3979 : // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
3980 22360179 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
3981 477684 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) +=
3982 477684 : (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) +
3983 477684 : (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3984 477684 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
3985 477684 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
3986 477684 : state.dataSurface->SurfWinFrameEmis(SurfNum)) *
3987 477684 : (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)); // Window has a frame
3988 : }
3989 22360179 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) { // Window has dividers
3990 329931 : Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
3991 329931 : Real64 DividerSolAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
3992 329931 : if (state.dataSurface->SurfWinDividerType(SurfNum) ==
3993 : DataSurfaces::FrameDividerType::Suspended) { // Suspended divider; account for inside glass
3994 29589 : Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass layer material number
3995 29589 : auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
3996 29589 : assert(thisMaterial != nullptr);
3997 29589 : Real64 TransGl = thisMaterial->Trans; // Glass layer solar transmittance, reflectance, absorptance
3998 29589 : Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
3999 29589 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
4000 29589 : Real64 DividerSolRefl = 1.0 - DividerSolAbs; // Window divider solar reflectance
4001 29589 : DividerSolAbs = AbsGl + TransGl * (DividerSolAbs + DividerSolRefl * AbsGl) / (1.0 - DividerSolRefl * ReflGl);
4002 29589 : DividerThermAbs = thisMaterial->AbsorpThermalBack;
4003 : }
4004 : // Correct for interior shade transmittance
4005 329931 : if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
4006 742 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4007 742 : int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers); // Shade layer material number
4008 742 : auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
4009 742 : assert(matSh != nullptr);
4010 742 : DividerSolAbs *= matSh->Trans;
4011 742 : DividerThermAbs *= matSh->TransThermal;
4012 :
4013 329189 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
4014 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4015 0 : Real64 SolBackDiffDiffTrans = surfShade.blind.TAR.Sol.Bk.Df.Tra;
4016 0 : Real64 IRBackTrans = surfShade.blind.TAR.IR.Bk.Tra;
4017 :
4018 0 : DividerSolAbs *= SolBackDiffDiffTrans;
4019 0 : DividerThermAbs *= IRBackTrans;
4020 : }
4021 : // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
4022 329931 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) +=
4023 329931 : (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * DividerSolAbs +
4024 329931 : (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
4025 329931 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
4026 329931 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
4027 329931 : DividerThermAbs) *
4028 329931 : (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
4029 : }
4030 : } else {
4031 : // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
4032 8109 : Real64 pulseMultipler = 0.01; // the W/sqft pulse for the zone
4033 8109 : if (!state.dataGlobal->doLoadComponentPulseNow) {
4034 8109 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
4035 8109 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
4036 8109 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
4037 : } else {
4038 : // radiant value prior to adjustment for pulse for load component report
4039 0 : Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
4040 : // for the loads component report during the special sizing run increase the radiant portion
4041 : // a small amount to create a "pulse" of heat that is used for the
4042 : // radiant value including adjustment for pulse for load component report
4043 0 : Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
4044 : // ITABSF is the Inside Thermal Absorptance
4045 : // EnclRadThermAbsMult is a multiplier for each zone/radiant enclosure
4046 : // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
4047 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
4048 0 : adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
4049 0 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
4050 : }
4051 : // Radiations absorbed by the window layers coming from zone side
4052 8109 : int EQLNum = thisConstruct.EQLConsPtr;
4053 37842 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4054 29733 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) +=
4055 29733 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffBackEQL(Lay);
4056 : }
4057 : // Window frame has not been included for equivalent layer model yet
4058 :
4059 : } // end if for IF ( SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: EQL) THEN
4060 :
4061 22368288 : if (surface.ExtBoundCond > 0) { // Interzone surface
4062 : // Short-wave radiation absorbed in panes of corresponding window in adjacent zone
4063 27192 : int SurfNumAdjZone = surface.ExtBoundCond; // Surface number in adjacent zone for interzone surfaces
4064 27192 : if (state.dataSurface->SurfWinWindowModelType(SurfNumAdjZone) != DataSurfaces::WindowModel::EQL) {
4065 27192 : int TotGlassLayers = thisConstruct.TotGlassLayers;
4066 54384 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4067 27192 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, IGlass) +=
4068 27192 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
4069 27192 : state.dataConstruction->Construct(state.dataSurface->Surface(SurfNumAdjZone).Construction).AbsDiff(IGlass);
4070 : // Note that AbsDiff rather than AbsDiffBack is used in the above since the
4071 : // radiation from the current zone is incident on the outside of the adjacent
4072 : // zone's window.
4073 : }
4074 : } else { // IF (SurfaceWindow(SurfNumAdjZone)%WindowModelType == WindowModel:: EQL) THEN
4075 0 : int const AdjConstrNum = state.dataSurface->Surface(SurfNumAdjZone).Construction;
4076 0 : int const EQLNum = state.dataConstruction->Construct(AdjConstrNum).EQLConsPtr;
4077 0 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4078 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, Lay) +=
4079 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffFrontEQL(Lay);
4080 : // Note that AbsDiffFrontEQL rather than AbsDiffBackEQL is used in the above
4081 : // since the radiation from the current zone is incident on the outside of the
4082 : // adjacent zone's window.
4083 : }
4084 : }
4085 : }
4086 :
4087 22368288 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) {
4088 22320639 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
4089 22320639 : int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
4090 22320639 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4091 22320639 : if (DataSurfaces::NOT_SHADED(ShadeFlag)) { // No window shading
4092 50207892 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4093 28148017 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4094 : }
4095 260764 : } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
4096 215358 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4097 143572 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4098 : }
4099 : } else {
4100 188978 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4101 : // Interior, exterior or between-glass shade, screen or blind in place
4102 433866 : for (int IGlass = 1; IGlass <= constructionSh.TotGlassLayers; ++IGlass) {
4103 244888 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4104 : }
4105 188978 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag) || DataSurfaces::ANY_BLIND(ShadeFlag)) {
4106 188978 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum);
4107 : }
4108 : } // End of shading flag check
4109 47649 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
4110 39540 : int TotGlassLayers = thisConstruct.TotGlassLayers;
4111 119289 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4112 79749 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4113 : }
4114 8109 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
4115 :
4116 : // ConstrNum = Surface(SurfNum)%Construction
4117 8109 : int EQLNum = thisConstruct.EQLConsPtr;
4118 :
4119 37842 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4120 29733 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay);
4121 : }
4122 : }
4123 :
4124 : } // End of window
4125 19822956 : }
4126 : }
4127 2800078 : Dayltg::DistributeTDDAbsorbedSolar(state);
4128 2800078 : }
4129 :
4130 2800078 : void ComputeIntThermalAbsorpFactors(EnergyPlusData &state)
4131 : {
4132 :
4133 : // SUBROUTINE INFORMATION:
4134 : // AUTHOR Legacy Code (George Walton)
4135 : // DATE WRITTEN Legacy: Dec 1976
4136 : // MODIFIED Nov. 99, FCW: to take into account movable interior shades and switchable glazing
4137 : // June 01, FCW: to take into account interior blinds.
4138 :
4139 : // PURPOSE OF THIS SUBROUTINE:
4140 : // This routine computes the fractions of long-wave radiation from lights, equipment and people
4141 : // that is absorbed by each zone surface.
4142 :
4143 : // METHODOLOGY EMPLOYED:
4144 : // The fraction is assumed to be proportional to the product of the surface area times its thermal absorptivity.
4145 :
4146 : // REFERENCES:
4147 : // BLAST Routine: CITAF - Compute Interior Thermal Absorption Factors
4148 2800078 : auto &s_mat = state.dataMaterial;
4149 :
4150 22618990 : for (auto const &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
4151 19818912 : if (!thisEnclosure.radReCalc) {
4152 19641879 : continue;
4153 : }
4154 354220 : for (int spaceNum : thisEnclosure.spaceNums) {
4155 177187 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4156 177187 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
4157 177187 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
4158 596634 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
4159 419447 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4160 419447 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4161 10800 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4162 10800 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
4163 : } else {
4164 408647 : int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
4165 408647 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal;
4166 : }
4167 : }
4168 177033 : }
4169 2800078 : }
4170 2800078 : if (state.dataSurface->AnyMovableSlat) {
4171 12150 : for (int SurfNum : state.dataHeatBalSurf->SurfMovSlatsIndexList) {
4172 : // For window with an interior shade or blind, emissivity is a combination of glass and shade/blind emissivity
4173 6075 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4174 : // Not sure we need to do this anymore
4175 6075 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4176 2578 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4177 2578 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
4178 : }
4179 6075 : }
4180 : }
4181 :
4182 22618990 : for (auto &thisRadEnclosure : state.dataViewFactor->EnclRadInfo) {
4183 19818912 : if (!thisRadEnclosure.radReCalc) {
4184 19641879 : continue;
4185 : }
4186 177033 : Real64 SUM1 = 0.0;
4187 1903624 : for (int const SurfNum : thisRadEnclosure.SurfacePtr) {
4188 1726591 : auto &surf = state.dataSurface->Surface(SurfNum);
4189 1726591 : int const ConstrNum = surf.Construction;
4190 1726591 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
4191 1726591 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4192 1726591 : if (ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
4193 1726591 : SUM1 += surf.Area * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
4194 : } else { // Switchable glazing
4195 0 : SUM1 += surf.Area * Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
4196 0 : thisConstruct.InsideAbsorpThermal,
4197 0 : state.dataConstruction->Construct(surf.activeShadedConstruction).InsideAbsorpThermal);
4198 : }
4199 :
4200 : // Window frame and divider effects
4201 1726591 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
4202 122286 : SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) *
4203 122286 : state.dataSurface->SurfWinFrameEmis(SurfNum);
4204 : }
4205 1726591 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
4206 121637 : Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
4207 : // Suspended (between-glass) divider; relevant emissivity is inner glass emissivity
4208 121637 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
4209 95 : DividerThermAbs = thisConstruct.InsideAbsorpThermal;
4210 : }
4211 121637 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4212 : // Interior shade or blind in place
4213 14 : int const ConstrNumSh = surf.activeShadedConstruction;
4214 14 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4215 :
4216 14 : if (state.dataSurface->SurfWinHasShadeOrBlindLayer(SurfNum)) {
4217 14 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4218 : // Shade layer material number
4219 14 : int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers);
4220 14 : auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
4221 14 : assert(matSh != nullptr);
4222 : // Shade or blind IR transmittance
4223 14 : Real64 TauShIR = matSh->TransThermal;
4224 : // Effective emissivity of shade or blind
4225 14 : Real64 EffShDevEmiss = surfShade.effShadeEmi;
4226 :
4227 14 : if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
4228 0 : TauShIR = surfShade.blind.TAR.IR.Bk.Tra;
4229 : }
4230 14 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (EffShDevEmiss + DividerThermAbs * TauShIR);
4231 : } else {
4232 : // this is for EMS activated shade/blind but the window construction has no shade/blind layer
4233 0 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
4234 : DividerThermAbs;
4235 : }
4236 : } else {
4237 121623 : SUM1 +=
4238 121623 : state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * DividerThermAbs;
4239 : }
4240 : }
4241 :
4242 : } // End of loop over surfaces in zone/enclosure
4243 177033 : thisRadEnclosure.radThermAbsMult = 1.0 / SUM1;
4244 :
4245 2800078 : } // End of loop over enclosures
4246 2800078 : }
4247 :
4248 2800078 : void ComputeIntSWAbsorpFactors(EnergyPlusData &state)
4249 : {
4250 :
4251 : // SUBROUTINE INFORMATION:
4252 : // AUTHOR Legacy (George Walton)
4253 : // DATE WRITTEN Legacy (December 1980)
4254 : // MODIFIED Nov. 99, FW; now called every time step to account for movable
4255 : // window shades and insulation
4256 : // Mar. 00, FW; change name from ComputeVisLightingAbsorpFactors
4257 : // to ComputeIntSWAbsorpFactors
4258 : // May 00, FW; add window frame and divider effects
4259 : // June 01, FW: account for window blinds
4260 : // Nov 01, FW: account for absorptance of exterior shades and interior or exterior blinds
4261 : // Jan 03, FW: add between-glass shade/blind
4262 : // May 06, RR: account for exterior window screens
4263 :
4264 : // PURPOSE OF THIS SUBROUTINE:
4265 : // Computes VMULT, the inverse of the sum of area*(short-wave absorptance+transmittance) for
4266 : // the surfaces in a zone. VMULT is used to calculate the zone interior diffuse short-wave radiation
4267 : // absorbed by the inside of opaque zone surfaces or by the glass and shade/blind layers of zone windows.
4268 :
4269 : // Sets VCONV to zero (VCONV was formerly used to calculate convective gain due to short-wave
4270 : // radiation absorbed by interior window shades).
4271 :
4272 : // REFERENCES:
4273 : // BLAST Routine - CIVAF - Compute Surface Absorption Factors For Short Wave Radiation
4274 : // From Zone Lights And Diffuse Solar.
4275 :
4276 : // Avoid a division by zero of the user has entered a bunch of surfaces with zero absorptivity on the inside
4277 2800078 : Real64 constexpr SmallestAreaAbsProductAllowed(0.01);
4278 :
4279 2800078 : auto &s_mat = state.dataMaterial;
4280 :
4281 22618990 : for (auto &thisSolEnclosure : state.dataViewFactor->EnclSolInfo) {
4282 19818912 : if (!thisSolEnclosure.radReCalc) {
4283 19641879 : continue;
4284 : }
4285 177033 : Real64 SUM1 = 0.0; // Intermediate calculation value for solar absorbed and transmitted
4286 :
4287 1904148 : for (int const SurfNum : thisSolEnclosure.SurfacePtr) {
4288 1727115 : auto &thisSurf = state.dataSurface->Surface(SurfNum);
4289 1727115 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
4290 1727115 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
4291 1727115 : if (thisConstruct.TransDiff <= 0.0) {
4292 : // Opaque surface
4293 1309773 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum); // Inside surface short-wave absorptance
4294 1309773 : SUM1 += thisSurf.Area * AbsIntSurf;
4295 :
4296 : } else {
4297 : // Window
4298 417342 : if (!state.dataConstruction->Construct(thisSurf.Construction).WindowTypeEQL) {
4299 411348 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4300 :
4301 411348 : Real64 AbsDiffTotWin = 0.0; // Sum of window layer short-wave absorptances
4302 411348 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
4303 411348 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
4304 :
4305 : // Sum of absorptances of glass layers
4306 984630 : for (int Lay = 1; Lay <= thisConstruct.TotGlassLayers; ++Lay) {
4307 573282 : Real64 AbsDiffLayWin = thisConstruct.AbsDiffBack(Lay); // Window layer short-wave absorptance
4308 :
4309 : // Window with shade, screen or blind
4310 573282 : if (ConstrNumSh != 0) {
4311 269488 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4312 269488 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
4313 13665 : AbsDiffLayWin = constrSh.AbsDiffBack(Lay);
4314 255823 : } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
4315 8643 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4316 8643 : auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxLo];
4317 8643 : auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxHi];
4318 8643 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
4319 8643 : AbsDiffLayWin = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
4320 : }
4321 : }
4322 :
4323 : // Switchable glazing
4324 573282 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
4325 0 : assert(ConstrNumSh > 0); // Should this be included in the if above
4326 0 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4327 0 : AbsDiffLayWin = Window::InterpSw(SwitchFac, AbsDiffLayWin, constrSh.AbsDiffBack(Lay));
4328 : }
4329 573282 : AbsDiffTotWin += AbsDiffLayWin;
4330 : }
4331 :
4332 411348 : Real64 TransDiffWin = thisConstruct.TransDiff; // Window diffuse short-wave transmittance
4333 411348 : Real64 DiffAbsShade = 0.0; // Diffuse short-wave shade or blind absorptance
4334 :
4335 : // Window with shade, screen or blind
4336 :
4337 411348 : if (ConstrNumSh != 0) {
4338 143733 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4339 143733 : if (ANY_SHADE_SCREEN(ShadeFlag)) {
4340 7679 : TransDiffWin = constrSh.TransDiff;
4341 7679 : DiffAbsShade = constrSh.AbsDiffBackShade;
4342 136054 : } else if (ANY_BLIND(ShadeFlag)) {
4343 8605 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4344 8605 : auto const &btarSlatLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
4345 8605 : auto const &btarSlatHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
4346 8605 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
4347 8605 : TransDiffWin = Interp(btarSlatLo.Sol.Ft.Df.Tra, btarSlatHi.Sol.Ft.Df.Tra, interpFac);
4348 8605 : DiffAbsShade = Interp(btarSlatLo.Sol.Bk.Df.Abs, btarSlatHi.Sol.Bk.Df.Abs, interpFac);
4349 : }
4350 : }
4351 :
4352 : // Switchable glazing
4353 :
4354 411348 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
4355 0 : assert(ConstrNumSh > 0);
4356 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4357 0 : TransDiffWin = Window::InterpSw(SwitchFac, TransDiffWin, constructionSh.TransDiff);
4358 : }
4359 :
4360 411348 : SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin + DiffAbsShade);
4361 :
4362 : // Window frame and divider effects (shade area is glazed area plus divider area)
4363 :
4364 411348 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
4365 122286 : SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) *
4366 122286 : (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum));
4367 : }
4368 411348 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
4369 121637 : Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
4370 121637 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
4371 : // Suspended (between-glass) divider: account for glass on inside of divider
4372 95 : Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass material number
4373 95 : auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
4374 95 : assert(thisMaterial != nullptr);
4375 95 : Real64 TransGl = thisMaterial->Trans; // Glass layer short-wave transmittance, reflectance, absorptance
4376 95 : Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
4377 95 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
4378 95 : Real64 DividerRefl = 1.0 - DividerAbs; // Window divider short-wave reflectance
4379 95 : DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
4380 : }
4381 121637 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4382 14 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (DividerAbs + DiffAbsShade);
4383 : } else {
4384 121623 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
4385 : DividerAbs;
4386 : }
4387 : }
4388 : } else { // equivalent layer window
4389 : // In equivalent layer window solid layers (Glazing and shades) are treated equally
4390 : // frames and dividers are not supported
4391 5994 : Real64 AbsDiffTotWin = 0.0;
4392 5994 : Real64 AbsDiffLayWin = 0.0;
4393 5994 : Real64 TransDiffWin = thisConstruct.TransDiff;
4394 28000 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL; ++Lay) {
4395 22006 : AbsDiffLayWin = thisConstruct.AbsDiffBackEQL(Lay);
4396 22006 : AbsDiffTotWin += AbsDiffLayWin;
4397 : }
4398 5994 : SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin);
4399 : }
4400 : } // End of check if opaque surface or window
4401 : } // End of loop over surfaces in zone
4402 :
4403 177033 : if (SUM1 > SmallestAreaAbsProductAllowed) { // Everything is okay, proceed with the regular calculation
4404 177028 : thisSolEnclosure.solVMULT = 1.0 / SUM1;
4405 :
4406 : } else { // the sum of area*solar absorptance for all surfaces in the zone is zero--either the user screwed up
4407 : // or they really want to disallow any solar from being absorbed on the inside surfaces. Fire off a
4408 : // nasty warning message and then assume that no solar is ever absorbed (basically everything goes
4409 : // back out whatever window is there. Note that this also assumes that the shade has no effect.
4410 : // That's probably not correct, but how correct is it to assume that no solar is absorbed anywhere
4411 : // in the zone?
4412 5 : if (thisSolEnclosure.solAbsFirstCalc) {
4413 2 : ShowWarningError(
4414 : state,
4415 2 : format("ComputeIntSWAbsorbFactors: Sum of area times inside solar absorption for all surfaces is zero in Enclosure: {}",
4416 1 : thisSolEnclosure.Name));
4417 1 : thisSolEnclosure.solAbsFirstCalc = false;
4418 : }
4419 5 : thisSolEnclosure.solVMULT = 0.0;
4420 : }
4421 2800078 : } // End of enclosure loop
4422 2800078 : }
4423 :
4424 12147 : void ComputeDifSolExcZonesWIZWindows(EnergyPlusData &state)
4425 : {
4426 :
4427 : // SUBROUTINE INFORMATION:
4428 : // MODIFIED Jun 2007 - Lawrie - Speed enhancements.
4429 : // RE-ENGINEERED Winkelmann, Lawrie
4430 :
4431 : // PURPOSE OF THIS SUBROUTINE:
4432 : // This subroutine computes the diffuse solar exchange factors between enclosures with
4433 : // interzone windows.
4434 :
4435 12147 : int const numEnclosures = state.dataViewFactor->NumOfSolarEnclosures;
4436 12147 : if (!allocated(state.dataHeatBalSurf->ZoneFractDifShortZtoZ)) {
4437 6 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ.allocate(numEnclosures, numEnclosures);
4438 6 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ.allocate(numEnclosures);
4439 6 : state.dataHeatBalSurfMgr->DiffuseArray.allocate(numEnclosures, numEnclosures);
4440 : }
4441 :
4442 12147 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ = false;
4443 12147 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ.to_identity();
4444 12147 : state.dataHeatBalSurfMgr->DiffuseArray.to_identity();
4445 :
4446 : // IF (.not. ANY(Zone%HasInterZoneWindow)) RETURN ! this caused massive diffs
4447 12147 : if (state.dataGlobal->KickOffSimulation || state.dataGlobal->KickOffSizing) {
4448 51 : return;
4449 : }
4450 : // Compute fraction transmitted in one pass.
4451 :
4452 101664 : for (int const SurfNum : state.dataSurface->AllHTWindowSurfaceList) {
4453 89568 : auto &surface = state.dataSurface->Surface(SurfNum);
4454 89568 : if (surface.ExtBoundCond <= 0) {
4455 62496 : continue;
4456 : }
4457 27072 : if (surface.ExtBoundCond == SurfNum) {
4458 0 : continue;
4459 : }
4460 27072 : if (state.dataConstruction->Construct(surface.Construction).TransDiff <= 0.0) {
4461 0 : continue;
4462 : }
4463 :
4464 27072 : int surfEnclNum = surface.SolarEnclIndex;
4465 27072 : if (!state.dataViewFactor->EnclSolInfo(surfEnclNum).HasInterZoneWindow) {
4466 0 : continue;
4467 : }
4468 27072 : int MZ = state.dataSurface->Surface(surface.ExtBoundCond).SolarEnclIndex;
4469 54144 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(surfEnclNum, MZ) += state.dataConstruction->Construct(surface.Construction).TransDiff *
4470 27072 : state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT * surface.Area;
4471 27072 : if (state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT != 0.0) {
4472 27072 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ(surfEnclNum) = true;
4473 : }
4474 12096 : }
4475 : // Compute fractions for multiple passes.
4476 :
4477 12096 : Array2D<Real64>::size_type l(0u), m(0u), d(0u);
4478 60480 : for (int NZ = 1; NZ <= numEnclosures; ++NZ, d += numEnclosures + 1) {
4479 48384 : m = NZ - 1;
4480 48384 : Real64 D_d(0.0); // Local accumulator
4481 241920 : for (int MZ = 1; MZ <= numEnclosures; ++MZ, ++l, m += numEnclosures) {
4482 193536 : if (MZ == NZ) {
4483 48384 : continue;
4484 : }
4485 145152 : state.dataHeatBalSurfMgr->DiffuseArray[l] =
4486 145152 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] /
4487 290304 : (1.0 - state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] *
4488 145152 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m]); // [ l ] == ( MZ, NZ ), [ m ] == ( NZ, MZ )
4489 145152 : D_d += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m] * state.dataHeatBalSurfMgr->DiffuseArray[l];
4490 : }
4491 48384 : state.dataHeatBalSurfMgr->DiffuseArray[d] += D_d; // [ d ] == ( NZ, NZ )
4492 : }
4493 :
4494 12096 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ = state.dataHeatBalSurfMgr->DiffuseArray;
4495 : // added for CR 7999 & 7869
4496 12096 : assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize1() == numEnclosures);
4497 12096 : assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize2() == numEnclosures);
4498 60480 : for (int NZ = 1; NZ <= numEnclosures; ++NZ) {
4499 197568 : for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
4500 173376 : if (MZ == NZ) {
4501 36288 : continue;
4502 : }
4503 137088 : if (state.dataHeatBalSurf->ZoneFractDifShortZtoZ(MZ, NZ) > 0.0) {
4504 24192 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ(NZ) = true;
4505 24192 : break;
4506 : }
4507 : }
4508 : }
4509 :
4510 : // Compute fractions for multiple zones.
4511 :
4512 60480 : for (int IZ = 1; IZ <= numEnclosures; ++IZ) {
4513 48384 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(IZ)) {
4514 24192 : continue;
4515 : }
4516 :
4517 120960 : for (int JZ = 1; JZ <= numEnclosures; ++JZ) {
4518 96768 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(JZ)) {
4519 48384 : continue;
4520 : }
4521 48384 : if (IZ == JZ) {
4522 24192 : continue;
4523 : }
4524 24192 : if (state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ) == 0.0) {
4525 0 : continue;
4526 : }
4527 :
4528 120960 : for (int KZ = 1; KZ <= numEnclosures; ++KZ) {
4529 96768 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(KZ)) {
4530 48384 : continue;
4531 : }
4532 48384 : if (IZ == KZ) {
4533 24192 : continue;
4534 : }
4535 24192 : if (JZ == KZ) {
4536 24192 : continue;
4537 : }
4538 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) == 0.0) {
4539 0 : continue;
4540 : }
4541 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, KZ) +=
4542 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4543 :
4544 0 : for (int LZ = 1; LZ <= numEnclosures; ++LZ) {
4545 0 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(LZ)) {
4546 0 : continue;
4547 : }
4548 0 : if (IZ == LZ) {
4549 0 : continue;
4550 : }
4551 0 : if (JZ == LZ) {
4552 0 : continue;
4553 : }
4554 0 : if (KZ == LZ) {
4555 0 : continue;
4556 : }
4557 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) == 0.0) {
4558 0 : continue;
4559 : }
4560 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, LZ) += state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
4561 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) *
4562 0 : state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4563 :
4564 0 : for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
4565 0 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(MZ)) {
4566 0 : continue;
4567 : }
4568 0 : if (IZ == MZ) {
4569 0 : continue;
4570 : }
4571 0 : if (JZ == MZ) {
4572 0 : continue;
4573 : }
4574 0 : if (KZ == MZ) {
4575 0 : continue;
4576 : }
4577 0 : if (LZ == MZ) {
4578 0 : continue;
4579 : }
4580 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) == 0.0) {
4581 0 : continue;
4582 : }
4583 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, MZ) +=
4584 0 : state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) * state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
4585 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4586 : } // MZ Loop
4587 :
4588 : } // LZ Loop
4589 :
4590 : } // KZ Loop
4591 :
4592 : } // JZ Loop
4593 :
4594 : } // IZ Loop
4595 : } // ComputeDifSolExcZoneWIZWindows()
4596 :
4597 419548 : void InitEMSControlledSurfaceProperties(EnergyPlusData &state)
4598 : {
4599 :
4600 : // SUBROUTINE INFORMATION:
4601 : // AUTHOR B. Griffith
4602 : // DATE WRITTEN April 2011
4603 :
4604 : // PURPOSE OF THIS SUBROUTINE:
4605 : // initialize material and construction surface properties if being overridden by EMS
4606 :
4607 : // METHODOLOGY EMPLOYED:
4608 : // update solar, thermal and visible absorptance values when actuated by EMS
4609 :
4610 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4611 : int TotLayers; // count of material layers in a construction
4612 : int InsideMaterNum; // integer pointer for inside face's material layer
4613 : int OutsideMaterNum; // integer pointer for outside face's material layer
4614 :
4615 419548 : auto &s_mat = state.dataMaterial;
4616 :
4617 419548 : state.dataGlobal->AnySurfPropOverridesInModel = false;
4618 : // first determine if anything needs to be done, once yes, then always init
4619 9337604 : for (auto const *mat : s_mat->materials) {
4620 8918056 : if (mat->group != Material::Group::Regular) {
4621 1221929 : continue;
4622 : }
4623 :
4624 7696127 : if ((mat->AbsorpSolarEMSOverrideOn) || (mat->AbsorpThermalEMSOverrideOn) || (mat->AbsorpVisibleEMSOverrideOn)) {
4625 0 : state.dataGlobal->AnySurfPropOverridesInModel = true;
4626 0 : break;
4627 : }
4628 : }
4629 :
4630 419548 : if (!state.dataGlobal->AnySurfPropOverridesInModel) {
4631 419548 : return; // quick return if nothing has ever needed to be done
4632 : }
4633 :
4634 : // first, loop over materials
4635 : // why is this a second loop?
4636 0 : for (auto *mat : s_mat->materials) {
4637 0 : if (mat->group != Material::Group::Regular) {
4638 0 : continue;
4639 : }
4640 :
4641 0 : mat->AbsorpSolar = mat->AbsorpSolarEMSOverrideOn ? max(min(mat->AbsorpSolarEMSOverride, 0.9999), 0.0001) : mat->AbsorpSolarInput;
4642 0 : mat->AbsorpThermal = mat->AbsorpThermalEMSOverrideOn ? max(min(mat->AbsorpThermalEMSOverride, 0.9999), 0.0001) : mat->AbsorpThermalInput;
4643 0 : mat->AbsorpVisible = mat->AbsorpVisibleEMSOverrideOn ? max(min(mat->AbsorpVisibleEMSOverride, 0.9999), 0.0001) : mat->AbsorpVisibleInput;
4644 : } // loop over materials
4645 :
4646 : // second, loop over constructions
4647 0 : for (auto &thisConstruct : state.dataConstruction->Construct) {
4648 0 : if (thisConstruct.TypeIsWindow) {
4649 0 : continue; // only override opaque constructions
4650 : }
4651 0 : TotLayers = thisConstruct.TotLayers;
4652 0 : if (TotLayers == 0) {
4653 0 : continue; // error condition
4654 : }
4655 0 : InsideMaterNum = thisConstruct.LayerPoint(TotLayers);
4656 0 : if (InsideMaterNum != 0) {
4657 0 : auto const *mat = s_mat->materials(InsideMaterNum);
4658 0 : thisConstruct.InsideAbsorpVis = mat->AbsorpVisible;
4659 0 : thisConstruct.InsideAbsorpSolar = mat->AbsorpSolar;
4660 0 : thisConstruct.InsideAbsorpThermal = mat->AbsorpThermal;
4661 : }
4662 :
4663 0 : OutsideMaterNum = thisConstruct.LayerPoint(1);
4664 0 : if (OutsideMaterNum != 0) {
4665 0 : auto const *mat = s_mat->materials(OutsideMaterNum);
4666 0 : thisConstruct.OutsideAbsorpVis = mat->AbsorpVisible;
4667 0 : thisConstruct.OutsideAbsorpSolar = mat->AbsorpSolar;
4668 0 : thisConstruct.OutsideAbsorpThermal = mat->AbsorpThermal;
4669 : }
4670 : } // for (ConstrNum)
4671 : } // InitEMSControlledSurfaceProperties()
4672 :
4673 419548 : void InitEMSControlledConstructions(EnergyPlusData &state)
4674 : {
4675 :
4676 : // SUBROUTINE INFORMATION:
4677 : // AUTHOR B. Griffith
4678 : // DATE WRITTEN Jan 2012
4679 :
4680 : // PURPOSE OF THIS SUBROUTINE:
4681 : // change construction on surface if overridden by EMS
4682 :
4683 419548 : state.dataGlobal->AnyConstrOverridesInModel = false;
4684 45096650 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4685 44683161 : if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum)) {
4686 6059 : state.dataGlobal->AnyConstrOverridesInModel = true;
4687 6059 : break;
4688 : }
4689 : }
4690 419548 : if (!state.dataGlobal->AnyConstrOverridesInModel) {
4691 413489 : return;
4692 : }
4693 :
4694 424130 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4695 418071 : auto &surface = state.dataSurface->Surface(SurfNum);
4696 :
4697 418071 : if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum) && (state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum) > 0)) {
4698 :
4699 6059 : if (state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
4700 6059 : .TypeIsWindow) { // okay, always allow windows
4701 6059 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
4702 6059 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
4703 : }
4704 :
4705 12118 : if ((state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) &&
4706 6059 : (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum))) {
4707 :
4708 6059 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4709 6059 : state.dataConstruction->Construct(surface.Construction).IsUsed = true;
4710 6059 : state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4711 :
4712 : } else { // have not checked yet or is not okay, so see if we need to warn about incompatible
4713 0 : if (!state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) {
4714 : // check if constructions appear compatible
4715 :
4716 0 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
4717 0 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
4718 : // compare old construction to new construction and see if terms match
4719 : // set as okay and turn false if find a big problem
4720 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4721 : true;
4722 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4723 : true;
4724 0 : if (state.dataConstruction->Construct(surface.Construction).NumHistories !=
4725 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories) {
4726 : // throw warning, but allow
4727 0 : ShowWarningError(state,
4728 : "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
4729 : "CTF timescales are being used.");
4730 0 : ShowContinueError(state,
4731 0 : format("Construction named = {} has CTF timesteps = {}",
4732 0 : state.dataConstruction->Construct(surface.Construction).Name,
4733 0 : state.dataConstruction->Construct(surface.Construction).NumHistories));
4734 0 : ShowContinueError(
4735 : state,
4736 0 : format("While construction named = {} has CTF timesteps = {}",
4737 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4738 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories));
4739 0 : ShowContinueError(
4740 : state,
4741 0 : format("Transient heat transfer modeling may not be valid for surface name = {}, and the simulation continues",
4742 0 : surface.Name));
4743 : }
4744 0 : if (state.dataConstruction->Construct(surface.Construction).NumCTFTerms !=
4745 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms) {
4746 : // throw warning, but allow
4747 0 : ShowWarningError(state,
4748 : "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
4749 : "CTF terms are being used.");
4750 0 : ShowContinueError(state,
4751 0 : format("Construction named = {} has number of CTF terms = {}",
4752 0 : state.dataConstruction->Construct(surface.Construction).Name,
4753 0 : state.dataConstruction->Construct(surface.Construction).NumCTFTerms));
4754 0 : ShowContinueError(
4755 : state,
4756 0 : format("While construction named = {} has number of CTF terms = {}",
4757 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4758 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms));
4759 0 : ShowContinueError(state,
4760 0 : format("The actuator is allowed but the transient heat transfer modeling may not be valid for surface "
4761 : "name = {}, and the simulation continues",
4762 0 : surface.Name));
4763 : }
4764 :
4765 0 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
4766 0 : if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
4767 : // throw warning, and do not allow
4768 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4769 0 : ShowContinueError(state,
4770 0 : format("Construction named = {} has internal source/sink",
4771 0 : state.dataConstruction->Construct(surface.Construction).Name));
4772 0 : ShowContinueError(
4773 : state,
4774 0 : format("While construction named = {} is not an internal source/sink construction",
4775 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
4776 0 : ShowContinueError(
4777 : state,
4778 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4779 0 : surface.Name));
4780 :
4781 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4782 0 : SurfNum) = false;
4783 : }
4784 : }
4785 :
4786 0 : if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4787 : SurfNum)) {
4788 0 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4789 : }
4790 :
4791 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
4792 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4793 : true;
4794 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4795 : true;
4796 0 : if (state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes !=
4797 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).TotNodes) {
4798 : // throw warning, and do not allow
4799 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4800 0 : ShowContinueError(state,
4801 0 : format("Construction named = {} has number of finite difference nodes ={}",
4802 0 : state.dataConstruction->Construct(surface.Construction).Name,
4803 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes));
4804 0 : ShowContinueError(
4805 : state,
4806 0 : format("While construction named = {}has number of finite difference nodes ={}",
4807 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4808 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
4809 0 : .TotNodes));
4810 0 : ShowContinueError(
4811 : state,
4812 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4813 0 : surface.Name));
4814 :
4815 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4816 : false;
4817 : }
4818 :
4819 0 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
4820 0 : if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
4821 : // throw warning, and do not allow
4822 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4823 0 : ShowContinueError(state,
4824 0 : format("Construction named = {} has internal source/sink",
4825 0 : state.dataConstruction->Construct(surface.Construction).Name));
4826 0 : ShowContinueError(
4827 : state,
4828 0 : format("While construction named = {} is not an internal source/sink construction",
4829 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
4830 0 : ShowContinueError(
4831 : state,
4832 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4833 0 : surface.Name));
4834 :
4835 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4836 0 : SurfNum) = false;
4837 : }
4838 : }
4839 :
4840 0 : if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4841 : SurfNum)) {
4842 0 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4843 : }
4844 :
4845 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { // don't allow
4846 0 : ShowSevereError(state,
4847 : "InitEMSControlledConstructions: EMS Construction State Actuator not available with Heat transfer "
4848 : "algorithm CombinedHeatAndMoistureFiniteElement.");
4849 0 : ShowContinueError(
4850 : state,
4851 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4852 0 : surface.Name));
4853 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4854 : true;
4855 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4856 : false;
4857 :
4858 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) { // don't allow
4859 0 : ShowSevereError(state,
4860 : "InitEMSControlledConstructions: EMS Construction State Actuator not available for Surfaces with "
4861 : "Foundation Outside Boundary Condition.");
4862 0 : ShowContinueError(
4863 : state,
4864 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4865 0 : surface.Name));
4866 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4867 : true;
4868 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4869 : false;
4870 : }
4871 :
4872 : } else {
4873 : // do nothing, has been checked and is not okay with single warning already issued.
4874 : }
4875 : }
4876 : } else {
4877 412012 : surface.Construction = surface.ConstructionStoredInputValue;
4878 412012 : state.dataSurface->SurfActiveConstruction(SurfNum) = surface.ConstructionStoredInputValue;
4879 : }
4880 : } // for (SurfNum)
4881 : } // InitEMSControlledConstructions()
4882 :
4883 : // End Initialization Section of the Module
4884 : //******************************************************************************
4885 :
4886 : // Begin Algorithm Section of the Module
4887 : //******************************************************************************
4888 :
4889 : // Beginning of Record Keeping subroutines for the HB Module
4890 : // *****************************************************************************
4891 :
4892 3732214 : void UpdateIntermediateSurfaceHeatBalanceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
4893 : {
4894 3732214 : int firstZone = 1;
4895 3732214 : int lastZone = state.dataGlobal->NumOfZones;
4896 :
4897 3732214 : if (present(ZoneToResimulate)) {
4898 796099 : firstZone = ZoneToResimulate;
4899 796099 : lastZone = ZoneToResimulate;
4900 : }
4901 :
4902 24954457 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4903 42493086 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4904 21270843 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4905 21270843 : int const firstSurf = thisSpace.WindowSurfaceFirst;
4906 21270843 : int const lastSurf = thisSpace.WindowSurfaceLast;
4907 44623294 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4908 23352451 : if (state.dataSurface->Surface(surfNum).ExtSolar) { // WindowManager's definition of ZoneWinHeatGain/Loss
4909 23321209 : state.dataHeatBal->ZoneWinHeatGain(zoneNum) += state.dataSurface->SurfWinHeatGain(surfNum);
4910 : }
4911 : }
4912 : // Update zone window heat gain reports (these intermediate values are also used for Sensible Heat Gain Summary in GatherHeatGainReport)
4913 21270843 : if (state.dataHeatBal->ZoneWinHeatGain(zoneNum) >= 0.0) {
4914 12739695 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = state.dataHeatBal->ZoneWinHeatGain(zoneNum);
4915 12739695 : state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) =
4916 12739695 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
4917 : } else {
4918 8531148 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = -state.dataHeatBal->ZoneWinHeatGain(zoneNum);
4919 8531148 : state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) =
4920 8531148 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
4921 : }
4922 21222243 : }
4923 : }
4924 :
4925 3732214 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
4926 342 : UpdateNonRepresentativeSurfaceResults(state, ZoneToResimulate);
4927 : }
4928 :
4929 : // Opaque or window surfaces (Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.)
4930 24954457 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4931 42493086 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4932 21270843 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4933 21270843 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
4934 21270843 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
4935 201679567 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4936 180408724 : state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) =
4937 180408724 : -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
4938 180408724 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
4939 : }
4940 21222243 : }
4941 : }
4942 : // Opaque surfaces
4943 24954457 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4944 42493086 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4945 21270843 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4946 21270843 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
4947 21270843 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
4948 178327116 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4949 157056273 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) =
4950 157056273 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum);
4951 : }
4952 21222243 : }
4953 : }
4954 : // Inside face conduction calculation for Kiva surfaces
4955 3850474 : for (int surfNum : state.dataSurface->AllHTKivaSurfaceList) {
4956 118260 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) =
4957 118260 : -(state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
4958 118260 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
4959 118260 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum));
4960 3732214 : }
4961 3732214 : }
4962 :
4963 342 : void UpdateNonRepresentativeSurfaceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
4964 : {
4965 342 : int firstZone = 1;
4966 342 : int lastZone = state.dataGlobal->NumOfZones;
4967 :
4968 342 : if (present(ZoneToResimulate)) {
4969 0 : firstZone = ZoneToResimulate;
4970 0 : lastZone = ZoneToResimulate;
4971 : }
4972 :
4973 16074 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4974 31464 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4975 15732 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4976 : // Heat transfer surfaces
4977 15732 : int firstSurf = thisSpace.HTSurfaceFirst;
4978 15732 : int lastSurf = thisSpace.HTSurfaceLast;
4979 213750 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4980 198018 : auto const &surface = state.dataSurface->Surface(surfNum);
4981 198018 : int repSurfNum = surface.RepresentativeCalcSurfNum;
4982 :
4983 198018 : if (surfNum != repSurfNum) {
4984 : #if 0
4985 : // Check for divergence
4986 : Real64 surfConv = -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
4987 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
4988 : Real64 repSurfConv = -state.dataHeatBalSurf->SurfHConvInt(repSurfNum) *
4989 : (state.dataHeatBalSurf->SurfTempIn(repSurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum));
4990 : Real64 diff = surfConv - repSurfConv;
4991 : if (std::abs(diff) > 3.0 && state.dataSurface->Surface(repSurfNum).ConstituentSurfaceNums.size() == 2) {
4992 : ShowWarningError(state, format("Difference in representative surface convection {:.3R} W/m2", diff));
4993 : ShowContinueErrorTimeStamp(state, "");
4994 : ShowContinueError(state, format(" Original Surface: {}", surface.Name));
4995 : ShowContinueError(state, format(" Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(surfNum)));
4996 : ShowContinueError(state,
4997 : format(" Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(surfNum)));
4998 : ShowContinueError(state,
4999 : format(" Sunlit fraction: {:.3R}",
5000 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum)));
5001 : ShowContinueError(state, format(" Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum)));
5002 : ShowContinueError(state,
5003 : format(" Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(surfNum)));
5004 : ShowContinueError(state, format(" Representative Surface: {}", state.dataSurface->Surface(repSurfNum).Name));
5005 : ShowContinueError(state, format(" Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(repSurfNum)));
5006 : ShowContinueError(state,
5007 : format(" Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(repSurfNum)));
5008 : ShowContinueError(state,
5009 : format(" Sunlit fraction: {:.3R}",
5010 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, repSurfNum)));
5011 : ShowContinueError(state,
5012 : format(" Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum)));
5013 : ShowContinueError(
5014 : state, format(" Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(repSurfNum)));
5015 : }
5016 : #endif
5017 :
5018 : // Surface Heat Balance Arrays
5019 44802 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempIn(repSurfNum);
5020 44802 : state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(repSurfNum);
5021 44802 : state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBal->SurfTempEffBulkAir(repSurfNum);
5022 44802 : state.dataHeatBalSurf->SurfHConvInt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(repSurfNum);
5023 44802 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(repSurfNum);
5024 44802 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(repSurfNum);
5025 44802 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(repSurfNum);
5026 :
5027 44802 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(repSurfNum);
5028 44802 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvExt(repSurfNum);
5029 44802 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(repSurfNum);
5030 44802 : state.dataHeatBalSurf->SurfHAirExt(surfNum) = state.dataHeatBalSurf->SurfHAirExt(repSurfNum);
5031 44802 : state.dataHeatBalSurf->SurfHSkyExt(surfNum) = state.dataHeatBalSurf->SurfHSkyExt(repSurfNum);
5032 44802 : state.dataHeatBalSurf->SurfHGrdExt(surfNum) = state.dataHeatBalSurf->SurfHGrdExt(repSurfNum);
5033 :
5034 44802 : state.dataSurface->SurfTAirRef(surfNum) = state.dataSurface->SurfTAirRef(repSurfNum);
5035 44802 : if (state.dataSurface->SurfTAirRef(surfNum) != DataSurfaces::RefAirTemp::Invalid) {
5036 0 : state.dataSurface->SurfTAirRefRpt(surfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(surfNum)];
5037 : }
5038 :
5039 44802 : state.dataSurface->surfExtConv(surfNum).hfModelEq = state.dataSurface->surfExtConv(repSurfNum).hfModelEq;
5040 44802 : state.dataSurface->surfExtConv(surfNum).hnModelEq = state.dataSurface->surfExtConv(repSurfNum).hnModelEq;
5041 :
5042 44802 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
5043 44802 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(repSurfNum);
5044 44802 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) =
5045 44802 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(repSurfNum);
5046 :
5047 : // Internal (non reporting variables)
5048 44802 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(repSurfNum);
5049 44802 : state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum);
5050 : }
5051 : }
5052 :
5053 : // Opaque surfaces
5054 15732 : firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
5055 15732 : lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
5056 152874 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
5057 137142 : auto const &surface = state.dataSurface->Surface(surfNum);
5058 137142 : int repSurfNum = surface.RepresentativeCalcSurfNum;
5059 :
5060 137142 : if (surfNum != repSurfNum) {
5061 : // Surface Heat Balance Arrays
5062 5814 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(repSurfNum);
5063 5814 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum);
5064 5814 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(repSurfNum);
5065 : }
5066 : }
5067 :
5068 : // Window surfaces
5069 15732 : firstSurf = thisSpace.WindowSurfaceFirst;
5070 15732 : lastSurf = thisSpace.WindowSurfaceLast;
5071 76608 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
5072 60876 : auto const &surface = state.dataSurface->Surface(surfNum);
5073 60876 : int repSurfNum = surface.RepresentativeCalcSurfNum;
5074 :
5075 60876 : if (surfNum != repSurfNum) {
5076 38988 : Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
5077 :
5078 : // Glazing
5079 38988 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
5080 38988 : state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
5081 38988 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
5082 :
5083 : // Frame
5084 38988 : Real64 frameHeatGain = 0.0;
5085 38988 : if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
5086 0 : Real64 frameAreaRatio = state.dataSurface->SurfWinFrameArea(surfNum) / state.dataSurface->SurfWinFrameArea(repSurfNum);
5087 0 : state.dataSurface->SurfWinFrameHeatGain(surfNum) = state.dataSurface->SurfWinFrameHeatGain(repSurfNum) * frameAreaRatio;
5088 0 : state.dataSurface->SurfWinFrameHeatLoss(surfNum) = state.dataSurface->SurfWinFrameHeatLoss(repSurfNum) * frameAreaRatio;
5089 0 : state.dataSurface->SurfWinFrameTempIn(surfNum) = state.dataSurface->SurfWinFrameTempIn(repSurfNum);
5090 0 : state.dataSurface->SurfWinFrameTempSurfOut(surfNum) = state.dataSurface->SurfWinFrameTempSurfOut(repSurfNum);
5091 0 : frameHeatGain = state.dataSurface->SurfWinFrameHeatGain(surfNum) - state.dataSurface->SurfWinFrameHeatLoss(surfNum);
5092 : }
5093 :
5094 : // Divider
5095 38988 : Real64 dividerHeatGain = 0.0;
5096 38988 : if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
5097 0 : Real64 dividerAreaRatio = state.dataSurface->SurfWinDividerArea(surfNum) / state.dataSurface->SurfWinDividerArea(repSurfNum);
5098 0 : state.dataSurface->SurfWinDividerHeatGain(surfNum) = state.dataSurface->SurfWinDividerHeatGain(repSurfNum) * dividerAreaRatio;
5099 0 : state.dataSurface->SurfWinDividerHeatLoss(surfNum) = state.dataSurface->SurfWinDividerHeatLoss(repSurfNum) * dividerAreaRatio;
5100 0 : state.dataSurface->SurfWinDividerTempIn(surfNum) = state.dataSurface->SurfWinDividerTempIn(repSurfNum);
5101 0 : state.dataSurface->SurfWinDividerTempSurfOut(surfNum) = state.dataSurface->SurfWinDividerTempSurfOut(repSurfNum);
5102 0 : dividerHeatGain = state.dataSurface->SurfWinDividerHeatGain(surfNum) - state.dataSurface->SurfWinDividerHeatLoss(surfNum);
5103 : }
5104 :
5105 38988 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = frameHeatGain + dividerHeatGain;
5106 :
5107 : // Whole window
5108 77976 : state.dataSurface->SurfWinHeatGain(surfNum) = (state.dataSurface->SurfWinHeatGain(repSurfNum) -
5109 38988 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(repSurfNum) * areaRatio) +
5110 38988 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum);
5111 : }
5112 : }
5113 15732 : }
5114 : }
5115 342 : }
5116 :
5117 2799877 : void UpdateFinalSurfaceHeatBalance(EnergyPlusData &state)
5118 : {
5119 :
5120 : // SUBROUTINE INFORMATION:
5121 : // AUTHOR Rick Strand
5122 : // DATE WRITTEN December 2000
5123 :
5124 : // PURPOSE OF THIS SUBROUTINE:
5125 : // If a radiant system is present and was on for part of the time step,
5126 : // then we probably need to make yet another pass through the heat balance.
5127 : // This is necessary because the heat source/sink to the surface that is
5128 : // the radiant system may have varied during the system time steps.
5129 :
5130 : // METHODOLOGY EMPLOYED:
5131 : // First, determine whether or not the radiant system was running. If
5132 : // any of the Qsource terms are non-zero, then it was running. Then,
5133 : // update the current source terms with the "average" value calculated
5134 : // by the radiant system algorithm. This requires the "USE" of the
5135 : // radiant algorithm module. Finally, using this source value, redo
5136 : // the inside and outside heat balances.
5137 :
5138 : bool LowTempRadSysOn; // .TRUE. if a low temperature radiant system is running
5139 : bool HighTempRadSysOn; // .TRUE. if a high temperature radiant system is running
5140 : bool HWBaseboardSysOn; // .TRUE. if a water baseboard heater is running
5141 : bool SteamBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
5142 : bool ElecBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
5143 : bool CoolingPanelSysOn; // true if a simple cooling panel is running
5144 : bool SwimmingPoolOn; // true if a pool is present (running)
5145 :
5146 2799877 : LowTempRadiantSystem::UpdateRadSysSourceValAvg(state, LowTempRadSysOn);
5147 2799877 : HighTempRadiantSystem::UpdateHTRadSourceValAvg(state, HighTempRadSysOn);
5148 2799877 : HWBaseboardRadiator::UpdateBBRadSourceValAvg(state, HWBaseboardSysOn);
5149 2799877 : SteamBaseboardRadiator::UpdateBBSteamRadSourceValAvg(state, SteamBaseboardSysOn);
5150 2799877 : ElectricBaseboardRadiator::UpdateBBElecRadSourceValAvg(state, ElecBaseboardSysOn);
5151 2799877 : CoolingPanelSimple::UpdateCoolingPanelSourceValAvg(state, CoolingPanelSysOn);
5152 2799877 : SwimmingPool::UpdatePoolSourceValAvg(state, SwimmingPoolOn);
5153 :
5154 2799877 : if (LowTempRadSysOn || HighTempRadSysOn || HWBaseboardSysOn || SteamBaseboardSysOn || ElecBaseboardSysOn || CoolingPanelSysOn || SwimmingPoolOn) {
5155 : // Solve the zone heat balance 'Detailed' solution
5156 : // Call the outside and inside surface heat balances
5157 82564 : CalcHeatBalanceOutsideSurf(state);
5158 82564 : CalcHeatBalanceInsideSurf(state);
5159 : }
5160 2799877 : }
5161 :
5162 2624518 : void UpdateThermalHistories(EnergyPlusData &state)
5163 : {
5164 :
5165 : // SUBROUTINE INFORMATION:
5166 : // AUTHOR Russ Taylor
5167 : // DATE WRITTEN June 1990
5168 : // RE-ENGINEERED Mar98 (RKS)
5169 :
5170 : // PURPOSE OF THIS SUBROUTINE:
5171 : // This subroutine updates and shifts the thermal and flux histories.
5172 :
5173 : // METHODOLOGY EMPLOYED:
5174 : // If a surface runs on the user selected subhourly time step, then the
5175 : // history terms for the temperatures and fluxes must simply be updated
5176 : // and shifted. However, if the surface runs at a different (longer) time
5177 : // step, then the "master" history series is used for the interpolated
5178 : // update scheme.
5179 :
5180 : // REFERENCES:
5181 : // (I)BLAST legacy routine UTHRMH
5182 : // Taylor et.al., Impact of Simultaneous Simulation of Buildings and
5183 : // Mechanical Systems in Heat Balance Based Energy Analysis Programs
5184 : // on System Response and Control, Building Simulation '91, IBPSA, Nice, France.
5185 :
5186 2624518 : if (state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag) {
5187 790 : state.dataHeatBalSurfMgr->QExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5188 790 : state.dataHeatBalSurfMgr->QInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5189 790 : state.dataHeatBalSurfMgr->TempInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5190 790 : state.dataHeatBalSurfMgr->TempExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5191 790 : state.dataHeatBalSurfMgr->SumTime.dimension(state.dataSurface->TotSurfaces, 0.0);
5192 790 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5193 31 : state.dataHeatBalSurfMgr->Qsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
5194 31 : state.dataHeatBalSurfMgr->Tsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
5195 31 : state.dataHeatBalSurfMgr->Tuser1.dimension(state.dataSurface->TotSurfaces, 0.0);
5196 : }
5197 790 : state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag = false;
5198 : }
5199 :
5200 22163257 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5201 39126078 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5202 19587339 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5203 19587339 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5204 19587339 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5205 165433320 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5206 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5207 145845981 : auto const &surface = state.dataSurface->Surface(SurfNum);
5208 :
5209 145845981 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5210 288450 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5211 138432 : continue;
5212 : }
5213 :
5214 145707549 : int const ConstrNum = surface.Construction;
5215 145707549 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5216 :
5217 145707549 : if (construct.NumCTFTerms == 0) {
5218 0 : continue; // Skip surfaces with no history terms
5219 : }
5220 :
5221 : // Sign convention for the various terms in the following two equations
5222 : // is based on the form of the Conduction Transfer Function equation
5223 : // given by:
5224 : // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + (Sum of)(V Qsrc)
5225 : // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + (Sum of)(W Qsrc)
5226 : // In both equations, flux is positive from outside to inside. The V and W terms are for radiant systems only.
5227 :
5228 : // Set current inside flux:
5229 145707549 : Real64 const SurfOutsideTempCurr = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
5230 145707549 : Real64 SurfInsideFluxHistCurr = SurfOutsideTempCurr * construct.CTFCross[0] -
5231 145707549 : state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFInside[0] +
5232 145707549 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum); // Heat source/sink term for radiant systems
5233 : // Only HT opaq surfaces are evaluated, previous if (surface.Class == SurfaceClass::Floor || surface.Class == SurfaceClass::Wall ||
5234 : // surface.Class == SurfaceClass::IntMass || surface.Class == SurfaceClass::Roof || surface.Class == SurfaceClass::Door) checks are
5235 : // redundant.
5236 145707549 : if (construct.SourceSinkPresent) {
5237 397692 : SurfInsideFluxHistCurr += state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceIn[0];
5238 : }
5239 145707549 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr;
5240 145707549 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting
5241 145707549 : state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr;
5242 :
5243 : // Update the temperature at the source/sink location (if one is present)
5244 145707549 : if (construct.SourceSinkPresent) {
5245 397692 : state.dataHeatBalSurf->SurfTempSource(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1) =
5246 397692 : SurfOutsideTempCurr * construct.CTFTSourceOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTSourceIn[0] +
5247 397692 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTSourceQ[0] +
5248 397692 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
5249 397692 : state.dataHeatBalSurf->SurfTempUserLoc(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1) =
5250 397692 : SurfOutsideTempCurr * construct.CTFTUserOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTUserIn[0] +
5251 397692 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTUserSource[0] +
5252 397692 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum);
5253 : }
5254 :
5255 : // Set current outside flux:
5256 145707549 : if (construct.SourceSinkPresent) {
5257 397692 : state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) =
5258 397692 : SurfOutsideTempCurr * construct.CTFOutside[0] - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
5259 397692 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceOut[0] +
5260 397692 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); // Heat source/sink term for radiant systems
5261 : } else {
5262 290619714 : state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = SurfOutsideTempCurr * construct.CTFOutside[0] -
5263 145309857 : state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
5264 145309857 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum);
5265 : }
5266 : // switch sign for balance at outside face
5267 145707549 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = -state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
5268 145707549 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(SurfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum);
5269 : }
5270 19538739 : }
5271 : } // ...end of loop over all (heat transfer) surfaces...
5272 :
5273 2624518 : if (state.dataHeatBal->SimpleCTFOnly && !state.dataGlobal->AnyConstrOverridesInModel) {
5274 : // Temporarily save the rvalue references of the last term arrays
5275 2161746 : Array1D<Real64> insideTemp(std::move(state.dataHeatBalSurf->SurfInsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
5276 2161746 : Array1D<Real64> outsideTemp(std::move(state.dataHeatBalSurf->SurfOutsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
5277 2161746 : Array1D<Real64> insideFlux(std::move(state.dataHeatBalSurf->SurfInsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
5278 2161746 : Array1D<Real64> outsideFlux(std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
5279 : // Shifting its internal pointer to data to the new object; Using the (Array1D && a) overload of the "=" operator
5280 19289358 : for (int HistTermNum = state.dataHeatBal->MaxCTFTerms + 1; HistTermNum >= 3; --HistTermNum) {
5281 17127612 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum - 1));
5282 17127612 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum - 1));
5283 17127612 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum - 1));
5284 17127612 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum - 1));
5285 : }
5286 : // Reuse the pointers of the last term arrays for the second term arrays
5287 2161746 : state.dataHeatBalSurf->SurfInsideTempHist(2) = std::move(insideTemp);
5288 2161746 : state.dataHeatBalSurf->SurfOutsideTempHist(2) = std::move(outsideTemp);
5289 2161746 : state.dataHeatBalSurf->SurfInsideFluxHist(2) = std::move(insideFlux);
5290 2161746 : state.dataHeatBalSurf->SurfOutsideFluxHist(2) = std::move(outsideFlux);
5291 : // 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)
5292 2161746 : state.dataHeatBalSurf->SurfInsideTempHist(2) = state.dataHeatBalSurf->SurfInsideTempHist(1);
5293 2161746 : state.dataHeatBalSurf->SurfOutsideTempHist(2) = state.dataHeatBalSurf->SurfOutsideTempHist(1);
5294 2161746 : state.dataHeatBalSurf->SurfInsideFluxHist(2) = state.dataHeatBalSurf->SurfInsideFluxHist(1);
5295 2161746 : state.dataHeatBalSurf->SurfOutsideFluxHist(2) = state.dataHeatBalSurf->SurfOutsideFluxHist(1);
5296 2161746 : return;
5297 2161746 : }
5298 :
5299 3581182 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5300 6253020 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5301 3134610 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5302 3134610 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5303 3134610 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5304 26009661 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5305 22875051 : auto const &surface = state.dataSurface->Surface(SurfNum);
5306 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5307 22875051 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5308 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5309 0 : continue;
5310 : }
5311 22875051 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5312 19144611 : state.dataHeatBalSurfMgr->TempExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
5313 19144611 : state.dataHeatBalSurfMgr->TempInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
5314 19144611 : state.dataHeatBalSurfMgr->QExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
5315 19144611 : state.dataHeatBalSurfMgr->QInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum);
5316 : }
5317 : }
5318 3118410 : }
5319 :
5320 : } // ...end of loop over all (heat transfer) surfaces...
5321 462772 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5322 431634 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5323 653526 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5324 326763 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5325 326763 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5326 326763 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5327 2540337 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5328 2213574 : auto const &surface = state.dataSurface->Surface(SurfNum);
5329 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5330 2213574 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5331 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5332 0 : continue;
5333 : }
5334 2213574 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5335 2201448 : state.dataHeatBalSurfMgr->Tsrc1(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1);
5336 2201448 : state.dataHeatBalSurfMgr->Tuser1(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1);
5337 2201448 : state.dataHeatBalSurfMgr->Qsrc1(SurfNum) = state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1);
5338 : }
5339 : }
5340 326763 : }
5341 : } // ...end of loop over all (heat transfer) surfaces...
5342 : }
5343 :
5344 : // SHIFT TEMPERATURE AND FLUX HISTORIES:
5345 : // SHIFT AIR TEMP AND FLUX SHIFT VALUES WHEN AT BOTTOM OF ARRAY SPACE.
5346 3581182 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5347 6253020 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5348 3134610 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5349 3134610 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5350 3134610 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5351 26009661 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5352 22875051 : auto const &surface = state.dataSurface->Surface(SurfNum);
5353 :
5354 22875051 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5355 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5356 0 : continue;
5357 : }
5358 :
5359 22875051 : int const ConstrNum = surface.Construction;
5360 22875051 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5361 :
5362 22875051 : ++state.dataHeatBalSurf->SurfCurrNumHist(SurfNum);
5363 22875051 : state.dataHeatBalSurfMgr->SumTime(SurfNum) = double(state.dataHeatBalSurf->SurfCurrNumHist(SurfNum)) * state.dataGlobal->TimeStepZone;
5364 :
5365 22875051 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == construct.NumHistories) {
5366 19142399 : state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
5367 :
5368 19142399 : if (construct.NumCTFTerms > 1) {
5369 18915644 : int const numCTFTerms(construct.NumCTFTerms);
5370 150295692 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
5371 131380048 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum) =
5372 131380048 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
5373 131380048 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum) =
5374 131380048 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
5375 131380048 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum) =
5376 131380048 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5377 131380048 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum) =
5378 131380048 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5379 131380048 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) =
5380 131380048 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
5381 131380048 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) =
5382 131380048 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
5383 131380048 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) =
5384 131380048 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5385 131380048 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) =
5386 131380048 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5387 : }
5388 : }
5389 :
5390 19142399 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempExt1(SurfNum);
5391 19142399 : state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempInt1(SurfNum);
5392 19142399 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QExt1(SurfNum);
5393 19142399 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QInt1(SurfNum);
5394 :
5395 19142399 : state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum);
5396 19142399 : state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum);
5397 19142399 : state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum);
5398 19142399 : state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum);
5399 : } else {
5400 3732652 : Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
5401 3732652 : if (construct.NumCTFTerms > 1) {
5402 3732652 : int const numCTFTerms(construct.NumCTFTerms);
5403 53391610 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
5404 : // TH(SideNum, TermNum, SurfNum) = (THM(SideNum, TermNum, SurfNum) -
5405 : // (THM(SideNum, TermNum, SurfNum) - THM(SideNum, TermNum - 1, SurfNum)) * sum_steps;
5406 49658958 : Real64 const THM_Out_1(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum));
5407 49658958 : Real64 const THM_In_1(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum));
5408 49658958 : Real64 const THM_Out_2(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum));
5409 49658958 : Real64 const THM_In_2(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum));
5410 49658958 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = THM_Out_1 - (THM_Out_1 - THM_Out_2) * sum_steps;
5411 49658958 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = THM_In_1 - (THM_In_1 - THM_In_2) * sum_steps;
5412 :
5413 49658958 : Real64 const QHM_Out_1(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum));
5414 49658958 : Real64 const QHM_In_1(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum));
5415 49658958 : Real64 const QHM_Out_2(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum));
5416 49658958 : Real64 const QHM_In_2(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum));
5417 49658958 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = QHM_Out_1 - (QHM_Out_1 - QHM_Out_2) * sum_steps;
5418 49658958 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = QHM_In_1 - (QHM_In_1 - QHM_In_2) * sum_steps;
5419 : }
5420 : }
5421 : // TH( 1, 2, SurfNum ) = THM( 1, 2, SurfNum ) - ( THM( 1, 2, SurfNum ) - TempExt1( SurfNum ) ) * sum_steps;
5422 3732652 : state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) =
5423 3732652 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) -
5424 3732652 : (state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempExt1(SurfNum)) * sum_steps;
5425 3732652 : state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) =
5426 3732652 : state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) -
5427 3732652 : (state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempInt1(SurfNum)) * sum_steps;
5428 3732652 : state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) =
5429 3732652 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) -
5430 3732652 : (state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QExt1(SurfNum)) * sum_steps;
5431 3732652 : state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) =
5432 3732652 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) -
5433 3732652 : (state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QInt1(SurfNum)) * sum_steps;
5434 : }
5435 : }
5436 3118410 : }
5437 : } // ...end of loop over all (heat transfer) surfaces
5438 :
5439 462772 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5440 431634 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5441 653526 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5442 326763 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5443 326763 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5444 326763 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5445 2540337 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5446 2213574 : auto const &surface = state.dataSurface->Surface(SurfNum);
5447 2213574 : int const ConstrNum = surface.Construction;
5448 2213574 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5449 2213574 : if (!construct.SourceSinkPresent) {
5450 1815882 : continue;
5451 : }
5452 397692 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5453 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5454 0 : continue;
5455 : }
5456 :
5457 397692 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5458 385536 : if (construct.NumCTFTerms > 1) {
5459 385536 : int const numCTFTerms = construct.NumCTFTerms;
5460 385536 : int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
5461 385536 : int m1 = m + 1;
5462 3820314 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing
5463 : // SurfTsrcHist( SurfNum, HistTerm ) = SurfTsrcHistM( SurfNum, HHistTerm ) = SurfTsrcHistM( SurfNum, HistTermNum - 1
5464 : // ); SurfQsrcHist( SurfNum, HistTerm ) = SurfQsrcHistM( SurfNum, HHistTerm ) = SurfQsrcHistM( SurfNum, HistTermNum -
5465 : // 1 );
5466 3434778 : state.dataHeatBalSurf->SurfTsrcHist[m1] = state.dataHeatBalSurf->SurfTsrcHistM[m1] =
5467 3434778 : state.dataHeatBalSurf->SurfTsrcHistM[m];
5468 3434778 : state.dataHeatBalSurf->SurfQsrcHist[m1] = state.dataHeatBalSurf->SurfQsrcHistM[m1] =
5469 3434778 : state.dataHeatBalSurf->SurfQsrcHistM[m];
5470 3434778 : state.dataHeatBalSurf->SurfTuserHist[m1] = state.dataHeatBalSurf->SurfTuserHistM[m1] =
5471 3434778 : state.dataHeatBalSurf->SurfTuserHistM[m];
5472 : }
5473 : }
5474 385536 : state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tsrc1(SurfNum);
5475 385536 : state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tuser1(SurfNum);
5476 385536 : state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Qsrc1(SurfNum);
5477 385536 : state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2);
5478 385536 : state.dataHeatBalSurf->SurfTuserHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2);
5479 385536 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2);
5480 : } else {
5481 12156 : Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
5482 :
5483 12156 : if (construct.NumCTFTerms > 1) {
5484 12156 : int const numCTFTerms = construct.NumCTFTerms;
5485 12156 : int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
5486 12156 : int m1 = m + 1;
5487 158028 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing [ l ] == ()
5488 : // Real64 const SurfTsrcHistM_elem( SurfTsrcHistM( SurfNum, HistTermNum ) );
5489 : // SurfTsrcHist( SurfNum, HistTermNum ) = SurfTsrcHistM_elem - ( SurfTsrcHistM_elem - SurfTsrcHistM( SurfNum,
5490 : // HistTermNum
5491 : // - 1 ) ) * sum_steps; Real64 const QsrcHistM_elem( SurfQsrcHistM( SurfNum, HistTermNum ) ); SurfQsrcHist( SurfNum,
5492 : // HistTermNum ) = QsrcHistM_elem - ( QsrcHistM_elem - SurfQsrcHistM( SurfNum, HistTermNum - 1 ) ) * sum_steps;
5493 145872 : Real64 const TsrcHistM_m1(state.dataHeatBalSurf->SurfTsrcHistM[m1]);
5494 145872 : state.dataHeatBalSurf->SurfTsrcHist[m1] =
5495 145872 : TsrcHistM_m1 - (TsrcHistM_m1 - state.dataHeatBalSurf->SurfTsrcHistM[m]) * sum_steps;
5496 145872 : Real64 const QsrcHistM_m1(state.dataHeatBalSurf->SurfQsrcHistM[m1]);
5497 145872 : state.dataHeatBalSurf->SurfQsrcHist[m1] =
5498 145872 : QsrcHistM_m1 - (QsrcHistM_m1 - state.dataHeatBalSurf->SurfQsrcHistM[m]) * sum_steps;
5499 145872 : Real64 const TuserHistM_m1(state.dataHeatBalSurf->SurfTuserHistM[m1]);
5500 145872 : state.dataHeatBalSurf->SurfTuserHist[m1] =
5501 145872 : TuserHistM_m1 - (TuserHistM_m1 - state.dataHeatBalSurf->SurfTuserHistM[m]) * sum_steps;
5502 : }
5503 : }
5504 : // Tuned Linear indexing
5505 : // SurfTsrcHist( SurfNum, 2 ) = SurfTsrcHistM( SurfNum, 2 ) - ( SurfTsrcHistM( SurfNum, 2 ) - Tsrc1( SurfNum ) ) * sum_steps;
5506 : // SurfQsrcHist( SurfNum, 2 ) = SurfQsrcHistM( SurfNum, 2 ) - ( SurfQsrcHistM( SurfNum, 2 ) - Qsrc1( SurfNum ) ) * sum_steps;
5507 12156 : int const l2 = state.dataHeatBalSurf->SurfTsrcHist.index(SurfNum, 2);
5508 12156 : state.dataHeatBalSurf->SurfTsrcHist[l2] =
5509 12156 : state.dataHeatBalSurf->SurfTsrcHistM[l2] -
5510 12156 : (state.dataHeatBalSurf->SurfTsrcHistM[l2] - state.dataHeatBalSurfMgr->Tsrc1(SurfNum)) * sum_steps;
5511 12156 : state.dataHeatBalSurf->SurfQsrcHist[l2] =
5512 12156 : state.dataHeatBalSurf->SurfQsrcHistM[l2] -
5513 12156 : (state.dataHeatBalSurf->SurfQsrcHistM[l2] - state.dataHeatBalSurfMgr->Qsrc1(SurfNum)) * sum_steps;
5514 12156 : state.dataHeatBalSurf->SurfTuserHist[l2] =
5515 12156 : state.dataHeatBalSurf->SurfTuserHistM[l2] -
5516 12156 : (state.dataHeatBalSurf->SurfTuserHistM[l2] - state.dataHeatBalSurfMgr->Tuser1(SurfNum)) * sum_steps;
5517 : }
5518 : }
5519 326763 : }
5520 : } // ...end of loop over all (heat transfer) surfaces...
5521 : } // ...end of AnyInternalHeatSourceInInput
5522 : }
5523 :
5524 3732214 : void CalculateZoneMRT(EnergyPlusData &state,
5525 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
5526 : {
5527 :
5528 : // SUBROUTINE INFORMATION:
5529 : // AUTHOR Rick Strand
5530 : // DATE WRITTEN November 2000
5531 :
5532 : // PURPOSE OF THIS SUBROUTINE:
5533 : // Calculates the current zone and enclosure MRT for thermal comfort and radiation
5534 : // calculation purposes.
5535 :
5536 3732214 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5537 803 : state.dataHeatBalSurfMgr->SurfaceAE.allocate(state.dataSurface->TotSurfaces);
5538 803 : state.dataHeatBalSurfMgr->ZoneAESum.allocate(state.dataGlobal->NumOfZones);
5539 803 : state.dataHeatBalSurfMgr->SurfaceAE = 0.0;
5540 803 : state.dataHeatBalSurfMgr->ZoneAESum = 0.0;
5541 6009 : for (auto &encl : state.dataViewFactor->EnclRadInfo) {
5542 5206 : encl.sumAE = 0.0;
5543 803 : }
5544 48135 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
5545 47332 : auto const &surface = state.dataSurface->Surface(SurfNum);
5546 47332 : if (surface.HeatTransSurf) {
5547 45625 : auto &thisSurfAE = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum);
5548 45625 : thisSurfAE = surface.Area * state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal;
5549 45625 : int ZoneNum = surface.Zone;
5550 45625 : if (ZoneNum > 0) {
5551 45624 : state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) += thisSurfAE;
5552 : }
5553 45625 : if (surface.RadEnclIndex > 0) {
5554 45624 : state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).sumAE += thisSurfAE;
5555 : }
5556 : }
5557 : }
5558 : }
5559 :
5560 : // Zero sumAET for applicable enclosures
5561 3732214 : if (present(ZoneToResimulate)) {
5562 1592198 : for (int spaceNum : state.dataHeatBal->Zone(ZoneToResimulate).spaceIndexes) {
5563 796099 : int enclNum = state.dataHeatBal->space(spaceNum).radiantEnclosureNum;
5564 796099 : state.dataViewFactor->EnclRadInfo(enclNum).sumAET = 0.0;
5565 796099 : state.dataViewFactor->EnclRadInfo(enclNum).reCalcMRT = true;
5566 796099 : }
5567 : } else {
5568 23358215 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
5569 20422100 : thisEnclosure.reCalcMRT = true;
5570 2936115 : }
5571 : }
5572 26930699 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5573 23198485 : if (present(ZoneToResimulate) && (ZoneNum != ZoneToResimulate)) {
5574 1976242 : continue;
5575 : }
5576 21222243 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
5577 21222243 : if (state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) > 0.01) {
5578 21220218 : Real64 zoneSumAET = 0.0;
5579 42489036 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
5580 21268818 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5581 201669442 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
5582 180400624 : Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) * state.dataHeatBalSurf->SurfTempIn(SurfNum);
5583 180400624 : zoneSumAET += surfAET;
5584 180400624 : state.dataViewFactor->EnclRadInfo(state.dataSurface->Surface(SurfNum).RadEnclIndex).sumAET += surfAET;
5585 : }
5586 21220218 : }
5587 21220218 : thisZoneHB.MRT = zoneSumAET / state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum);
5588 : } else {
5589 2025 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5590 2 : ShowWarningError(
5591 : state,
5592 2 : format("Zone areas*inside surface emissivities are summing to zero, for Zone=\"{}\"", state.dataHeatBal->Zone(ZoneNum).Name));
5593 3 : ShowContinueError(state, "As a result, MRT will be set to MAT for that zone");
5594 : }
5595 2025 : thisZoneHB.MRT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
5596 : }
5597 : }
5598 : // Calculate MRT for applicable enclosures
5599 26926655 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
5600 23194441 : if (!thisEnclosure.reCalcMRT) {
5601 0 : continue;
5602 : }
5603 23194441 : if (thisEnclosure.sumAE > 0.01) {
5604 23192416 : thisEnclosure.sumAET = 0.0;
5605 218005217 : for (int surfNum : thisEnclosure.SurfacePtr) {
5606 194812801 : Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum);
5607 194812801 : thisEnclosure.sumAET += surfAET;
5608 : }
5609 23192416 : thisEnclosure.MRT = thisEnclosure.sumAET / thisEnclosure.sumAE;
5610 : } else {
5611 2025 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5612 2 : ShowWarningError(state,
5613 2 : format("Enclosure areas*inside surface emissivities are summing to zero, for Enclosure=\"{}\"", thisEnclosure.Name));
5614 3 : ShowContinueError(state, "As a result, MRT will be set to the volume weighted average MAT for that enclosure");
5615 : }
5616 2025 : Real64 sumMATVol = 0.0;
5617 2025 : Real64 sumVol = 0.0;
5618 2025 : Real64 sumMAT = 0.0;
5619 4050 : for (auto &spaceNum : thisEnclosure.spaceNums) {
5620 2025 : Real64 spaceVolume = state.dataHeatBal->space(spaceNum).Volume;
5621 2025 : Real64 spaceMAT = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT;
5622 2025 : sumVol += spaceVolume;
5623 2025 : sumMATVol += spaceMAT * spaceVolume;
5624 2025 : sumMAT += spaceMAT;
5625 2025 : }
5626 2025 : if (sumVol > 0.01) {
5627 2025 : thisEnclosure.MRT = sumMATVol / sumVol;
5628 : } else {
5629 0 : thisEnclosure.MRT = sumMAT / (int)thisEnclosure.spaceNums.size();
5630 : }
5631 : }
5632 : // Set space MRTs
5633 46441526 : for (int spaceNum : thisEnclosure.spaceNums) {
5634 23247085 : state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MRT = thisEnclosure.MRT;
5635 23194441 : }
5636 3732214 : }
5637 :
5638 3732214 : state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime = false;
5639 3732214 : }
5640 :
5641 : // End of Record Keeping subroutines for the HB Module
5642 : // *****************************************************************************
5643 :
5644 : // Beginning of Reporting subroutines for the HB Module
5645 : // *****************************************************************************
5646 :
5647 2799877 : void CalcThermalResilience(EnergyPlusData &state)
5648 : {
5649 : // This function calculate timestep-wise heat index and humidex.
5650 :
5651 : // The computation of the heat index is a refinement of a result obtained by multiple regression analysis
5652 : // carried out by Lans P. Rothfusz and described in a 1990 National Weather Service (NWS)
5653 : // Technical Attachment (SR 90-23).
5654 : // Reference: https://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
5655 :
5656 : // The current formula for determining the humidex was developed by J. M. Masterton and F. A. Richardson of
5657 : // Canada's Atmospheric Environment Service in 1979.
5658 : // Reference: Masterson, J., and F. Richardson, 1979: Humidex, a method of quantifying human
5659 : // discomfort due to excessive heat and humidity CLI 1-79, Environment Canada, Atmospheric Environment Service
5660 : // using OutputProcessor::ReqRepVars;
5661 2799877 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
5662 6010 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5663 10414 : SetupOutputVariable(state,
5664 : "Zone Heat Index",
5665 : Constant::Units::C,
5666 5207 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex,
5667 : OutputProcessor::TimeStepType::Zone,
5668 : OutputProcessor::StoreType::Average,
5669 5207 : state.dataHeatBal->Zone(ZoneNum).Name);
5670 10414 : SetupOutputVariable(state,
5671 : "Zone Humidity Index",
5672 : Constant::Units::None,
5673 5207 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex,
5674 : OutputProcessor::TimeStepType::Zone,
5675 : OutputProcessor::StoreType::Average,
5676 5207 : state.dataHeatBal->Zone(ZoneNum).Name);
5677 : }
5678 22660 : for (auto const *reqVar : state.dataOutputProcessor->reqVars) {
5679 21857 : if (reqVar->name == "Zone Heat Index") {
5680 0 : state.dataHeatBalSurfMgr->reportVarHeatIndex = true;
5681 21857 : } else if (reqVar->name == "Zone Humidity Index") {
5682 0 : state.dataHeatBalSurfMgr->reportVarHumidex = true;
5683 : }
5684 803 : }
5685 : }
5686 :
5687 : // Calculate Heat Index and Humidex.
5688 : // The heat index equation set is fit to Fahrenheit units, so the zone air temperature values are first convert to F,
5689 : // then heat index is calculated and converted back to C.
5690 2799877 : if (state.dataHeatBalSurfMgr->reportVarHeatIndex || state.dataOutRptTab->displayThermalResilienceSummary) {
5691 6500454 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5692 5413755 : Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5693 5413755 : Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
5694 5413755 : Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress) * 100.0;
5695 5413755 : Real64 const ZoneTF = ZoneT * (9.0 / 5.0) + 32.0;
5696 5413755 : if (state.dataHeatBal->heatIndexMethod == DataHeatBalance::HeatIndexMethod::Simplified) {
5697 5413755 : Real64 constexpr c1 = -42.379;
5698 5413755 : Real64 constexpr c2 = 2.04901523;
5699 5413755 : Real64 constexpr c3 = 10.14333127;
5700 5413755 : Real64 constexpr c4 = -.22475541;
5701 5413755 : Real64 constexpr c5 = -.00683783;
5702 5413755 : Real64 constexpr c6 = -.05481717;
5703 5413755 : Real64 constexpr c7 = .00122874;
5704 5413755 : Real64 constexpr c8 = .00085282;
5705 5413755 : Real64 constexpr c9 = -.00000199;
5706 : Real64 HI;
5707 :
5708 5413755 : if (ZoneTF < 80) {
5709 4680490 : HI = 0.5 * (ZoneTF + 61.0 + (ZoneTF - 68.0) * 1.2 + (ZoneRH * 0.094));
5710 : } else {
5711 733265 : HI = c1 + c2 * ZoneTF + c3 * ZoneRH + c4 * ZoneTF * ZoneRH + c5 * ZoneTF * ZoneTF + c6 * ZoneRH * ZoneRH +
5712 733265 : c7 * ZoneTF * ZoneTF * ZoneRH + c8 * ZoneTF * ZoneRH * ZoneRH + c9 * ZoneTF * ZoneTF * ZoneRH * ZoneRH;
5713 733265 : if (ZoneRH < 13 && ZoneTF < 112) {
5714 34760 : HI -= (13 - ZoneRH) / 4 * std::sqrt((17 - abs(ZoneTF - 95)) / 17);
5715 698505 : } else if (ZoneRH > 85 && ZoneTF < 87) {
5716 15013 : HI += (ZoneRH - 85) / 10 * (87 - ZoneTF) / 5;
5717 : }
5718 : }
5719 5413755 : HI = (HI - 32.0) * (5.0 / 9.0);
5720 5413755 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex = HI;
5721 : } else {
5722 : // calculate extended heat index
5723 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex =
5724 0 : ExtendedHI::heatindex(state, ZoneT + Constant::Kelvin, ZoneRH / 100.0) - Constant::Kelvin;
5725 : }
5726 : }
5727 : }
5728 2799877 : if (state.dataHeatBalSurfMgr->reportVarHumidex || state.dataOutRptTab->displayThermalResilienceSummary) {
5729 6500454 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5730 5413755 : Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
5731 5413755 : Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5732 5413755 : Real64 const TDewPointK = Psychrometrics::PsyTdpFnWPb(state, ZoneW, state.dataEnvrn->OutBaroPress) + Constant::Kelvin;
5733 5413755 : Real64 const e = 6.11 * std::exp(5417.7530 * ((1 / 273.16) - (1 / TDewPointK)));
5734 5413755 : Real64 const h = 5.0 / 9.0 * (e - 10.0);
5735 5413755 : Real64 const Humidex = ZoneT + h;
5736 5413755 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex = Humidex;
5737 : }
5738 : }
5739 2799877 : }
5740 :
5741 1086699 : void ReportThermalResilience(EnergyPlusData &state)
5742 : {
5743 :
5744 1086699 : Array1D_bool reportPeriodFlags;
5745 1086699 : if (state.dataWeather->TotReportPers > 0) {
5746 5376 : reportPeriodFlags.dimension(state.dataWeather->TotThermalReportPers, false);
5747 5376 : General::findReportPeriodIdx(state, state.dataWeather->ThermalReportPeriodInput, state.dataWeather->TotThermalReportPers, reportPeriodFlags);
5748 : }
5749 :
5750 1086699 : auto &ort = state.dataOutRptTab;
5751 1093611 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5752 6912 : if (reportPeriodFlags(i)) {
5753 0 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
5754 0 : state.dataWeather->ThermalReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
5755 : }
5756 : }
5757 :
5758 1086699 : if (state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime) {
5759 672 : int constexpr HINoBins = 5; // Heat Index range - number of bins
5760 672 : int constexpr HumidexNoBins = 5; // Humidex range - number of bins
5761 672 : int constexpr SETNoBins = 5; // SET report column numbers
5762 672 : int constexpr ColdHourOfSafetyNoBins = 5; // Cold Stress Hour of Safety number of columns
5763 672 : int constexpr HeatHourOfSafetyNoBins = 5; // Heat Stress Hour of Safety number of columns
5764 672 : int constexpr UnmetDegreeHourNoBins = 6; // Unmet Degree Hour number of columns
5765 672 : int constexpr DiscomfortWtExceedHourNoBins = 4; // Unmet Degree Hour number of columns
5766 :
5767 672 : if (state.dataHeatBal->TotPeople == 0) {
5768 103 : state.dataHeatBalSurfMgr->hasPierceSET = false;
5769 : }
5770 3619 : for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
5771 2947 : if (!state.dataHeatBal->People(iPeople).Pierce) {
5772 2936 : state.dataHeatBalSurfMgr->hasPierceSET = false;
5773 : }
5774 : }
5775 4271 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5776 : // the whole period
5777 : // user specified reporting period
5778 3604 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5779 5 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5780 5 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5781 5 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5782 5 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5783 5 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5784 5 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5785 5 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
5786 5 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
5787 5 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
5788 : }
5789 5 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(ColdHourOfSafetyNoBins, 0.0);
5790 5 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(HeatHourOfSafetyNoBins, 0.0);
5791 5 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, i).assign(UnmetDegreeHourNoBins, 0.0);
5792 5 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
5793 5 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
5794 : }
5795 3599 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod = 0.0;
5796 3599 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod = 0.0;
5797 3599 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod = 0.0;
5798 3599 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod = 0.0;
5799 : }
5800 672 : state.dataHeatBalSurfMgr->lowSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
5801 672 : state.dataHeatBalSurfMgr->highSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
5802 672 : state.dataHeatBalSurfMgr->lowSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
5803 672 : state.dataHeatBalSurfMgr->highSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
5804 672 : state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime = false;
5805 : }
5806 :
5807 : // Count hours only during weather simulation periods
5808 1086699 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
5809 : // use default value if there are no user inputs
5810 219096 : Real64 ColdTempThresh = 15.56;
5811 219096 : Real64 HeatTempThresh = 30.0;
5812 : // Trace current time step Zone Pierce SET; NaN if no occupant or SET not calculated
5813 : // Record last time step SET to trace SET unmet duration;
5814 :
5815 219096 : Real64 valueNotInit = -999.0;
5816 219096 : Real64 nearThreshold = 1.0;
5817 1192032 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5818 972936 : state.dataHeatBal->Resilience(ZoneNum).PierceSET = valueNotInit;
5819 972936 : state.dataHeatBal->Resilience(ZoneNum).PMV = valueNotInit;
5820 : }
5821 1069296 : for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
5822 850200 : int ZoneNum = state.dataHeatBal->People(iPeople).ZonePtr;
5823 850200 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc =
5824 850200 : state.dataHeatBal->People(iPeople).NumberOfPeople * state.dataHeatBal->People(iPeople).sched->getCurrentVal();
5825 850200 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
5826 850200 : if (state.dataHeatBal->People(iPeople).Pierce) {
5827 0 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = state.dataThermalComforts->ThermalComfortData(iPeople).PierceSET;
5828 : } else {
5829 850200 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = -1;
5830 : }
5831 :
5832 850200 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
5833 850200 : Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5834 850200 : ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
5835 850200 : bool &CrossedColdThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedColdThresh;
5836 850200 : if (Temperature > ColdTempThresh) { // safe
5837 781208 : if (!CrossedColdThresh) {
5838 : // compute the number of hours before threshold is reached
5839 396296 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
5840 : }
5841 : } else { // danger
5842 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5843 68992 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
5844 68992 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
5845 68992 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5846 : // first time crossing threshold
5847 68992 : if (!CrossedColdThresh) {
5848 : // compute the time when the zone crosses the threshold temperature
5849 : int encodedMonDayHrMin;
5850 10 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5851 10 : state.dataEnvrn->Month,
5852 10 : state.dataEnvrn->DayOfMonth,
5853 10 : state.dataGlobal->HourOfDay,
5854 10 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5855 : // fixme: not sure how to aggregate by zone
5856 10 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[1] = encodedMonDayHrMin;
5857 10 : CrossedColdThresh = true;
5858 : }
5859 : }
5860 850200 : HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
5861 850200 : bool &CrossedHeatThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedHeatThresh;
5862 850200 : if (Temperature < HeatTempThresh) { // safe
5863 845039 : if (!CrossedHeatThresh) {
5864 : // compute the number of hours before threshold is reached
5865 460217 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
5866 : }
5867 : } else { // danger
5868 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5869 5161 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
5870 5161 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
5871 5161 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5872 : // first time crossing threshold
5873 5161 : if (!CrossedHeatThresh) {
5874 : // compute the time when the zone crosses the threshold temperature
5875 : int encodedMonDayHrMin;
5876 13 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5877 13 : state.dataEnvrn->Month,
5878 13 : state.dataEnvrn->DayOfMonth,
5879 13 : state.dataGlobal->HourOfDay,
5880 13 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5881 13 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[1] = encodedMonDayHrMin;
5882 13 : CrossedHeatThresh = true;
5883 : }
5884 : }
5885 :
5886 850200 : Real64 VeryHotPMVThresh = 3.0;
5887 850200 : Real64 WarmPMVThresh = 0.7;
5888 850200 : Real64 CoolPMVThresh = -0.7;
5889 850200 : Real64 VeryColdPMVThresh = -3.0;
5890 850200 : Real64 PMV = state.dataThermalComforts->ThermalComfortData(iPeople).FangerPMV;
5891 850200 : if (PMV < VeryColdPMVThresh) {
5892 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[0] +=
5893 0 : (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5894 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[0] +=
5895 0 : (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5896 : }
5897 850200 : if (PMV < CoolPMVThresh) {
5898 91082 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[1] +=
5899 91082 : (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5900 91082 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[1] +=
5901 91082 : (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5902 : }
5903 850200 : if (PMV > WarmPMVThresh) {
5904 94796 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[2] +=
5905 94796 : (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
5906 94796 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[2] +=
5907 94796 : (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5908 : }
5909 850200 : if (PMV > VeryHotPMVThresh) {
5910 402 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[3] +=
5911 402 : (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
5912 402 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[3] +=
5913 402 : (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5914 : }
5915 :
5916 : // check whether PierceSET changed for people in a zone
5917 850200 : if (state.dataHeatBal->Resilience(ZoneNum).PierceSET < valueNotInit + nearThreshold) {
5918 850200 : state.dataHeatBal->Resilience(ZoneNum).PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
5919 : } else {
5920 0 : if (state.dataHeatBal->Resilience(ZoneNum).PierceSET != state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET) {
5921 0 : ShowRecurringWarningErrorAtEnd(state,
5922 0 : fmt::format("Zone {} has multiple people objects with different PierceSet.", ZoneNum),
5923 0 : state.dataHeatBalFanSys->PierceSETerrorIndex);
5924 : }
5925 : }
5926 :
5927 : // check whether PierceSET, PMV, etc. changed for different people in a zone
5928 850200 : if (state.dataHeatBal->Resilience(ZoneNum).PMV < valueNotInit + nearThreshold) {
5929 850200 : state.dataHeatBal->Resilience(ZoneNum).PMV = PMV;
5930 : } else {
5931 0 : if (state.dataHeatBal->Resilience(ZoneNum).PMV != PMV) {
5932 0 : ShowRecurringWarningErrorAtEnd(state,
5933 0 : fmt::format("Zone {} has multiple people objects with different PMV.", ZoneNum),
5934 0 : state.dataHeatBalFanSys->PMVerrorIndex);
5935 : }
5936 : }
5937 :
5938 850200 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5939 0 : if (reportPeriodFlags(i)) {
5940 0 : int ReportPeriodIdx = i;
5941 0 : ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
5942 0 : bool &CrossedColdThreshRepPeriod = state.dataHeatBalFanSys->CrossedColdThreshRepPeriod(ZoneNum, ReportPeriodIdx);
5943 0 : if (Temperature > ColdTempThresh) { // safe
5944 0 : if (!CrossedColdThreshRepPeriod) {
5945 : // compute the number of hours before threshold is reached
5946 0 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
5947 : }
5948 : } else { // danger
5949 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5950 0 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
5951 0 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
5952 0 : NumOcc * state.dataGlobal->TimeStepZone;
5953 0 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
5954 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5955 : // first time crossing threshold
5956 0 : if (!CrossedColdThreshRepPeriod) {
5957 : // compute the time when the zone crosses the threshold temperature
5958 : int encodedMonDayHrMin;
5959 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5960 0 : state.dataEnvrn->Month,
5961 0 : state.dataEnvrn->DayOfMonth,
5962 0 : state.dataGlobal->HourOfDay,
5963 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5964 : // fixme: not sure how to aggregate by zone
5965 0 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
5966 0 : CrossedColdThreshRepPeriod = true;
5967 : }
5968 : }
5969 0 : HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
5970 0 : bool &CrossedHeatThreshRepPeriod = state.dataHeatBalFanSys->CrossedHeatThreshRepPeriod(ZoneNum, ReportPeriodIdx);
5971 0 : if (Temperature < HeatTempThresh) { // safe
5972 0 : if (!CrossedHeatThreshRepPeriod) {
5973 : // compute the number of hours before threshold is reached
5974 0 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
5975 : }
5976 : } else { // danger
5977 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5978 0 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
5979 0 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
5980 0 : NumOcc * state.dataGlobal->TimeStepZone;
5981 0 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
5982 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5983 : // first time crossing threshold
5984 0 : if (!CrossedHeatThreshRepPeriod) {
5985 : // compute the time when the zone crosses the threshold temperature
5986 : int encodedMonDayHrMin;
5987 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5988 0 : state.dataEnvrn->Month,
5989 0 : state.dataEnvrn->DayOfMonth,
5990 0 : state.dataGlobal->HourOfDay,
5991 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5992 0 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
5993 0 : CrossedHeatThreshRepPeriod = true;
5994 : }
5995 : }
5996 :
5997 0 : if (PMV < VeryColdPMVThresh) {
5998 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
5999 0 : (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
6000 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6001 0 : (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6002 : }
6003 0 : if (PMV < CoolPMVThresh) {
6004 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6005 0 : (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
6006 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6007 0 : (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6008 : }
6009 0 : if (PMV > WarmPMVThresh) {
6010 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6011 0 : (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
6012 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6013 0 : (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6014 : }
6015 0 : if (PMV > VeryHotPMVThresh) {
6016 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6017 0 : (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
6018 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6019 0 : (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6020 : }
6021 : }
6022 : }
6023 : }
6024 1192032 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6025 972936 : Real64 HI = state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex;
6026 972936 : Real64 Humidex = state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex;
6027 :
6028 972936 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6029 972936 : if (HI <= 26.7) {
6030 921157 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[0] += state.dataGlobal->TimeStepZone;
6031 921157 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6032 921157 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6033 51779 : } else if (HI > 26.7 && HI <= 32.2) {
6034 41483 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[1] += state.dataGlobal->TimeStepZone;
6035 41483 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6036 41483 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6037 10296 : } else if (HI > 32.2 && HI <= 39.4) {
6038 4776 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[2] += state.dataGlobal->TimeStepZone;
6039 4776 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6040 4776 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6041 5520 : } else if (HI > 39.4 && HI <= 51.7) {
6042 3610 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[3] += state.dataGlobal->TimeStepZone;
6043 3610 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
6044 3610 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6045 : } else {
6046 1910 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[4] += state.dataGlobal->TimeStepZone;
6047 1910 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
6048 1910 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6049 : }
6050 :
6051 972936 : if (Humidex <= 29) {
6052 884184 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[0] += state.dataGlobal->TimeStepZone;
6053 884184 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6054 884184 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6055 88752 : } else if (Humidex > 29 && Humidex <= 40) {
6056 78160 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[1] += state.dataGlobal->TimeStepZone;
6057 78160 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6058 78160 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6059 10592 : } else if (Humidex > 40 && Humidex <= 45) {
6060 4801 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[2] += state.dataGlobal->TimeStepZone;
6061 4801 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6062 4801 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6063 5791 : } else if (Humidex > 45 && Humidex <= 50) {
6064 3093 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[3] += state.dataGlobal->TimeStepZone;
6065 3093 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
6066 3093 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6067 : } else {
6068 2698 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[4] += state.dataGlobal->TimeStepZone;
6069 2698 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
6070 2698 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6071 : }
6072 :
6073 972936 : Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
6074 972936 : auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
6075 972936 : Real64 CoolingSetpoint = zoneTstatSetpt.setptHi;
6076 972936 : Real64 HeatingSetpoint = zoneTstatSetpt.setptLo;
6077 :
6078 972936 : if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
6079 42672 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[0] += (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6080 42672 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[1] +=
6081 42672 : NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6082 42672 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[2] +=
6083 42672 : (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6084 : }
6085 972936 : if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
6086 65815 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[3] += (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6087 65815 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[4] +=
6088 65815 : NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6089 65815 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[5] +=
6090 65815 : (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6091 : }
6092 :
6093 972936 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
6094 : int encodedMonDayHrMin;
6095 0 : Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
6096 0 : Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
6097 :
6098 0 : if (PierceSET <= 12.2) {
6099 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[0] += (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
6100 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[1] += (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
6101 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[2] += (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6102 : // Reset duration when last step is out of range.
6103 0 : if (PierceSETLast == -1 || PierceSETLast > 12.2) {
6104 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6105 0 : state.dataEnvrn->Month,
6106 0 : state.dataEnvrn->DayOfMonth,
6107 0 : state.dataGlobal->HourOfDay,
6108 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6109 0 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
6110 0 : state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
6111 : }
6112 : // Keep the longest duration record.
6113 0 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
6114 0 : if (state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] &&
6115 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6116 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] = state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1];
6117 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[4] = state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1];
6118 : }
6119 0 : } else if (PierceSET > 30) {
6120 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[0] += (PierceSET - 30) * state.dataGlobal->TimeStepZone;
6121 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[1] += (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
6122 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[2] += (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6123 0 : if (PierceSETLast == -1 || PierceSETLast <= 30) {
6124 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6125 0 : state.dataEnvrn->Month,
6126 0 : state.dataEnvrn->DayOfMonth,
6127 0 : state.dataGlobal->HourOfDay,
6128 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6129 0 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
6130 0 : state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
6131 : }
6132 0 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
6133 0 : if (state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] &&
6134 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6135 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] = state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1];
6136 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[4] = state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1];
6137 : }
6138 : }
6139 :
6140 0 : if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
6141 0 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
6142 0 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
6143 : }
6144 : }
6145 :
6146 972936 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
6147 0 : if (reportPeriodFlags(i)) {
6148 0 : int ReportPeriodIdx = i;
6149 :
6150 0 : if (HI <= 26.7) {
6151 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6152 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6153 0 : NumOcc * state.dataGlobal->TimeStepZone;
6154 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6155 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6156 0 : } else if (HI > 26.7 && HI <= 32.2) {
6157 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6158 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6159 0 : NumOcc * state.dataGlobal->TimeStepZone;
6160 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6161 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6162 0 : } else if (HI > 32.2 && HI <= 39.4) {
6163 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6164 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6165 0 : NumOcc * state.dataGlobal->TimeStepZone;
6166 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6167 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6168 0 : } else if (HI > 39.4 && HI <= 51.7) {
6169 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6170 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6171 0 : NumOcc * state.dataGlobal->TimeStepZone;
6172 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6173 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6174 : } else {
6175 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
6176 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6177 0 : NumOcc * state.dataGlobal->TimeStepZone;
6178 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6179 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6180 : }
6181 :
6182 0 : if (Humidex <= 29) {
6183 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6184 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6185 0 : NumOcc * state.dataGlobal->TimeStepZone;
6186 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6187 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6188 0 : } else if (Humidex > 29 && Humidex <= 40) {
6189 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6190 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6191 0 : NumOcc * state.dataGlobal->TimeStepZone;
6192 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6193 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6194 0 : } else if (Humidex > 40 && Humidex <= 45) {
6195 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6196 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6197 0 : NumOcc * state.dataGlobal->TimeStepZone;
6198 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6199 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6200 0 : } else if (Humidex > 45 && Humidex <= 50) {
6201 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6202 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6203 0 : NumOcc * state.dataGlobal->TimeStepZone;
6204 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6205 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6206 : } else {
6207 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
6208 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6209 0 : NumOcc * state.dataGlobal->TimeStepZone;
6210 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6211 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6212 : }
6213 :
6214 0 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
6215 : int encodedMonDayHrMin;
6216 0 : Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
6217 0 : Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
6218 0 : if (PierceSET <= 12.2) {
6219 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6220 0 : (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
6221 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6222 0 : (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
6223 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6224 0 : (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6225 : // Reset duration when last step is out of range
6226 0 : if (PierceSETLast == -1 || PierceSETLast > 12.2) {
6227 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6228 0 : state.dataEnvrn->Month,
6229 0 : state.dataEnvrn->DayOfMonth,
6230 0 : state.dataGlobal->HourOfDay,
6231 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6232 0 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6233 0 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6234 0 : } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
6235 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6236 0 : state.dataEnvrn->Month,
6237 0 : state.dataEnvrn->DayOfMonth,
6238 0 : state.dataGlobal->HourOfDay,
6239 0 : state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
6240 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6241 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6242 : }
6243 : // Keep the longest duration record.
6244 0 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
6245 0 : if (state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
6246 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
6247 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6248 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
6249 0 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
6250 0 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
6251 0 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
6252 : }
6253 0 : } else if (PierceSET > 30) {
6254 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6255 0 : (PierceSET - 30) * state.dataGlobal->TimeStepZone;
6256 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6257 0 : (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
6258 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6259 0 : (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6260 : // Reset duration when last step is out of range.
6261 0 : if (PierceSETLast == -1 || PierceSETLast <= 30) {
6262 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6263 0 : state.dataEnvrn->Month,
6264 0 : state.dataEnvrn->DayOfMonth,
6265 0 : state.dataGlobal->HourOfDay,
6266 0 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6267 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6268 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6269 0 : } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
6270 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6271 0 : state.dataEnvrn->Month,
6272 0 : state.dataEnvrn->DayOfMonth,
6273 0 : state.dataGlobal->HourOfDay,
6274 0 : state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
6275 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6276 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6277 : }
6278 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
6279 0 : if (state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
6280 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
6281 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6282 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
6283 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
6284 0 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
6285 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
6286 : }
6287 : }
6288 0 : if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
6289 0 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6290 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6291 : }
6292 : }
6293 :
6294 0 : if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
6295 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6296 0 : (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6297 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6298 0 : NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6299 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6300 0 : (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6301 : }
6302 0 : if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
6303 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6304 0 : (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6305 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6306 0 : NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6307 0 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[5] +=
6308 0 : (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6309 : }
6310 : }
6311 : }
6312 : } // loop over zones
6313 : }
6314 1086699 : }
6315 :
6316 19089 : void ReportCO2Resilience(EnergyPlusData &state)
6317 : {
6318 19089 : if (state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime) {
6319 672 : int NoBins = 3;
6320 4271 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6321 3602 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6322 3 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6323 3 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6324 3 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6325 : }
6326 : }
6327 672 : state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime = false;
6328 672 : if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
6329 657 : if (state.dataOutRptTab->displayCO2ResilienceSummaryExplicitly) {
6330 0 : ShowWarningError(state,
6331 : "Writing Annual CO2 Resilience Summary - CO2 Level Hours reports: "
6332 : "Zone Air CO2 Concentration output is required, "
6333 : "but no ZoneAirContaminantBalance object is defined.");
6334 : }
6335 657 : state.dataOutRptTab->displayCO2ResilienceSummary = false;
6336 657 : return;
6337 : }
6338 : }
6339 :
6340 18432 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
6341 0 : for (auto const &people : state.dataHeatBal->People) {
6342 0 : state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
6343 0 : }
6344 :
6345 0 : Array1D_bool reportPeriodFlags;
6346 0 : if (state.dataWeather->TotReportPers > 0) {
6347 0 : reportPeriodFlags.dimension(state.dataWeather->TotCO2ReportPers, false);
6348 0 : General::findReportPeriodIdx(state, state.dataWeather->CO2ReportPeriodInput, state.dataWeather->TotCO2ReportPers, reportPeriodFlags);
6349 : }
6350 :
6351 0 : auto &ort = state.dataOutRptTab;
6352 0 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6353 0 : if (reportPeriodFlags(i)) {
6354 0 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
6355 0 : state.dataWeather->CO2ReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
6356 : }
6357 : }
6358 :
6359 0 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6360 0 : Real64 ZoneAirCO2 = state.dataContaminantBalance->ZoneAirCO2Avg(ZoneNum);
6361 :
6362 0 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6363 0 : if (ZoneAirCO2 <= 1000) {
6364 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[0] += state.dataGlobal->TimeStepZone;
6365 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6366 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6367 0 : } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
6368 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[1] += state.dataGlobal->TimeStepZone;
6369 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6370 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6371 : } else {
6372 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[2] += state.dataGlobal->TimeStepZone;
6373 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6374 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6375 : }
6376 0 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6377 0 : if (reportPeriodFlags(i)) {
6378 0 : int ReportPeriodIdx = i;
6379 0 : if (ZoneAirCO2 <= 1000) {
6380 0 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6381 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6382 0 : NumOcc * state.dataGlobal->TimeStepZone;
6383 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6384 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6385 0 : } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
6386 0 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6387 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6388 0 : NumOcc * state.dataGlobal->TimeStepZone;
6389 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6390 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6391 : } else {
6392 0 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6393 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6394 0 : NumOcc * state.dataGlobal->TimeStepZone;
6395 0 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6396 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6397 : }
6398 : }
6399 : }
6400 : }
6401 0 : } // loop over zones
6402 : }
6403 :
6404 92393 : void ReportVisualResilience(EnergyPlusData &state)
6405 : {
6406 92393 : if (state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime) {
6407 672 : int NoBins = 4;
6408 4271 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6409 3602 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6410 3 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6411 3 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6412 3 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6413 : }
6414 : }
6415 672 : state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime = false;
6416 672 : if ((int)state.dataDayltg->daylightControl.size() == 0) {
6417 617 : if (state.dataOutRptTab->displayVisualResilienceSummaryExplicitly) {
6418 0 : ShowWarningError(state,
6419 : "Writing Annual Visual Resilience Summary - Lighting Level Hours reports: "
6420 : "Zone Average Daylighting Reference Point Illuminance output is required, "
6421 : "but no Daylighting Control Object is defined.");
6422 : }
6423 617 : state.dataOutRptTab->displayVisualResilienceSummary = false;
6424 617 : return;
6425 : }
6426 : }
6427 :
6428 91776 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
6429 0 : for (auto const &people : state.dataHeatBal->People) {
6430 0 : state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
6431 0 : }
6432 : // Accumulate across daylighting controls first
6433 0 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6434 0 : state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum = 0.0;
6435 : }
6436 0 : for (int daylightCtrlNum = 1; daylightCtrlNum <= (int)state.dataDayltg->daylightControl.size(); ++daylightCtrlNum) {
6437 0 : auto &thisDaylightControl = state.dataDayltg->daylightControl(daylightCtrlNum);
6438 0 : if (thisDaylightControl.PowerReductionFactor > 0) {
6439 0 : for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
6440 0 : state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum += thisDaylightControl.refPts(refPt).illumSetPoint;
6441 : }
6442 : } else {
6443 0 : for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
6444 0 : state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum +=
6445 0 : thisDaylightControl.refPts(refPt).lums[(int)DataSurfaces::Lum::Illum];
6446 : }
6447 : }
6448 : }
6449 :
6450 0 : Array1D_bool reportPeriodFlags;
6451 0 : if (state.dataWeather->TotReportPers > 0) {
6452 0 : reportPeriodFlags.dimension(state.dataWeather->TotVisualReportPers, false);
6453 0 : General::findReportPeriodIdx(
6454 0 : state, state.dataWeather->VisualReportPeriodInput, state.dataWeather->TotVisualReportPers, reportPeriodFlags);
6455 : }
6456 :
6457 0 : auto &ort = state.dataOutRptTab;
6458 0 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6459 0 : if (reportPeriodFlags(i)) {
6460 0 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
6461 0 : state.dataWeather->VisualReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
6462 : }
6463 : }
6464 :
6465 0 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6466 0 : if (state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts == 0) {
6467 0 : continue;
6468 : }
6469 : // Now divide by total reference points to get average
6470 0 : Real64 avgZoneIllum = state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum / state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts;
6471 :
6472 0 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6473 0 : if (avgZoneIllum <= 100) {
6474 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[0] += state.dataGlobal->TimeStepZone;
6475 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6476 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6477 0 : } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
6478 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[1] += state.dataGlobal->TimeStepZone;
6479 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6480 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6481 0 : } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
6482 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[2] += state.dataGlobal->TimeStepZone;
6483 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6484 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6485 : } else {
6486 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[3] += state.dataGlobal->TimeStepZone;
6487 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
6488 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6489 : }
6490 0 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6491 0 : if (reportPeriodFlags(i)) {
6492 0 : int ReportPeriodIdx = i;
6493 0 : if (avgZoneIllum <= 100) {
6494 0 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6495 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6496 0 : NumOcc * state.dataGlobal->TimeStepZone;
6497 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6498 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6499 0 : } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
6500 0 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6501 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6502 0 : NumOcc * state.dataGlobal->TimeStepZone;
6503 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6504 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6505 0 : } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
6506 0 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6507 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6508 0 : NumOcc * state.dataGlobal->TimeStepZone;
6509 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6510 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6511 : } else {
6512 0 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6513 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6514 0 : NumOcc * state.dataGlobal->TimeStepZone;
6515 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6516 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6517 : }
6518 : }
6519 : }
6520 : }
6521 0 : } // loop over zones
6522 : }
6523 :
6524 2799877 : void ReportSurfaceHeatBalance(EnergyPlusData &state)
6525 : {
6526 :
6527 : // SUBROUTINE INFORMATION:
6528 : // AUTHOR Linda Lawrie
6529 : // DATE WRITTEN Oct 2000
6530 :
6531 : // PURPOSE OF THIS SUBROUTINE:
6532 : // This subroutine puts the reporting part of the HBSurface Module in one area.
6533 :
6534 2799877 : SolarShading::ReportSurfaceShading(state);
6535 :
6536 2799877 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
6537 342 : ReportNonRepresentativeSurfaceResults(state);
6538 : }
6539 :
6540 : // Set derived surface output variables and other record keeping - after iterations are complete - all HT surfaces
6541 :
6542 : // Opaque or window surfaces
6543 22621627 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6544 39692100 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6545 19870350 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6546 19870350 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
6547 19870350 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
6548 189889131 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6549 170018781 : auto const &surface = state.dataSurface->Surface(surfNum);
6550 : // Inside Face Convection - sign convention is positive means energy going into inside face from the air.
6551 170018781 : state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) = surface.Area * state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum);
6552 170018781 : state.dataHeatBalSurf->SurfQConvInRep(surfNum) =
6553 170018781 : state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6554 :
6555 170018781 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
6556 170018781 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(surfNum) =
6557 170018781 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6558 :
6559 170018781 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) * surface.Area;
6560 170018781 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(surfNum) =
6561 170018781 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6562 :
6563 170018781 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) * surface.Area;
6564 170018781 : state.dataHeatBalSurf->SurfQRadHVACInRep(surfNum) =
6565 170018781 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6566 :
6567 170018781 : state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) * surface.Area;
6568 :
6569 170018781 : state.dataHeatBalSurf->SurfQConvOutReport(surfNum) =
6570 170018781 : state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6571 :
6572 170018781 : state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) * surface.Area;
6573 170018781 : state.dataHeatBalSurf->SurfQRadOutReport(surfNum) =
6574 170018781 : state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6575 :
6576 : // Calculate surface heat emission to the air, positive values indicates heat transfer from surface to the outside
6577 170018781 : state.dataHeatBalSurf->SurfQAirExtReport(surfNum) =
6578 170018781 : surface.Area * state.dataHeatBalSurf->SurfHAirExt(surfNum) *
6579 170018781 : (state.dataHeatBalSurf->SurfTempOut(surfNum) - state.dataSurface->SurfOutDryBulbTemp(surfNum));
6580 :
6581 : // Subtract since SurfQdotConvOutRep's convention is opposite (positive values indicate heat transfer from the outside to the surface)
6582 170018781 : state.dataHeatBalSurf->SurfQHeatEmiReport(surfNum) =
6583 170018781 : state.dataHeatBalSurf->SurfQAirExtReport(surfNum) - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum);
6584 : }
6585 19821750 : }
6586 : }
6587 :
6588 2799877 : if (state.dataOutRptTab->displayHeatEmissionsSummary) {
6589 1081995 : state.dataHeatBalSurf->SumSurfaceHeatEmission = 0.0;
6590 47580495 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
6591 46498500 : if (state.dataSurface->Surface(SurfNum).ExtBoundCond == DataSurfaces::ExternalEnvironment) {
6592 21434877 : state.dataHeatBalSurf->SumSurfaceHeatEmission +=
6593 21434877 : state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
6594 : }
6595 : }
6596 : }
6597 :
6598 : // Window surfaces
6599 22621627 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6600 39692100 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6601 19870350 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6602 19870350 : int const firstSurf = thisSpace.WindowSurfaceFirst;
6603 19870350 : int const lastSurf = thisSpace.WindowSurfaceLast;
6604 42237432 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6605 22367082 : auto const &surface = state.dataSurface->Surface(surfNum);
6606 22367082 : state.dataHeatBal->SurfWinInitialDifSolInTransReport(surfNum) =
6607 22367082 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum) * surface.Area;
6608 :
6609 : // Absorbed short wave radiation
6610 : int TotGlassLayers;
6611 22367082 : int const constrNum = state.dataSurface->SurfActiveConstruction(surfNum);
6612 22367082 : auto const &thisConstruct = state.dataConstruction->Construct(constrNum);
6613 22367082 : int const constrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(surfNum);
6614 22367082 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(surfNum);
6615 22367082 : if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::EQL) {
6616 8109 : TotGlassLayers = state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL;
6617 22358973 : } else if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::BSDF) {
6618 39540 : TotGlassLayers = thisConstruct.TotSolidLayers;
6619 22319433 : } else if (DataSurfaces::NOT_SHADED(ShadeFlag) || ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
6620 22130455 : TotGlassLayers = thisConstruct.TotGlassLayers;
6621 : } else {
6622 : // Interior, exterior or between-glass shade, screen or blind in place
6623 188978 : TotGlassLayers = state.dataConstruction->Construct(constrNumSh).TotGlassLayers;
6624 : }
6625 22367082 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) = 0.0;
6626 22367082 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = 0.0;
6627 22367082 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = 0.0;
6628 51041118 : for (int lay = 1; lay <= TotGlassLayers; ++lay) {
6629 : // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
6630 28674036 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) +=
6631 28674036 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(surfNum, lay) * surface.Area;
6632 : // Total Shortwave Radiation Absorbed on Inside of Surface[W]
6633 28674036 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
6634 : // Total Shortwave Absorbed:All solid Layers[W]
6635 28674036 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
6636 : }
6637 :
6638 : // Window heat gain/loss
6639 22367082 : if (state.dataSurface->SurfWinHeatGain(surfNum) >= 0.0) {
6640 7744835 : state.dataSurface->SurfWinHeatGainRep(surfNum) = state.dataSurface->SurfWinHeatGain(surfNum);
6641 7744835 : state.dataSurface->SurfWinHeatGainRepEnergy(surfNum) =
6642 7744835 : state.dataSurface->SurfWinHeatGainRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6643 : } else {
6644 14622247 : state.dataSurface->SurfWinHeatLossRep(surfNum) = -state.dataSurface->SurfWinHeatGain(surfNum);
6645 14622247 : state.dataSurface->SurfWinHeatLossRepEnergy(surfNum) =
6646 14622247 : state.dataSurface->SurfWinHeatLossRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6647 : }
6648 22367082 : state.dataSurface->SurfWinHeatTransferRepEnergy(surfNum) =
6649 22367082 : state.dataSurface->SurfWinHeatGain(surfNum) * state.dataGlobal->TimeStepZoneSec;
6650 22367082 : if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
6651 4050 : int pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
6652 4050 : state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatGain = state.dataSurface->SurfWinHeatGainRep(surfNum);
6653 4050 : state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatLoss = state.dataSurface->SurfWinHeatLossRep(surfNum);
6654 : }
6655 : }
6656 19821750 : }
6657 : }
6658 :
6659 2799877 : if (state.dataSurface->AnyMovableInsulation) {
6660 10122 : ReportIntMovInsInsideSurfTemp(state);
6661 : }
6662 :
6663 : // Opaque heat transfer surfaces
6664 22621627 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6665 39692100 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6666 19870350 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6667 19870350 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6668 19870350 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6669 167522049 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6670 147651699 : auto const &surface = state.dataSurface->Surface(surfNum);
6671 :
6672 147651699 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) * surface.Area;
6673 147651699 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(surfNum) =
6674 147651699 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) * state.dataGlobal->TimeStepZoneSec;
6675 :
6676 147651699 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) * surface.Area;
6677 147651699 : state.dataHeatBalSurf->SurfQRadSolarInRep(surfNum) =
6678 147651699 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6679 :
6680 147651699 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) * surface.Area;
6681 147651699 : state.dataHeatBalSurf->SurfQRadLightsInRep(surfNum) =
6682 147651699 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6683 :
6684 : // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
6685 147651699 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(surfNum) * surface.Area;
6686 : // Total Shortwave Radiation Absorbed on Inside of Surface[W]
6687 147651699 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) * surface.Area;
6688 :
6689 : // inside face conduction updates
6690 147651699 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) * surface.Area;
6691 147651699 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(surfNum) =
6692 147651699 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6693 147651699 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = 0.0;
6694 147651699 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = 0.0;
6695 147651699 : if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) >= 0.0) {
6696 71781074 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6697 : } else {
6698 75870625 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6699 : }
6700 :
6701 : // outside face conduction updates
6702 147651699 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum);
6703 147651699 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(surfNum) =
6704 147651699 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6705 147651699 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = 0.0;
6706 147651699 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = 0.0;
6707 147651699 : if (state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) >= 0.0) {
6708 90935375 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6709 : } else {
6710 56716324 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6711 : }
6712 : }
6713 167522049 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6714 : // do average surface conduction updates
6715 :
6716 147651699 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) =
6717 147651699 : (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)) / 2.0;
6718 147651699 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(surfNum) =
6719 147651699 : (state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)) / 2.0;
6720 147651699 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(surfNum) =
6721 147651699 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6722 147651699 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = 0.0;
6723 147651699 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = 0.0;
6724 147651699 : if (state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) >= 0.0) {
6725 64681931 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
6726 : } else {
6727 82969768 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
6728 : }
6729 :
6730 : // do surface storage rate updates
6731 147651699 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux(surfNum) =
6732 147651699 : -(state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum));
6733 147651699 : state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) =
6734 147651699 : -(state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum));
6735 147651699 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(surfNum) =
6736 147651699 : state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6737 147651699 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = 0.0;
6738 147651699 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = 0.0;
6739 147651699 : if (state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) >= 0.0) {
6740 63507931 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
6741 : } else {
6742 84143768 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
6743 : }
6744 : }
6745 19821750 : }
6746 : }
6747 :
6748 2799877 : if (state.dataGlobal->ZoneSizingCalc && state.dataGlobal->CompLoadReportIsReq) {
6749 : // This is by surface, so it works for both space and zone component loads
6750 73122 : int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
6751 73122 : auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
6752 674988 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6753 1236060 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6754 634194 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6755 634194 : int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6756 634194 : int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6757 5032314 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6758 4398120 : surfCLDayTS.surf[surfNum - 1].lightSWRadSeq = state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum);
6759 4398120 : surfCLDayTS.surf[surfNum - 1].feneSolarRadSeq = state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum);
6760 : }
6761 634194 : firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
6762 634194 : lastSurf = thisSpace.OpaqOrWinSurfaceLast;
6763 5588010 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6764 4953816 : auto const &surface = state.dataSurface->Surface(surfNum);
6765 4953816 : if (!state.dataGlobal->WarmupFlag) {
6766 677376 : if (state.dataGlobal->isPulseZoneSizing) {
6767 338688 : surfCLDayTS.surf[surfNum - 1].loadConvectedWithPulse = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
6768 : } else {
6769 338688 : surfCLDayTS.surf[surfNum - 1].loadConvectedNormal = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
6770 338688 : surfCLDayTS.surf[surfNum - 1].netSurfRadSeq = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
6771 : }
6772 : }
6773 : }
6774 601866 : }
6775 : }
6776 : }
6777 :
6778 2799877 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
6779 514302 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6780 777210 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6781 388605 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6782 388605 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6783 388605 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6784 3186792 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6785 2798187 : state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6786 2798187 : state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6787 : }
6788 388605 : if (state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) >= 0.0) {
6789 177218 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
6790 177218 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) =
6791 177218 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6792 : } else {
6793 211387 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
6794 211387 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) =
6795 211387 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6796 : }
6797 :
6798 388605 : if (state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) >= 0.0) {
6799 256629 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
6800 256629 : state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) =
6801 256629 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6802 : } else {
6803 131976 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
6804 131976 : state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) =
6805 131976 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6806 : }
6807 388605 : }
6808 : }
6809 : }
6810 2799877 : }
6811 :
6812 342 : void ReportNonRepresentativeSurfaceResults(EnergyPlusData &state)
6813 : {
6814 16074 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6815 31464 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6816 15732 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6817 : // Heat transfer surfaces
6818 15732 : int firstSurf = thisSpace.HTSurfaceFirst;
6819 15732 : int lastSurf = thisSpace.HTSurfaceLast;
6820 213750 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6821 198018 : auto const &surface = state.dataSurface->Surface(surfNum);
6822 198018 : int repSurfNum = surface.RepresentativeCalcSurfNum;
6823 198018 : if (surfNum != repSurfNum) {
6824 44802 : state.dataSurface->surfIntConv(surfNum).convClassRpt = state.dataSurface->surfIntConv(repSurfNum).convClassRpt;
6825 44802 : state.dataSurface->surfExtConv(surfNum).convClassRpt = state.dataSurface->surfExtConv(repSurfNum).convClassRpt;
6826 : }
6827 : }
6828 :
6829 : // Windows
6830 15732 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
6831 0 : firstSurf = thisSpace.WindowSurfaceFirst;
6832 0 : lastSurf = thisSpace.WindowSurfaceLast;
6833 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6834 0 : auto const &surface = state.dataSurface->Surface(surfNum);
6835 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
6836 0 : if (surfNum != repSurfNum) {
6837 0 : Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
6838 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
6839 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
6840 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
6841 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
6842 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
6843 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(repSurfNum) * areaRatio;
6844 : }
6845 : }
6846 : }
6847 15732 : }
6848 : }
6849 342 : }
6850 :
6851 10122 : void ReportIntMovInsInsideSurfTemp(EnergyPlusData &state)
6852 : {
6853 10122 : state.dataHeatBalSurf->SurfTempInMovInsRep = state.dataHeatBalSurf->SurfTempIn;
6854 16197 : for (int SurfNum : state.dataSurface->intMovInsulSurfNums) {
6855 6075 : if (state.dataSurface->intMovInsuls(SurfNum).present) {
6856 6075 : state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
6857 : }
6858 10122 : }
6859 10122 : }
6860 : // End of Reporting subroutines for the HB Module
6861 : // *****************************************************************************
6862 :
6863 : // *****************************************************************************
6864 : // *****************************************************************************
6865 : // *****************************************************************************
6866 : // *****************************************************************************
6867 :
6868 : // Formerly EXTERNAL SUBROUTINES (heavily related to HeatBalanceSurfaceManager) now moved into namespace
6869 :
6870 3699480 : void CalcHeatBalanceOutsideSurf(EnergyPlusData &state,
6871 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
6872 : {
6873 :
6874 : // SUBROUTINE INFORMATION:
6875 : // AUTHOR George Walton
6876 : // DATE WRITTEN December 1979
6877 : // MODIFIED Jun 1990 (RDT for new CTF arrays);
6878 : // Aug 2000 (RJL for MTF moisture calculations)
6879 : // Sep 2000 (RKS for new radiant exchange algorithm)
6880 : // Dec 2000 (RKS for radiant system model addition)
6881 : // Apr 2002 (COP removed denominator from OSC calculation
6882 : // Jul 2008 (P.Biddulph include calls to HAMT)
6883 : // Jul 2011, M.J. Witte and C.O. Pedersen, add new fields to OSC for last T, max and min
6884 : // Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
6885 : // RE-ENGINEERED Mar 1998 (RKS)
6886 :
6887 : // PURPOSE OF THIS SUBROUTINE:
6888 : // This subroutine performs a heat balance on the outside face of each
6889 : // surface in the building.
6890 :
6891 : // METHODOLOGY EMPLOYED:
6892 : // Various boundary conditions are set and additional parameters are set-
6893 : // up. Then, the proper heat balance equation is selected based on the
6894 : // presence of movable insulation, thermal mass of the surface construction,
6895 : // and convection model being used.
6896 :
6897 : // REFERENCES:
6898 : // (I)BLAST legacy routine HBOUT
6899 : // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
6900 :
6901 : // // Using/Aliasing
6902 : // using namespace DataEnvironment;
6903 : // using namespace DataHeatBalance;
6904 : // using namespace DataHeatBalSurface;
6905 : // using namespace DataSurfaces;
6906 : // using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
6907 : // using namespace Psychrometrics;
6908 : // using EcoRoofManager::CalcEcoRoof;
6909 : //
6910 : // // Locals
6911 : // // SUBROUTINE ARGUMENT DEFINITIONS:
6912 : //
6913 : //>>>>>>> origin/develop
6914 : // SUBROUTINE PARAMETER DEFINITIONS:
6915 3699480 : constexpr std::string_view RoutineNameGroundTemp("CalcHeatBalanceOutsideSurf:GroundTemp");
6916 3699480 : constexpr std::string_view RoutineNameGroundTempFC("CalcHeatBalanceOutsideSurf:GroundTempFC");
6917 3699480 : constexpr std::string_view RoutineNameOtherSideCoefNoCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefNoCalcExt");
6918 3699480 : constexpr std::string_view RoutineNameOtherSideCoefCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefCalcExt");
6919 3699480 : constexpr std::string_view RoutineNameOSCM("CalcHeatBalanceOutsideSurf:OSCM");
6920 3699480 : constexpr std::string_view RoutineNameExtEnvWetSurf("CalcHeatBalanceOutsideSurf:extEnvWetSurf");
6921 3699480 : constexpr std::string_view RoutineNameExtEnvDrySurf("CalcHeatBalanceOutsideSurf:extEnvDrySurf");
6922 3699480 : constexpr std::string_view RoutineNameNoWind("CalcHeatBalanceOutsideSurf:nowind");
6923 3699480 : constexpr std::string_view RoutineNameOther("CalcHeatBalanceOutsideSurf:interior/other");
6924 3699480 : constexpr std::string_view RoutineNameIZPart("CalcHeatBalanceOutsideSurf:IZPart");
6925 3699480 : constexpr std::string_view HBSurfManGroundHAMT("HBSurfMan:Ground:HAMT");
6926 3699480 : constexpr std::string_view HBSurfManRainHAMT("HBSurfMan:Rain:HAMT");
6927 3699480 : constexpr std::string_view HBSurfManDrySurfCondFD("HBSurfMan:DrySurf:CondFD");
6928 3699480 : constexpr std::string_view Outside("Outside");
6929 :
6930 3699480 : auto &s_mat = state.dataMaterial;
6931 :
6932 3699480 : bool MovInsulErrorFlag = false; // Movable Insulation error flag
6933 :
6934 : // set ground surfaces average temperature
6935 3699480 : GetGroundSurfacesTemperatureAverage(state);
6936 :
6937 : // set surrounding surfaces average temperature
6938 3699480 : GetSurroundingSurfacesTemperatureAverage(state);
6939 :
6940 3699480 : auto &Surface = state.dataSurface->Surface;
6941 :
6942 3699480 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
6943 23750256 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
6944 : // Need to transfer any source/sink for a surface to the local array. Note that
6945 : // the local array is flux (W/m2) while the QRadSysSource is heat transfer (W).
6946 : // This must be done at this location so that this is always updated correctly.
6947 22781150 : if (Surface(SurfNum).Area > 0.0) {
6948 22781150 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) =
6949 22781150 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
6950 : }
6951 :
6952 : // next we add source (actually a sink) from any integrated PV
6953 22781150 : if (Surface(SurfNum).Area > 0.0) {
6954 22781150 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +=
6955 22781150 : state.dataHeatBalFanSys->QPVSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
6956 : }
6957 : }
6958 : }
6959 :
6960 3699480 : if (present(ZoneToResimulate)) {
6961 1592198 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
6962 796099 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, ZoneToResimulate, Outside);
6963 : } else {
6964 5806762 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
6965 2903381 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, Outside);
6966 : }
6967 :
6968 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
6969 3712053 : for (int surfNum : state.dataSurface->allOutsideSourceSurfaceList) {
6970 12573 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) = Surface(surfNum).outsideHeatSourceTermSched->getCurrentVal();
6971 3699480 : }
6972 26701561 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
6973 46052762 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6974 23050681 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
6975 216414670 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
6976 193363989 : if (Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) {
6977 24258476 : continue;
6978 : }
6979 169105513 : if (present(ZoneToResimulate)) {
6980 18716444 : if ((zoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) {
6981 11506789 : continue; // skip surfaces that are not associated with this zone
6982 : }
6983 : }
6984 : // Interior windows in partitions use "normal" heat balance calculations
6985 : // For rest, Outside surface temp of windows not needed in Window5 calculation approach.
6986 : // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
6987 :
6988 : // Initializations for this surface
6989 157598724 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
6990 157598724 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
6991 157598724 : Real64 HMovInsul = 0.0; // "Convection" coefficient of movable insulation
6992 157598724 : Real64 HSky = 0.0; // "Convection" coefficient from sky to surface
6993 157598724 : Real64 HGround = 0.0; // "Convection" coefficient from ground to surface
6994 157598724 : Real64 HAir = 0.0; // "Convection" coefficient from air to surface (radiation)
6995 157598724 : Real64 HSurrr = 0.0; // "Linearized radiation" coefficient from surrounding surfaces to surface
6996 157598724 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
6997 157598724 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
6998 157598724 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
6999 157598724 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
7000 157598724 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = 0.0;
7001 157598724 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) = 0.0;
7002 :
7003 : // Calculate the current outside surface temperature TH(SurfNum,1,1) for the
7004 : // various different boundary conditions
7005 157598724 : switch (Surface(SurfNum).ExtBoundCond) {
7006 9641561 : case DataSurfaces::Ground: { // Surface in contact with ground
7007 9641561 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
7008 9641561 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
7009 :
7010 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7011 9641561 : if (thisConstruct.SourceSinkPresent) {
7012 1374580 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7013 : }
7014 :
7015 : // start HAMT
7016 9641561 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7017 : // Set variables used in the HAMT moisture balance
7018 26913 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7019 26913 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
7020 26913 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
7021 26913 : state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0, HBSurfManGroundHAMT);
7022 26913 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7023 :
7024 26913 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7025 26913 : state.dataMstBal->HConvExtFD(SurfNum) /
7026 80739 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7027 : state,
7028 26913 : state.dataEnvrn->OutBaroPress,
7029 26913 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7030 : Psychrometrics::PsyWFnTdbRhPb(state,
7031 26913 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7032 : 1.0,
7033 26913 : state.dataEnvrn->OutBaroPress,
7034 26913 : RoutineNameGroundTemp)) +
7035 53826 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7036 26913 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7037 :
7038 26913 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7039 26913 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7040 26913 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7041 : }
7042 : // end HAMT
7043 :
7044 9641561 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7045 : // Set variables used in the FD moisture balance
7046 415748 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7047 415748 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
7048 415748 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
7049 415748 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0);
7050 415748 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7051 415748 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7052 415748 : state.dataMstBal->HConvExtFD(SurfNum) /
7053 1247244 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7054 : state,
7055 415748 : state.dataEnvrn->OutBaroPress,
7056 415748 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7057 : Psychrometrics::PsyWFnTdbRhPb(state,
7058 415748 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7059 : 1.0,
7060 415748 : state.dataEnvrn->OutBaroPress,
7061 415748 : RoutineNameGroundTemp)) +
7062 831496 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7063 415748 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7064 415748 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7065 415748 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7066 415748 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7067 : }
7068 : // Added for FCfactor grounds
7069 9641561 : } break;
7070 554427 : case DataSurfaces::GroundFCfactorMethod: { // Surface in contact with ground
7071 554427 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
7072 554427 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
7073 :
7074 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7075 554427 : if (thisConstruct.SourceSinkPresent) {
7076 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7077 : }
7078 :
7079 554427 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7080 : // Set variables used in the HAMT moisture balance
7081 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7082 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
7083 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
7084 0 : state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0, HBSurfManGroundHAMT);
7085 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7086 :
7087 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7088 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7089 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7090 : state,
7091 0 : state.dataEnvrn->OutBaroPress,
7092 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7093 : Psychrometrics::PsyWFnTdbRhPb(state,
7094 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7095 : 1.0,
7096 0 : state.dataEnvrn->OutBaroPress,
7097 0 : RoutineNameGroundTempFC)) +
7098 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7099 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7100 :
7101 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7102 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7103 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7104 : }
7105 :
7106 554427 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7107 : // Set variables used in the FD moisture balance
7108 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7109 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
7110 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
7111 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0);
7112 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7113 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7114 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7115 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7116 : state,
7117 0 : state.dataEnvrn->OutBaroPress,
7118 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7119 : Psychrometrics::PsyWFnTdbRhPb(state,
7120 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7121 : 1.0,
7122 0 : state.dataEnvrn->OutBaroPress,
7123 0 : RoutineNameGroundTempFC)) +
7124 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7125 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7126 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7127 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7128 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7129 : }
7130 554427 : } break;
7131 74661 : case DataSurfaces::OtherSideCoefNoCalcExt: {
7132 : // Use Other Side Coefficients to determine the surface film coefficient and
7133 : // the exterior boundary condition temperature
7134 :
7135 74661 : int OPtr = Surface(SurfNum).OSCPtr;
7136 : // Set surface temp from previous timestep
7137 74661 : if (state.dataGlobal->BeginTimeStepFlag) {
7138 74423 : state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7139 : }
7140 :
7141 74661 : if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
7142 67137 : state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
7143 : }
7144 :
7145 : // Allow for modification of TemperatureCoefficient with unitary sine wave.
7146 : Real64 ConstantTempCoef; // Temperature Coefficient as input or modified using sine wave COP mod
7147 74661 : if (state.dataSurface->OSC(OPtr).SinusoidalConstTempCoef) { // Sine wave C4
7148 3465 : ConstantTempCoef = std::sin(2 * Constant::Pi * state.dataGlobal->CurrentTime / state.dataSurface->OSC(OPtr).SinusoidPeriod);
7149 : } else {
7150 71196 : ConstantTempCoef = state.dataSurface->OSC(OPtr).ConstTempCoef;
7151 : }
7152 :
7153 74661 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7154 74661 : (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
7155 74661 : state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7156 74661 : ConstantTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
7157 74661 : state.dataSurface->OSC(OPtr).GroundTempCoef *
7158 74661 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
7159 74661 : state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
7160 74661 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7161 74661 : state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
7162 :
7163 : // Enforce max/min limits if applicable
7164 74661 : if (state.dataSurface->OSC(OPtr).MinLimitPresent) {
7165 33255 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7166 33255 : max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7167 : }
7168 74661 : if (state.dataSurface->OSC(OPtr).MaxLimitPresent) {
7169 33255 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7170 33255 : min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7171 : }
7172 :
7173 74661 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataSurface->OSC(OPtr).OSCTempCalc;
7174 :
7175 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7176 74661 : if (thisConstruct.SourceSinkPresent) {
7177 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7178 : }
7179 :
7180 149322 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7181 74661 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7182 : // Set variables used in the FD moisture balance and HAMT
7183 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7184 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7185 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7186 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7187 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7188 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7189 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7190 0 : state.dataEnvrn->OutBaroPress,
7191 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7192 : Psychrometrics::PsyWFnTdbRhPb(state,
7193 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7194 : 1.0,
7195 0 : state.dataEnvrn->OutBaroPress,
7196 0 : RoutineNameOtherSideCoefNoCalcExt)) +
7197 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7198 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7199 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7200 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7201 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7202 : }
7203 : // This ends the calculations for this surface and goes on to the next SurfNum
7204 74661 : } break;
7205 1353 : case DataSurfaces::OtherSideCoefCalcExt: { // A surface with other side coefficients that define the outside environment
7206 : // First, set up the outside convection coefficient and the exterior temperature
7207 : // boundary condition for the surface
7208 1353 : int OPtr = Surface(SurfNum).OSCPtr;
7209 : // Set surface temp from previous timestep
7210 1353 : if (state.dataGlobal->BeginTimeStepFlag) {
7211 1347 : state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7212 : }
7213 :
7214 1353 : if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
7215 0 : state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
7216 : }
7217 :
7218 1353 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSC(OPtr).SurfFilmCoef;
7219 :
7220 1353 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7221 1353 : (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
7222 1353 : state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7223 1353 : state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
7224 1353 : state.dataSurface->OSC(OPtr).GroundTempCoef *
7225 1353 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
7226 1353 : state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
7227 1353 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7228 1353 : state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
7229 :
7230 : // Enforce max/min limits if applicable
7231 1353 : if (state.dataSurface->OSC(OPtr).MinLimitPresent) {
7232 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7233 0 : max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7234 : }
7235 1353 : if (state.dataSurface->OSC(OPtr).MaxLimitPresent) {
7236 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7237 0 : min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7238 : }
7239 :
7240 1353 : Real64 TempExt = state.dataSurface->OSC(OPtr).OSCTempCalc;
7241 :
7242 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7243 1353 : if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) {
7244 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7245 : }
7246 :
7247 2706 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7248 1353 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7249 : // Set variables used in the FD moisture balance and HAMT
7250 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7251 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7252 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7253 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7254 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7255 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7256 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7257 0 : state.dataEnvrn->OutBaroPress,
7258 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7259 : Psychrometrics::PsyWFnTdbRhPb(state,
7260 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7261 : 1.0,
7262 0 : state.dataEnvrn->OutBaroPress,
7263 0 : RoutineNameOtherSideCoefCalcExt)) +
7264 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7265 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7266 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7267 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7268 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7269 : }
7270 :
7271 : // Call the outside surface temp calculation and pass the necessary terms
7272 1353 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7273 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7274 1353 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7275 1353 : if (MovInsulErrorFlag) {
7276 0 : ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7277 : }
7278 : }
7279 : // This ends the calculations for this surface and goes on to the next SurfNum
7280 1353 : } break;
7281 211815 : case DataSurfaces::OtherSideCondModeledExt: { // A surface with other side conditions determined from separate, dynamic component
7282 : // modeling that defines the "outside environment"
7283 : // First, set up the outside convection coefficient and the exterior temperature
7284 : // boundary condition for the surface
7285 211815 : int OPtr = Surface(SurfNum).OSCMPtr;
7286 : // EMS overrides
7287 211815 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTConv) {
7288 0 : state.dataSurface->OSCM(OPtr).TConv = state.dataSurface->OSCM(OPtr).EMSOverrideTConvValue;
7289 : }
7290 211815 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHConv) {
7291 0 : state.dataSurface->OSCM(OPtr).HConv = state.dataSurface->OSCM(OPtr).EMSOverrideHConvValue;
7292 : }
7293 211815 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTRad) {
7294 0 : state.dataSurface->OSCM(OPtr).TRad = state.dataSurface->OSCM(OPtr).EMSOverrideTRadValue;
7295 : }
7296 211815 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHrad) {
7297 0 : state.dataSurface->OSCM(OPtr).HRad = state.dataSurface->OSCM(OPtr).EMSOverrideHradValue;
7298 : }
7299 211815 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSCM(OPtr).HConv;
7300 :
7301 211815 : Real64 TempExt = state.dataSurface->OSCM(OPtr).TConv;
7302 :
7303 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7304 211815 : if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) {
7305 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7306 : }
7307 :
7308 423630 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7309 211815 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7310 : // Set variables used in the FD moisture balance and HAMT
7311 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7312 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7313 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7314 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7315 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7316 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7317 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7318 : state,
7319 0 : state.dataEnvrn->OutBaroPress,
7320 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7321 : Psychrometrics::PsyWFnTdbRhPb(
7322 0 : state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOSCM)) +
7323 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7324 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7325 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataSurface->OSCM(OPtr).HRad; // CR 8046, use sky term for surface to baffle IR
7326 0 : state.dataMstBal->HGrndFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
7327 0 : state.dataMstBal->HAirFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
7328 : }
7329 :
7330 : // Call the outside surface temp calculation and pass the necessary terms
7331 211815 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7332 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7333 :
7334 211815 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
7335 8124 : CalcExteriorVentedCavity(state, SurfNum);
7336 : }
7337 :
7338 211815 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7339 211815 : if (MovInsulErrorFlag) {
7340 0 : ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7341 : }
7342 :
7343 0 : } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7344 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7345 0 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
7346 0 : CalcExteriorVentedCavity(state, SurfNum);
7347 : }
7348 : }
7349 : // This ends the calculations for this surface and goes on to the next SurfNum
7350 211815 : } break;
7351 45311249 : case DataSurfaces::ExternalEnvironment: {
7352 : // checking the EcoRoof presented in the external environment
7353 : // recompute each load by calling ecoroof
7354 :
7355 : Real64 TempExt;
7356 :
7357 45311249 : if (state.dataSurface->SurfExtEcoRoof(SurfNum)) {
7358 443820 : EcoRoofManager::CalcEcoRoof(state, SurfNum, ConstrNum, TempExt);
7359 443820 : continue;
7360 : }
7361 : // Roughness index of the exterior surface
7362 44867429 : Material::SurfaceRoughness RoughSurf = state.dataHeatBalSurf->SurfRoughnessExt(SurfNum);
7363 : // Thermal absorptance of the exterior surface
7364 44867429 : Real64 AbsThermSurf = state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum);
7365 44867429 : HMovInsul = 0;
7366 : // Check for outside movable insulation
7367 44867429 : if (state.dataSurface->AnyMovableInsulation && state.dataSurface->extMovInsuls(SurfNum).present) {
7368 4047 : HMovInsul = state.dataSurface->extMovInsuls(SurfNum).H;
7369 : }
7370 :
7371 : // Check for exposure to wind (exterior environment)
7372 44867429 : if (Surface(SurfNum).ExtWind) {
7373 :
7374 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine)
7375 44690612 : Convect::InitExtConvCoeff(state,
7376 : SurfNum,
7377 : HMovInsul,
7378 : RoughSurf,
7379 : AbsThermSurf,
7380 44690612 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7381 44690612 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7382 44690612 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7383 44690612 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7384 44690612 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7385 44690612 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7386 :
7387 44690612 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside surface gets wet
7388 :
7389 11907 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum == 0) { // Reset SurfHcExt because of wetness
7390 11907 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0;
7391 : } else { // User set
7392 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
7393 : }
7394 :
7395 11907 : TempExt = state.dataSurface->SurfOutWetBulbTemp(SurfNum);
7396 :
7397 : // start HAMT
7398 11907 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7399 : // Set variables used in the HAMT moisture balance
7400 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7401 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) =
7402 0 : Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManRainHAMT);
7403 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7404 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7405 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7406 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7407 0 : state.dataEnvrn->OutBaroPress,
7408 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7409 : Psychrometrics::PsyWFnTdbRhPb(state,
7410 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7411 : 1.0,
7412 0 : state.dataEnvrn->OutBaroPress,
7413 0 : RoutineNameExtEnvWetSurf)) +
7414 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7415 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7416 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7417 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7418 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7419 : }
7420 : // end HAMT
7421 11907 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7422 : // Set variables used in the FD moisture balance
7423 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7424 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) =
7425 0 : Psychrometrics::PsyRhovFnTdbRhLBnd0C(state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0);
7426 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7427 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7428 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7429 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7430 0 : state.dataEnvrn->OutBaroPress,
7431 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7432 : Psychrometrics::PsyWFnTdbRhPb(state,
7433 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7434 : 1.0,
7435 0 : state.dataEnvrn->OutBaroPress,
7436 0 : RoutineNameExtEnvWetSurf)) +
7437 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7438 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7439 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7440 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7441 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7442 0 : state.dataMstBal->HSurrFD(SurfNum) = state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum);
7443 : }
7444 :
7445 : } else { // Surface is dry, use the normal correlation
7446 :
7447 44678705 : TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
7448 :
7449 87469528 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7450 42790823 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7451 : // Set variables used in the FD moisture balance and HAMT
7452 2032533 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7453 2032533 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7454 2032533 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7455 2032533 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7456 2032533 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7457 2032533 : state.dataMstBal->HConvExtFD(SurfNum) /
7458 4065066 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7459 2032533 : state.dataEnvrn->OutBaroPress,
7460 2032533 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7461 : Psychrometrics::PsyWFnTdbRhPb(state,
7462 2032533 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7463 : 1.0,
7464 2032533 : state.dataEnvrn->OutBaroPress,
7465 2032533 : RoutineNameExtEnvDrySurf)) +
7466 4065066 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7467 2032533 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7468 : // check for saturation conditions of air
7469 : // Local temporary saturated vapor density for checking
7470 : Real64 RhoVaporSat =
7471 2032533 : Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManDrySurfCondFD);
7472 2032533 : if (state.dataMstBal->RhoVaporAirOut(SurfNum) > RhoVaporSat) {
7473 1103097 : state.dataMstBal->RhoVaporAirOut(SurfNum) = RhoVaporSat;
7474 : }
7475 2032533 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7476 2032533 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7477 2032533 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7478 2032533 : state.dataMstBal->HSurrFD(SurfNum) = state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum);
7479 : }
7480 : }
7481 :
7482 : } else { // No wind
7483 :
7484 : // Calculate exterior heat transfer coefficients for windspeed = 0
7485 176817 : Convect::InitExtConvCoeff(state,
7486 : SurfNum,
7487 : HMovInsul,
7488 : RoughSurf,
7489 : AbsThermSurf,
7490 176817 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7491 176817 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7492 176817 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7493 176817 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7494 176817 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7495 176817 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7496 :
7497 176817 : TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
7498 :
7499 346908 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7500 170091 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7501 : // Set variables used in the FD moisture balance and HAMT
7502 6726 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7503 6726 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7504 6726 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7505 6726 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7506 6726 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7507 6726 : state.dataMstBal->HConvExtFD(SurfNum) /
7508 13452 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7509 6726 : state.dataEnvrn->OutBaroPress,
7510 6726 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7511 : Psychrometrics::PsyWFnTdbRhPb(state,
7512 6726 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7513 : 1.0,
7514 6726 : state.dataEnvrn->OutBaroPress,
7515 6726 : RoutineNameNoWind)) +
7516 13452 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7517 6726 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7518 6726 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7519 6726 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7520 6726 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7521 6726 : state.dataMstBal->HSurrFD(SurfNum) = state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum);
7522 : }
7523 : }
7524 : // Calculate LWR from surrounding surfaces if defined for an exterior surface
7525 44867429 : if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
7526 5412 : int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
7527 : // Absolute temperature of the outside surface of an exterior surface
7528 5412 : Real64 TSurf = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) + Constant::Kelvin;
7529 13530 : for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface;
7530 : SrdSurfNum++) {
7531 : // View factor of a surrounding surface
7532 8118 : Real64 SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor;
7533 : // Absolute temperature of a surrounding surface
7534 : Real64 SrdSurfTempAbs =
7535 8118 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() +
7536 8118 : Constant::Kelvin;
7537 8118 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) +=
7538 8118 : Constant::StefanBoltzmann * AbsThermSurf * SrdSurfViewFac * (pow_4(SrdSurfTempAbs) - pow_4(TSurf));
7539 : }
7540 : }
7541 :
7542 44867429 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7543 46910738 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD ||
7544 2043309 : Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
7545 42828170 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7546 42828170 : if (MovInsulErrorFlag) {
7547 0 : ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7548 : }
7549 : }
7550 44867429 : } break;
7551 :
7552 118260 : case DataSurfaces::KivaFoundation: {
7553 118260 : auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
7554 118260 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness;
7555 118260 : Real64 AbsThermSurf = thisMaterial->AbsorpThermal;
7556 :
7557 : // Set Kiva exterior convection algorithms
7558 118260 : Convect::InitExtConvCoeff(state,
7559 : SurfNum,
7560 : HMovInsul,
7561 : RoughSurf,
7562 : AbsThermSurf,
7563 118260 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7564 118260 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7565 118260 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7566 118260 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7567 118260 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7568 118260 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7569 118260 : } break;
7570 :
7571 101685398 : default: { // for interior or other zone surfaces
7572 :
7573 101685398 : if (Surface(SurfNum).ExtBoundCond == SurfNum) { // Regular partition/internal mass
7574 :
7575 31831518 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
7576 :
7577 : // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
7578 :
7579 63517968 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7580 31686450 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7581 : // Set variables used in the FD moisture balance HAMT
7582 145068 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
7583 145068 : state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(SurfNum);
7584 145068 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
7585 145068 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7586 145068 : state.dataMstBal->HConvExtFD(SurfNum) /
7587 290136 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7588 : state,
7589 145068 : state.dataEnvrn->OutBaroPress,
7590 145068 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7591 : Psychrometrics::PsyWFnTdbRhPb(
7592 145068 : state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOther)) +
7593 290136 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7594 145068 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7595 145068 : state.dataMstBal->HSkyFD(SurfNum) = 0.0;
7596 145068 : state.dataMstBal->HGrndFD(SurfNum) = 0.0;
7597 145068 : state.dataMstBal->HAirFD(SurfNum) = 0.0;
7598 145068 : state.dataMstBal->HSurrFD(SurfNum) = 0.0;
7599 : }
7600 :
7601 : } else { // Interzone partition
7602 :
7603 69853880 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
7604 69853880 : state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
7605 :
7606 : // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
7607 :
7608 138564488 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7609 68710608 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7610 : // Set variables used in the FD moisture balance and HAMT
7611 1143272 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
7612 1143272 : state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(Surface(SurfNum).ExtBoundCond);
7613 1143272 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(Surface(SurfNum).ExtBoundCond);
7614 1143272 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7615 1143272 : state.dataMstBal->HConvExtFD(SurfNum) /
7616 2286544 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7617 1143272 : state.dataEnvrn->OutBaroPress,
7618 1143272 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7619 : Psychrometrics::PsyWFnTdbRhPb(state,
7620 1143272 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7621 : 1.0,
7622 1143272 : state.dataEnvrn->OutBaroPress,
7623 1143272 : RoutineNameIZPart)) +
7624 2286544 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7625 1143272 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7626 1143272 : state.dataMstBal->HSkyFD(SurfNum) = 0.0;
7627 1143272 : state.dataMstBal->HGrndFD(SurfNum) = 0.0;
7628 1143272 : state.dataMstBal->HAirFD(SurfNum) = 0.0;
7629 1143272 : state.dataMstBal->HSurrFD(SurfNum) = 0.0;
7630 : }
7631 : }
7632 : // This ends the calculations for this surface and goes on to the next SurfNum
7633 101685398 : } break;
7634 : }
7635 :
7636 157154904 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = GetQdotConvOutPerArea(state, SurfNum);
7637 : }
7638 23002081 : }
7639 : } // ...end of DO loop over all surface (actually heat transfer surfaces)
7640 3699480 : }
7641 :
7642 157154904 : Real64 GetQdotConvOutPerArea(EnergyPlusData &state, int const SurfNum)
7643 : {
7644 157154904 : auto const &surface = state.dataSurface->Surface(SurfNum);
7645 157154904 : int OPtr = surface.OSCMPtr;
7646 157154904 : if (surface.OSCMPtr > 0) { // Optr is set above in this case, use OSCM boundary data
7647 211815 : return -state.dataSurface->OSCM(OPtr).HConv * (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->OSCM(OPtr).TConv);
7648 : } else {
7649 156943089 : if (state.dataEnvrn->IsRain) {
7650 43093 : return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
7651 43093 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutWetBulbTemp(SurfNum));
7652 : } else {
7653 156899996 : return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
7654 156899996 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutDryBulbTemp(SurfNum));
7655 : }
7656 : }
7657 : }
7658 :
7659 3732214 : void CalcHeatBalanceInsideSurf(EnergyPlusData &state,
7660 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
7661 : {
7662 3732214 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime) {
7663 803 : if (state.dataHeatBal->AnyEMPD) {
7664 2 : state.dataHeatBalSurf->MinIterations = DataHeatBalSurface::MinEMPDIterations;
7665 : }
7666 803 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
7667 66 : SetupOutputVariable(state,
7668 : "Surface Inside Face Heat Balance Calculation Iteration Count",
7669 : Constant::Units::None,
7670 22 : state.dataHeatBal->InsideSurfIterations,
7671 : OutputProcessor::TimeStepType::Zone,
7672 : OutputProcessor::StoreType::Sum,
7673 : "Simulation");
7674 : }
7675 : // Precompute whether CTF temperature limits will be needed
7676 803 : state.dataHeatBalSurf->Zone_has_mixed_HT_models.resize(state.dataGlobal->NumOfZones + 1, false);
7677 6010 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
7678 10426 : for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
7679 5219 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
7680 50533 : for (int iSurf = thisSpace.HTSurfaceFirst, eSurf = thisSpace.HTSurfaceLast; iSurf <= eSurf; ++iSurf) {
7681 45362 : DataSurfaces::HeatTransferModel const alg = state.dataSurface->Surface(iSurf).HeatTransferAlgorithm;
7682 45362 : if ((alg == DataSurfaces::HeatTransferModel::CondFD) || (alg == DataSurfaces::HeatTransferModel::HAMT) ||
7683 : (alg == DataSurfaces::HeatTransferModel::Kiva)) {
7684 48 : state.dataHeatBalSurf->Zone_has_mixed_HT_models[iZone] = true;
7685 48 : break;
7686 : }
7687 : }
7688 5207 : }
7689 : }
7690 803 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime = false;
7691 : }
7692 :
7693 3732214 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag) {
7694 6396 : state.dataHeatBalSurf->SurfTempInsOld = 23.0;
7695 6396 : state.dataHeatBalSurfMgr->RefAirTemp = 23.0;
7696 6396 : state.dataHeatBal->SurfTempEffBulkAir = 23.0;
7697 6396 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount = 0;
7698 6396 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = false;
7699 :
7700 : // Initialize Kiva instances ground temperatures
7701 6396 : if (state.dataHeatBal->AnyKiva) {
7702 63 : state.dataSurfaceGeometry->kivaManager.initKivaInstances(state);
7703 : }
7704 : }
7705 3732214 : if (!state.dataGlobal->BeginEnvrnFlag) {
7706 3723319 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = true;
7707 : }
7708 :
7709 3732214 : sumSurfQdotRadHVAC(state);
7710 :
7711 : // Pass correct list of surfaces to CalcHeatBalanceInsideSurf2
7712 3732214 : bool const PartialResimulate(present(ZoneToResimulate));
7713 :
7714 3732214 : if (!PartialResimulate) {
7715 2936115 : if (state.dataHeatBal->AllCTF) {
7716 2693116 : CalcHeatBalanceInsideSurf2CTFOnly(state, 1, state.dataGlobal->NumOfZones, state.dataSurface->AllIZSurfaceList);
7717 : } else {
7718 485998 : CalcHeatBalanceInsideSurf2(state,
7719 242999 : state.dataSurface->AllHTSurfaceList,
7720 242999 : state.dataSurface->AllIZSurfaceList,
7721 242999 : state.dataSurface->AllHTNonWindowSurfaceList,
7722 242999 : state.dataSurface->AllHTWindowSurfaceList);
7723 : }
7724 : } else {
7725 796099 : auto const &zoneHTSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTSurfaceList;
7726 796099 : auto const &zoneIZSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneIZSurfaceList;
7727 796099 : auto const &zoneHTNonWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTNonWindowSurfaceList;
7728 796099 : auto const &zoneHTWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTWindowSurfaceList;
7729 : // Cannot use CalcHeatBalanceInsideSurf2CTFOnly because resimulated zone includes adjacent interzone surfaces
7730 796099 : CalcHeatBalanceInsideSurf2(state, zoneHTSurfList, zoneIZSurfList, zoneHTNonWindowSurfList, zoneHTWindowSurfList, ZoneToResimulate);
7731 : }
7732 3732214 : CalculateZoneMRT(state, ZoneToResimulate); // Update here so that the proper value of MRT is available to radiant systems
7733 3732214 : UpdateIntermediateSurfaceHeatBalanceResults(state, ZoneToResimulate);
7734 3732214 : }
7735 :
7736 1039098 : void CalcHeatBalanceInsideSurf2(EnergyPlusData &state,
7737 : const std::vector<int> &HTSurfs, // Heat transfer surfaces to simulate (opaque and windows)
7738 : const std::vector<int> &IZSurfs, // Interzone heat transfer surfaces to simulate
7739 : const std::vector<int> &HTNonWindowSurfs, // Non-window heat transfer surfaces to simulate
7740 : const std::vector<int> &HTWindowSurfs, // Window heat transfer surfaces to simulate
7741 : ObjexxFCL::Optional_int_const ZoneToResimulate)
7742 : {
7743 : // SUBROUTINE INFORMATION:
7744 : // AUTHOR George Walton
7745 : // DATE WRITTEN December 1979
7746 : // MODIFIED Jun 1990 (RDT for new CTF arrays)
7747 : // Dec 1999 (FCW for window calculation)
7748 : // May 2000 (FCW for window frame and dividers)
7749 : // Aug 2000 (RJL for MTF moisture calculations)
7750 : // Sep 2000 (RKS for new radiant exchange algorithm)
7751 : // Dec 2000 (RKS for radiant system model addition)
7752 : // Jul 2003 (CC) set the reference temperatures for inside surface heat balance
7753 : // depending on convection algorithms and/or air models used
7754 : // May 2006 (RR account for exterior window screen)
7755 : // Jul 2008 (P. Biddulph include calls to HAMT)
7756 : // Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
7757 : // RE-ENGINEERED Mar 1998 (RKS)
7758 :
7759 : // PURPOSE OF THIS SUBROUTINE:
7760 : // This subroutine performs a heat balance on the inside face of each
7761 : // surface in the building.
7762 :
7763 : // METHODOLOGY EMPLOYED:
7764 : // Various boundary conditions are set and additional parameters are set-
7765 : // up. Then, the proper heat balance equation is selected based on whether
7766 : // the surface is a partition or not and on whether or not movable
7767 : // insulation is present on the inside face.
7768 :
7769 : // REFERENCES:
7770 : // (I)BLAST legacy routine HBSRF
7771 :
7772 1039098 : constexpr std::string_view rhoAirZone("RhoAirZone");
7773 1039098 : constexpr std::string_view wsurf("Wsurf");
7774 1039098 : constexpr std::string_view HBSurfManInsideSurf("HB,SurfMan:InsideSurf");
7775 1039098 : constexpr std::string_view Inside("Inside");
7776 :
7777 : Real64 TempSurfOutTmp; // Local Temporary Surface temperature for the outside surface face
7778 : Real64 SurfTempInSat; // Local temporary surface dew point temperature
7779 :
7780 : Real64 Wsurf; // Moisture ratio for HAMT
7781 : Real64 RhoAirZone; // Zone moisture density for HAMT
7782 : int OtherSideZoneNum; // Zone Number index for other side of an interzone partition HAMT
7783 :
7784 1039098 : auto &s_mat = state.dataMaterial;
7785 : // determine reference air temperatures
7786 13649562 : for (int SurfNum : HTSurfs) {
7787 :
7788 : // These conditions are not used in every SurfNum loop here so we don't use them to skip surfaces
7789 12610464 : if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
7790 0 : continue; // Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.
7791 : }
7792 12610464 : Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum);
7793 12610464 : state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) = RefAirTemp;
7794 12610464 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataHeatBalSurfMgr->RefAirTemp(SurfNum);
7795 1039098 : }
7796 :
7797 : // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
7798 : // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
7799 : // CalcWindowHeatBalance.
7800 : // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
7801 1963423 : for (int surfNum : HTWindowSurfs) {
7802 924325 : state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
7803 924325 : state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
7804 924325 : state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
7805 924325 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
7806 924325 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
7807 924325 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
7808 924325 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
7809 924325 : state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
7810 924325 : state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
7811 924325 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
7812 924325 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
7813 924325 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
7814 924325 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
7815 1039098 : }
7816 :
7817 1039098 : state.dataHeatBal->InsideSurfIterations = 0;
7818 :
7819 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
7820 1039098 : for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
7821 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
7822 0 : state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
7823 1039098 : }
7824 :
7825 : // Calculate Kiva instances
7826 1039098 : if (state.dataHeatBal->AnyKiva) {
7827 30738 : if (((state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::HOURLY &&
7828 21897 : state.dataGlobal->TimeStep == 1) ||
7829 61476 : state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::TIMESTEP) &&
7830 13063 : !state.dataGlobal->WarmupFlag) {
7831 9336 : state.dataSurfaceGeometry->kivaManager.calcKivaInstances(state);
7832 : }
7833 : }
7834 :
7835 1039098 : bool Converged = false; // .TRUE. if inside heat balance has converged
7836 4133103 : while (!Converged) { // Start of main inside heat balance DO loop...
7837 :
7838 3094005 : state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
7839 :
7840 3094005 : if (state.dataHeatBal->AnyKiva) {
7841 865799 : for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
7842 663220 : state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = kivaSurf.second.results.Trad - Constant::Kelvin;
7843 202579 : }
7844 : }
7845 :
7846 6188010 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
7847 3094005 : state.dataHeatBalSurf->SurfTempIn,
7848 3094005 : state.dataHeatBal->InsideSurfIterations,
7849 3094005 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
7850 : ZoneToResimulate,
7851 : Inside); // Update the radiation balance
7852 :
7853 3094005 : if (state.dataHeatBal->AnyKiva) {
7854 865799 : for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
7855 663220 : state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = state.dataHeatBalSurf->SurfTempInsOld(kivaSurf.first);
7856 202579 : }
7857 : }
7858 :
7859 : // Every 30 iterations, recalculate the inside convection coefficients in case
7860 : // there has been a significant drift in the surface temperatures predicted.
7861 : // This is not fool-proof and it basically means that the outside surface
7862 : // heat balance is in error (potentially) once HConvIn is re-evaluated.
7863 : // The choice of 30 is not significant--just want to do this a couple of
7864 : // times before the iteration limit is hit.
7865 5148912 : if ((state.dataHeatBal->InsideSurfIterations > 0) &&
7866 2054907 : (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
7867 67 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
7868 : }
7869 :
7870 3094005 : if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
7871 1437866 : for (int SurfNum : HTSurfs) {
7872 1330236 : auto const &surface = state.dataSurface->Surface(SurfNum);
7873 1330236 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
7874 0 : continue; // Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.
7875 : }
7876 :
7877 : // Calculate the inside surface moisture quantities
7878 : // calculate the inside surface moisture transfer conditions
7879 : // check for saturation conditions of air
7880 1330236 : if ((surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) ||
7881 626657 : (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)) {
7882 1056940 : int ZoneNum = surface.Zone;
7883 1056940 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
7884 1056940 : Real64 const ZoneAirHumRat_zone(max(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRat, 1.0e-5));
7885 1056940 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
7886 :
7887 1056940 : state.dataMstBal->RhoVaporAirIn(SurfNum) =
7888 1056940 : min(Psychrometrics::PsyRhovFnTdbWPb_fast(MAT_zone, ZoneAirHumRat_zone, state.dataEnvrn->OutBaroPress),
7889 : Psychrometrics::PsyRhovFnTdbRh(state, MAT_zone, 1.0, HBSurfManInsideSurf));
7890 1056940 : state.dataMstBal->HMassConvInFD(SurfNum) =
7891 2113880 : HConvIn_surf / (Psychrometrics::PsyRhoAirFnPbTdbW_fast(state, state.dataEnvrn->OutBaroPress, MAT_zone, ZoneAirHumRat_zone) *
7892 1056940 : Psychrometrics::PsyCpAirFnW_fast(ZoneAirHumRat_zone));
7893 : }
7894 107630 : }
7895 : }
7896 :
7897 43739600 : for (int SurfNum : HTNonWindowSurfs) {
7898 : // Perform heat balance on the inside face of the surface ...
7899 : // The following are possibilities here:
7900 : // (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
7901 : // (b) the surface is a partition, in which case the temperature of both sides are the same
7902 : // (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
7903 : // (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
7904 : // (e) standard opaque surface with movable insulation, special two-part equation
7905 : // In the surface calculation there are the following Algorithm types for opaque surfaces that
7906 : // do not have movable insulation:
7907 : // (a) the regular CTF calc (SolutionAlgo = UseCTF)
7908 : // (b) the EMPD calc (Solutionalgo = UseEMPD)
7909 : // (c) the CondFD calc (SolutionAlgo = UseCondFD)
7910 : // (d) the HAMT calc (solutionalgo = UseHAMT).
7911 :
7912 40645595 : auto const &surface = state.dataSurface->Surface(SurfNum);
7913 40645595 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
7914 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
7915 0 : if (SurfNum != repSurfNum) {
7916 0 : continue;
7917 : }
7918 : }
7919 40645595 : int const ZoneNum = surface.Zone;
7920 40645595 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7921 40645595 : int const ConstrNum = surface.Construction;
7922 40645595 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
7923 40645595 : Real64 const MAT_zone = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
7924 40645595 : Real64 const HConvIn_surf = state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
7925 :
7926 40645595 : if (surface.ExtBoundCond == SurfNum) {
7927 : // CR6869 -- let Window HB take care of it IF (Surface(SurfNum)%ExtBoundCond == SurfNum) THEN
7928 : // Surface is adiabatic
7929 2270634 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7930 295824 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
7931 :
7932 1974810 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7933 0 : MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
7934 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
7935 : }
7936 : // Pre-calculate a few terms
7937 : Real64 const TempTerm(
7938 1974810 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
7939 1974810 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
7940 1974810 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
7941 1974810 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
7942 1974810 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
7943 1974810 : Real64 const TempDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
7944 : // Calculate the current inside surface temperature
7945 1974810 : if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
7946 0 : ((state.dataSurface->SurfIsPool(SurfNum)) &&
7947 0 : (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
7948 0 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
7949 1974810 : if (construct.SourceSinkPresent) {
7950 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7951 0 : (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
7952 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
7953 : TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
7954 : // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
7955 : // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
7956 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
7957 : // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
7958 : // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
7959 : // same temp) | Convection and damping term | Radiation from AFN ducts
7960 : } else {
7961 1974810 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7962 1974810 : (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
7963 : TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
7964 : // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
7965 : // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
7966 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
7967 : // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
7968 : // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
7969 : // same temp) | Convection and damping term | Radiation from AFN ducts
7970 : }
7971 : } else { // this is a pool and it has been simulated this time step
7972 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7973 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
7974 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) /
7975 0 : (construct.CTFInside[0] - construct.CTFCross[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
7976 : DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms (see
7977 : // non-pool equation for details) | Iterative damping term (for stability) |
7978 : // Conduction term (both partition sides same temp) | Pool and damping term
7979 : }
7980 1974810 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7981 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
7982 0 : state.dataMstBalEMPD->HeatFluxLatent(SurfNum) * TempDiv; // Conduction term (both partition sides same temp) |
7983 : // Conduction term (both partition sides same temp) |
7984 : // Convection and damping term
7985 0 : if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
7986 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
7987 : }
7988 : }
7989 : // if any mixed heat transfer models in zone, apply limits to CTF result
7990 1974810 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
7991 766517 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7992 766517 : max(DataHeatBalSurface::MinSurfaceTempLimit,
7993 766517 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
7994 766517 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
7995 : }
7996 :
7997 1974810 : if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
7998 :
7999 : // Radiant system does not need the damping coefficient terms (hopefully) // Partitions are assumed to be symmetric
8000 0 : Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf));
8001 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
8002 0 : TempTerm * RadSysDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW
8003 : // radiation from internal sources | Convection from surface to zone air | Radiant flux from
8004 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant
8005 : // flux from a steam baseboard heater | Radiant flux from an electric baseboard heater | Net
8006 : // radiant exchange with other zone surfaces | Cond term (both partition sides same temp) | Cond
8007 : // term (both partition sides same temp) | Convection and damping term
8008 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
8009 : 0.0; // The outside temp is assumed to be equal to the inside temp for a partition
8010 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
8011 0 : construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both partition sides same temp) | Cond
8012 : // term (both partition sides same temp) | Convection and damping term
8013 : }
8014 :
8015 2270634 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
8016 0 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8017 :
8018 295824 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8019 0 : HeatBalanceHAMTManager::ManageHeatBalHAMT(state,
8020 : SurfNum,
8021 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
8022 : TempSurfOutTmp); // HAMT
8023 : }
8024 :
8025 295824 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
8026 591648 : HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
8027 295824 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
8028 : }
8029 :
8030 295824 : TH11 = TempSurfOutTmp;
8031 : }
8032 :
8033 2270634 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8034 :
8035 : } else { // Standard surface or interzone surface
8036 38374961 : bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataSurface->intMovInsuls(SurfNum).present;
8037 38374961 : if (!movableInsulPresent) { // No movable insulation present, normal heat balance equation
8038 :
8039 38374961 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
8040 11664367 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
8041 :
8042 27414173 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
8043 703579 : MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
8044 703579 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
8045 : }
8046 : // Pre-calculate a few terms
8047 : Real64 const TempTerm(
8048 27414173 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
8049 27414173 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
8050 27414173 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
8051 27414173 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
8052 27414173 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
8053 27414173 : Real64 const TempDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
8054 : // Calculate the current inside surface temperature
8055 27414173 : if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
8056 0 : ((state.dataSurface->SurfIsPool(SurfNum)) &&
8057 0 : (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
8058 0 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
8059 27414173 : if (construct.SourceSinkPresent) {
8060 1678300 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8061 1678300 : (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
8062 1678300 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
8063 1678300 : construct.CTFCross[0] * TH11) *
8064 : TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
8065 : // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
8066 : // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
8067 : // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
8068 : // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
8069 : // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
8070 : // outside surface | Coefficient for conduction (current time) | Convection and damping term |
8071 : // Radiation from AFN ducts
8072 : } else {
8073 25735873 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8074 25735873 : (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
8075 25735873 : construct.CTFCross[0] * TH11) *
8076 : TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
8077 : // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
8078 : // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
8079 : // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
8080 : // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
8081 : // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
8082 : // outside surface | Coefficient for conduction (current time) | Convection and damping term |
8083 : // Radiation from AFN ducts
8084 : }
8085 : } else { // surface is a pool and the pool has been simulated this time step
8086 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8087 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
8088 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) /
8089 0 : (construct.CTFInside[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
8090 : DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms
8091 : // (see non-pool equation for details) | Iterative damping term (for
8092 : // stability) | Current conduction from | the outside surface |
8093 : // Coefficient for conduction (current time) | Pool and damping term
8094 : }
8095 27414173 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
8096 703579 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
8097 703579 : state.dataMstBalEMPD->HeatFluxLatent(SurfNum) *
8098 : TempDiv; // Coefficient for conduction (current time) | Convection and damping term
8099 703579 : if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
8100 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
8101 : }
8102 : }
8103 : // if any mixed heat transfer models in zone, apply limits to CTF result
8104 27414173 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
8105 3648198 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = max(
8106 : DataHeatBalSurface::MinSurfaceTempLimit,
8107 3648198 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
8108 3648198 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
8109 : }
8110 :
8111 27414173 : if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
8112 :
8113 : // Radiant system does not need the damping coefficient terms (hopefully)
8114 1678300 : Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf));
8115 1678300 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
8116 1678300 : TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
8117 : // radiation from internal sources | Convection from surface to zone air | Radiant flux
8118 : // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
8119 : // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
8120 : // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
8121 : // sides same temp) | Convection and damping term
8122 1678300 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
8123 1678300 : construct.CTFCross[0] * RadSysDiv; // Outside temp=inside temp for a partition |
8124 : // Cond term (both partition sides same temp) |
8125 : // Convection and damping term
8126 1678300 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
8127 1678300 : construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both
8128 : // partition sides same temp) | Convection and
8129 : // damping term
8130 :
8131 1678300 : if (surface.ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
8132 : // The inside coefficients of one side are equal to the outside coefficients of the other side. But,
8133 : // the inside coefficients are set up once the heat balance equation for that side has been calculated.
8134 : // For both sides to actually have been set, we have to wait until we get to the second side in the surface
8135 : // derived type. At that point, both inside coefficient sets have been evaluated.
8136 270256 : if (surface.ExtBoundCond < SurfNum) { // Both of the inside coefficients have now been set
8137 135128 : int OtherSideSurfNum = surface.ExtBoundCond;
8138 135128 : state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
8139 135128 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
8140 135128 : state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
8141 135128 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
8142 135128 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
8143 135128 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
8144 135128 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
8145 135128 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
8146 135128 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) =
8147 135128 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
8148 135128 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) =
8149 135128 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
8150 : }
8151 : }
8152 : }
8153 :
8154 38374961 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
8155 1016581 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8156 :
8157 10297568 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8158 353361 : if (surface.ExtBoundCond > 0) {
8159 : // HAMT get the correct other side zone zone air temperature --
8160 0 : int OtherSideSurfNum = surface.ExtBoundCond;
8161 : // ZoneNum = surface.Zone;
8162 0 : OtherSideZoneNum = state.dataSurface->Surface(OtherSideSurfNum).Zone;
8163 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
8164 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(OtherSideZoneNum).MAT;
8165 : }
8166 353361 : HeatBalanceHAMTManager::ManageHeatBalHAMT(state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
8167 : }
8168 :
8169 10297568 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
8170 19888414 : HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
8171 9944207 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
8172 : }
8173 :
8174 10297568 : TH11 = TempSurfOutTmp;
8175 :
8176 10960788 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) {
8177 : // Read Kiva results for each surface
8178 663220 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8179 663220 : state.dataSurfaceGeometry->kivaManager.surfaceMap[SurfNum].results.Tconv - Constant::Kelvin;
8180 :
8181 663220 : TH11 = 0.0;
8182 : }
8183 :
8184 38374961 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8185 :
8186 : } else { // Movable insulation present
8187 0 : Real64 HMovInsul = state.dataSurface->intMovInsuls(SurfNum).H;
8188 0 : if (construct.SourceSinkPresent) {
8189 :
8190 0 : ShowSevereError(state, "Interior movable insulation is not valid with embedded sources/sinks");
8191 0 : ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
8192 0 : ShowContinueError(state,
8193 0 : format("interior movable insulation {} for a surface with that construction.",
8194 0 : s_mat->materials(state.dataSurface->intMovInsuls(SurfNum).matNum)->Name));
8195 0 : ShowContinueError(state,
8196 : "This is not currently allowed because the heat balance equations do not currently accommodate "
8197 : "this combination.");
8198 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
8199 : }
8200 :
8201 0 : Real64 F1 = HMovInsul / (HMovInsul + HConvIn_surf + DataHeatBalSurface::IterDampConst);
8202 :
8203 0 : state.dataHeatBalSurf->SurfTempIn(SurfNum) =
8204 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
8205 0 : construct.CTFCross[0] * TH11 +
8206 0 : F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
8207 0 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
8208 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
8209 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
8210 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum))) /
8211 0 : (construct.CTFInside[0] + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
8212 :
8213 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8214 0 : (construct.CTFInside[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
8215 0 : HMovInsul * state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) -
8216 0 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) - construct.CTFCross[0] * TH11) /
8217 : (HMovInsul);
8218 : // if any mixed heat transfer models in zone, apply limits to CTF result
8219 0 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
8220 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8221 0 : max(DataHeatBalSurface::MinSurfaceTempLimit,
8222 0 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
8223 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
8224 : }
8225 : }
8226 : }
8227 3094005 : }
8228 6456894 : for (int SurfNum : HTWindowSurfs) {
8229 3362889 : auto &surface = state.dataSurface->Surface(SurfNum);
8230 3362889 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8231 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8232 0 : if (SurfNum != repSurfNum) {
8233 0 : continue;
8234 : }
8235 : }
8236 3362889 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
8237 3362889 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // Not const, because storm window may change this
8238 3362889 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8239 3362889 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8240 : // Lookup up the TDD:DOME object
8241 0 : int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
8242 0 : int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
8243 : // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
8244 0 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
8245 :
8246 : // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
8247 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
8248 : // = SurfWinQRadSWwinAbs(SurfNum,1)/2.0
8249 0 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
8250 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8251 0 : (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
8252 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) + HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
8253 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
8254 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
8255 0 : Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
8256 0 : (Ueff + HConvIn_surf +
8257 : DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
8258 : // solar | Convection from surface to zone air | Net radiant exchange with
8259 : // other zone surfaces | Iterative damping term (for stability) | Current
8260 : // conduction from the outside surface | Coefficient for conduction (current
8261 : // time) | Convection and damping term
8262 0 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8263 :
8264 0 : Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(SurfNum) + Constant::Kelvin));
8265 :
8266 : // fill out report vars for components of Window Heat Gain
8267 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) =
8268 0 : HConvIn_surf * surface.Area * (state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(SurfNum));
8269 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
8270 0 : state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
8271 0 : (Sigma_Temp_4 - (state.dataSurface->SurfWinIRfromParentZone(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)));
8272 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) =
8273 0 : state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
8274 0 : (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
8275 0 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum);
8276 :
8277 : // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
8278 0 : state.dataSurface->SurfWinHeatGain(SurfNum) =
8279 0 : state.dataSurface->SurfWinTransSolar(SurfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) +
8280 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) -
8281 0 : surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum);
8282 : // Net transmitted solar | Convection | IR exchange | IR
8283 : // Zone diffuse interior shortwave reflected back into the TDD
8284 :
8285 : } else { // Regular window
8286 3362889 : if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
8287 : // Get outside convection coeff for exterior window here to avoid calling
8288 : // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
8289 : // (HeatBalanceSurfaceManager USEing and WindowManager and
8290 : // WindowManager USEing HeatBalanceSurfaceManager)
8291 924325 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
8292 924325 : auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
8293 924325 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
8294 924325 : Real64 EmisOut = thisMaterial->AbsorpThermalFront; // Glass outside surface emissivity
8295 924325 : DataSurfaces::WinShadingType const shading_flag(state.dataSurface->SurfWinShadingFlag(SurfNum));
8296 924325 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
8297 : // Exterior shade in place
8298 0 : int const ConstrNumSh = surface.activeShadedConstruction;
8299 0 : if (ConstrNumSh != 0) {
8300 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
8301 0 : auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
8302 0 : assert(thisMaterial2 != nullptr);
8303 0 : RoughSurf = thisMaterial2->Roughness;
8304 0 : EmisOut = thisMaterial2->AbsorpThermal;
8305 : }
8306 : }
8307 :
8308 : // Get the outside effective emissivity for Equivalent layer model
8309 924325 : if (construct.WindowTypeEQL) {
8310 0 : EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
8311 : }
8312 : // Set Exterior Convection Coefficient...
8313 924325 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
8314 :
8315 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
8316 :
8317 924325 : } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
8318 :
8319 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
8320 : // subroutine)
8321 924325 : Convect::InitExtConvCoeff(state,
8322 : SurfNum,
8323 : 0.0,
8324 : RoughSurf,
8325 : EmisOut,
8326 : TH11,
8327 924325 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
8328 924325 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
8329 924325 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
8330 924325 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
8331 924325 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
8332 :
8333 924325 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
8334 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0; // Reset SurfHcExt because of wetness
8335 : }
8336 :
8337 : } else { // Not Wind exposed
8338 :
8339 : // Calculate exterior heat transfer coefficients for windspeed = 0
8340 0 : Convect::InitExtConvCoeff(state,
8341 : SurfNum,
8342 : 0.0,
8343 : RoughSurf,
8344 : EmisOut,
8345 : TH11,
8346 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
8347 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
8348 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
8349 0 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
8350 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
8351 : }
8352 : } else { // Interior Surface
8353 :
8354 0 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
8355 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
8356 : } else {
8357 : // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
8358 : // same
8359 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
8360 : }
8361 : }
8362 :
8363 : // Following call determines inside surface temperature of glazing, and of
8364 : // frame and/or divider, if present
8365 924325 : Window::CalcWindowHeatBalance(
8366 924325 : state, SurfNum, state.dataHeatBalSurf->SurfHConvExt(SurfNum), state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TH11);
8367 924325 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8368 : }
8369 : }
8370 3094005 : } // ...end of inside surface heat balance equation selection
8371 :
8372 47102489 : for (int SurfNum : HTSurfs) {
8373 44008484 : int const ZoneNum = state.dataSurface->Surface(SurfNum).Zone;
8374 44008484 : auto &zone = state.dataHeatBal->Zone(ZoneNum);
8375 44008484 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
8376 44008484 : Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
8377 44008484 : TH12 = state.dataHeatBalSurf->SurfTempIn(SurfNum);
8378 44008484 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = TH11; // For reporting
8379 44008484 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Dome) {
8380 0 : continue;
8381 : }
8382 44008484 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8383 : // Tubular daylighting devices are treated as one big object with an effective R value.
8384 : // The outside face temperature of the TDD:DOME and the inside face temperature of the
8385 : // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
8386 : // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
8387 : // and the outside face of the TDD:DIFFUSER for reporting.
8388 :
8389 : // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
8390 0 : int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
8391 0 : state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
8392 0 : state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
8393 :
8394 : // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
8395 : // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
8396 0 : TH11 = state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
8397 0 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
8398 : }
8399 :
8400 44008484 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
8401 0 : TestSurfTempCalcHeatBalanceInsideSurf(state, TH12, SurfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
8402 : }
8403 :
8404 3094005 : } // ...end of main loops over all surfaces for inside heat balances
8405 :
8406 : // Interzone surface updating: interzone surfaces have other side temperatures
8407 : // which can vary as the simulation iterates through the inside heat
8408 : // balance. This block is intended to "lock" the opposite side (outside)
8409 : // temperatures to the correct value, namely the value calculated by the
8410 : // inside surface heat balance for the other side.
8411 : // assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
8412 : // int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
8413 22234717 : for (int SurfNum : IZSurfs) {
8414 19140712 : int const surfExtBoundCond = state.dataSurface->Surface(SurfNum).ExtBoundCond;
8415 : // Set the outside surface temperature to the inside surface temperature of the interzone pair.
8416 : // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
8417 : // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
8418 : // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
8419 19140712 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
8420 19140712 : state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
8421 3094005 : }
8422 :
8423 3094005 : ++state.dataHeatBal->InsideSurfIterations;
8424 :
8425 : // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
8426 3094005 : Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
8427 43739600 : for (int SurfNum : HTNonWindowSurfs) {
8428 40645595 : MaxDelTemp = max(std::abs(state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfTempInsOld(SurfNum)), MaxDelTemp);
8429 40645595 : if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
8430 : // also check all internal nodes as well as surface faces
8431 10240031 : MaxDelTemp = max(MaxDelTemp, state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).MaxNodeDelTemp);
8432 : }
8433 3094005 : } // ...end of loop to check for convergence
8434 :
8435 3094005 : if (!state.dataHeatBal->AnyCondFD) {
8436 2082927 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) {
8437 688318 : Converged = true;
8438 : }
8439 : } else {
8440 1011078 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTempCondFD) {
8441 369583 : Converged = true;
8442 : }
8443 :
8444 : // resets relaxation factor to speed up iterations when under-relaxation is not needed.
8445 1011078 : if (state.dataHeatBal->InsideSurfIterations <= 1) {
8446 351700 : state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
8447 : }
8448 1011078 : if ((state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::IterationsForCondFDRelaxChange) && !Converged) {
8449 : // adjust relaxation factor down, assume large number of iterations is result of instability
8450 1739 : state.dataHeatBal->CondFDRelaxFactor *= 0.9;
8451 1739 : if (state.dataHeatBal->CondFDRelaxFactor < 0.1) {
8452 1277 : state.dataHeatBal->CondFDRelaxFactor = 0.1;
8453 : }
8454 : }
8455 : }
8456 :
8457 : #ifdef EP_Count_Calls
8458 : state.dataTimingsData->NumMaxInsideSurfIterations =
8459 : max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
8460 : #endif
8461 :
8462 3094005 : if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) {
8463 39240 : Converged = false;
8464 : }
8465 :
8466 3094005 : if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
8467 0 : if (!state.dataGlobal->WarmupFlag) {
8468 0 : ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
8469 0 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
8470 0 : if (!state.dataHeatBal->AnyCondFD) {
8471 0 : ShowWarningError(state,
8472 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
8473 : "Allowed Temp Diff [C] ={:.3R}",
8474 : MaxDelTemp,
8475 0 : state.dataHeatBal->MaxAllowedDelTemp));
8476 0 : ShowContinueErrorTimeStamp(state, "");
8477 : } else {
8478 0 : ShowWarningError(state,
8479 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
8480 : "Allowed Temp Diff [C] ={:.6R}",
8481 : MaxDelTemp,
8482 0 : state.dataHeatBal->MaxAllowedDelTempCondFD));
8483 0 : ShowContinueErrorTimeStamp(state, "");
8484 : }
8485 : } else {
8486 0 : ShowRecurringWarningErrorAtEnd(state,
8487 : "Inside surface heat balance convergence problem continues",
8488 0 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
8489 : MaxDelTemp,
8490 : MaxDelTemp,
8491 : _,
8492 : "[C]",
8493 : "[C]");
8494 : }
8495 : }
8496 0 : break; // iteration loop
8497 : }
8498 :
8499 : } // ...end of main inside heat balance DO loop (ends when Converged)
8500 :
8501 : // Update SumHmXXXX for non-window EMPD or HAMT surfaces
8502 1039098 : if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
8503 :
8504 : // these SumHmA* variables are only used for EMPD and HAMT and should be reset each time step (and every iteration)
8505 94956 : for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
8506 54963 : thisZoneHB.SumHmAW = 0.0;
8507 54963 : thisZoneHB.SumHmARa = 0.0;
8508 54963 : thisZoneHB.SumHmARaW = 0.0;
8509 39993 : }
8510 :
8511 381747 : for (int SurfNum : HTNonWindowSurfs) {
8512 341754 : auto const &surface = state.dataSurface->Surface(SurfNum);
8513 341754 : int ZoneNum = surface.Zone;
8514 341754 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
8515 :
8516 341754 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8517 171564 : HeatBalanceHAMTManager::UpdateHeatBalHAMT(state, SurfNum);
8518 :
8519 171564 : Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
8520 :
8521 171564 : thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
8522 :
8523 171564 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).MAT);
8524 514692 : RhoAirZone = Psychrometrics::PsyRhoAirFnPbTdbW(
8525 : state,
8526 171564 : state.dataEnvrn->OutBaroPress,
8527 : MAT_zone,
8528 171564 : Psychrometrics::PsyWFnTdbRhPb(
8529 : state,
8530 : MAT_zone,
8531 171564 : Psychrometrics::PsyRhFnTdbRhov(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum), rhoAirZone),
8532 171564 : state.dataEnvrn->OutBaroPress));
8533 :
8534 171564 : Real64 const surfInTemp(state.dataHeatBalSurf->SurfTempInTmp(SurfNum));
8535 : Wsurf =
8536 343128 : Psychrometrics::PsyWFnTdbRhPb(state,
8537 : surfInTemp,
8538 171564 : Psychrometrics::PsyRhFnTdbRhov(state, surfInTemp, state.dataMstBal->RhoVaporSurfIn(SurfNum), wsurf),
8539 171564 : state.dataEnvrn->OutBaroPress);
8540 :
8541 171564 : thisZoneHB.SumHmARa += FD_Area_fac * RhoAirZone;
8542 :
8543 171564 : thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); // old eq'n: FD_Area_fac * RhoAirZone * Wsurf;
8544 :
8545 170190 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
8546 : // need to calculate the amount of moisture that is entering or
8547 : // leaving the zone Qm [kg/sec] = hmi * Area * (Del Rhov)
8548 : // {Hmi [m/sec]; Area [m2]; Rhov [kg moist/m3] }
8549 : // Positive values are into the zone and negative values are
8550 : // leaving the zone. SumHmAw is the sum of the moisture entering or
8551 : // leaving the zone from all of the surfaces and is a rate. Multiply
8552 : // by time to get the actual amount affecting the zone volume of air.
8553 :
8554 150018 : MoistureBalanceEMPDManager::UpdateMoistureBalanceEMPD(state, SurfNum);
8555 150018 : state.dataMstBal->RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum);
8556 150018 : Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
8557 150018 : thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
8558 150018 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
8559 150018 : thisZoneHB.SumHmARa +=
8560 150018 : FD_Area_fac *
8561 450054 : Psychrometrics::PsyRhoAirFnPbTdbW(
8562 : state,
8563 150018 : state.dataEnvrn->OutBaroPress,
8564 : MAT_zone,
8565 150018 : Psychrometrics::PsyWFnTdbRhPb(state,
8566 : MAT_zone,
8567 150018 : Psychrometrics::PsyRhFnTdbRhovLBnd0C(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum)),
8568 150018 : state.dataEnvrn->OutBaroPress)); // surfInTemp, PsyWFnTdbRhPb( surfInTemp, PsyRhFnTdbRhovLBnd0C(
8569 : // surfInTemp, RhoVaporAirIn( SurfNum ) ), OutBaroPress ) );
8570 150018 : thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum);
8571 : }
8572 39993 : }
8573 : }
8574 1039098 : }
8575 :
8576 2693116 : void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state,
8577 : const int FirstZone, // First zone to simulate
8578 : const int LastZone, // Last zone to simulate
8579 : const std::vector<int> &IZSurfs, // Last zone to simulate
8580 : ObjexxFCL::Optional_int_const ZoneToResimulate)
8581 : {
8582 :
8583 : // This function performs a heat balance on the inside face of each
8584 : // surface in the building. It is a copy of CalcHeatBalanceInsideSurf,
8585 : // simplified for CTF surfaces only.
8586 :
8587 : // REFERENCES:
8588 : // (I)BLAST legacy routine HBSRF
8589 :
8590 2693116 : auto &s_mat = state.dataMaterial;
8591 2693116 : auto &Surface = state.dataSurface->Surface;
8592 :
8593 2693116 : constexpr std::string_view Inside("Inside");
8594 :
8595 2693116 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime) {
8596 : // Set up coefficient arrays that never change - loop over non-window HT surfaces
8597 5897 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8598 10250 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8599 5131 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8600 5131 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8601 5131 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8602 43725 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8603 38594 : int const ConstrNum = Surface(surfNum).Construction;
8604 38594 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8605 38594 : if (Surface(surfNum).ExtBoundCond == surfNum) {
8606 6944 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 1;
8607 : } else {
8608 31650 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 0;
8609 : }
8610 38594 : if (construct.SourceSinkPresent) {
8611 127 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 1;
8612 : } else {
8613 38467 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 0;
8614 : }
8615 : }
8616 5119 : }
8617 : }
8618 :
8619 778 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime = false;
8620 : }
8621 :
8622 22496124 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8623 39654616 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8624 19851608 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8625 : // loop over all heat transfer surface except TDD Dome.
8626 19851608 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
8627 19851608 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
8628 : // determine reference air temperatures and other variable terms - loop over all surfaces
8629 189497629 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8630 169646021 : auto const &surface = Surface(surfNum);
8631 169646021 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8632 198018 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8633 198018 : if (surfNum != repSurfNum) {
8634 44802 : continue;
8635 : }
8636 : }
8637 :
8638 169601219 : int const ConstrNum = Surface(surfNum).Construction;
8639 169601219 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8640 169601219 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) = construct.CTFCross[0];
8641 169601219 : state.dataHeatBalSurf->SurfCTFInside0(surfNum) = construct.CTFInside[0];
8642 169601219 : state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) = construct.CTFSourceIn[0];
8643 169601219 : state.dataHeatBalSurf->SurfTempOutHist(surfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
8644 169601219 : if (construct.SourceSinkPresent) {
8645 791424 : state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) = state.dataHeatBalSurf->SurfQsrcHist(surfNum, 1);
8646 : }
8647 :
8648 : // The special heat balance terms for pools are used only when the pool is operating, so IsPool can change
8649 169601219 : if (state.dataSurface->SurfIsPool(surfNum)) {
8650 51624 : if ((std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit) ||
8651 8092 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit)) {
8652 35440 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 1;
8653 : } else {
8654 8092 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 0;
8655 : }
8656 : }
8657 169601219 : Real64 RefAirTemp = state.dataSurface->Surface(surfNum).getInsideAirTemperature(state, surfNum);
8658 169601219 : state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = RefAirTemp;
8659 169601219 : state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(surfNum);
8660 : }
8661 :
8662 : // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
8663 : // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
8664 : // CalcWindowHeatBalance.
8665 : // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
8666 19851608 : int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
8667 19851608 : int const lastWindowSurf = thisSpace.WindowSurfaceLast;
8668 42279734 : for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
8669 22428126 : state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
8670 22428126 : state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
8671 22428126 : state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
8672 22428126 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
8673 22428126 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
8674 22428126 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
8675 22428126 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
8676 22428126 : state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
8677 22428126 : state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
8678 22428126 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
8679 22428126 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
8680 22428126 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
8681 22428126 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
8682 : }
8683 :
8684 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
8685 19876754 : for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
8686 25146 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
8687 25146 : state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
8688 19851608 : }
8689 :
8690 : // Set up coefficient arrays prior to calculations and precalc terms that do no change during iteration - non-window surfaces
8691 19851608 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8692 19851608 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8693 19851608 : Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
8694 19851608 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8695 : // this loop auto-vectorizes
8696 167069503 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8697 147217895 : auto const &surface = Surface(surfNum);
8698 147217895 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8699 137142 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8700 137142 : if (surfNum != repSurfNum) {
8701 5814 : continue;
8702 : }
8703 : }
8704 :
8705 : // Pre-calculate a few terms before the iteration loop
8706 147212081 : state.dataHeatBalSurf->SurfTempTerm(surfNum) =
8707 147212081 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8708 147212081 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8709 147212081 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8710 147212081 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8711 147212081 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
8712 147212081 : state.dataHeatBalSurf->SurfTempDiv(surfNum) =
8713 147212081 : 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
8714 147212081 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
8715 147212081 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
8716 147212081 : (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant);
8717 : }
8718 19803008 : }
8719 : }
8720 :
8721 2693116 : state.dataHeatBal->InsideSurfIterations = 0;
8722 2693116 : bool Converged = false; // .TRUE. if inside heat balance has converged
8723 13605689 : while (!Converged) { // Start of main inside heat balance iteration loop...
8724 :
8725 10912573 : state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
8726 :
8727 21825146 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
8728 10912573 : state.dataHeatBalSurf->SurfTempIn,
8729 10912573 : state.dataHeatBal->InsideSurfIterations,
8730 10912573 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
8731 : ZoneToResimulate,
8732 : Inside); // Update the radiation balance
8733 :
8734 : // Every 30 iterations, recalculate the inside convection coefficients in case
8735 : // there has been a significant drift in the surface temperatures predicted.
8736 : // This is not fool-proof and it basically means that the outside surface
8737 : // heat balance is in error (potentially) once HConvIn is re-evaluated.
8738 : // The choice of 30 is not significant--just want to do this a couple of
8739 : // times before the iteration limit is hit.
8740 19132030 : if ((state.dataHeatBal->InsideSurfIterations > 0) &&
8741 8219457 : (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
8742 1759 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
8743 : // Since HConvIn has changed re-calculate a few terms - non-window surfaces
8744 12364 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8745 21210 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8746 10605 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8747 10605 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8748 10605 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8749 :
8750 10605 : Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
8751 10605 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8752 : // this loop auto-vectorizes
8753 91810 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8754 81205 : auto const &surface = Surface(surfNum);
8755 81205 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8756 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8757 0 : if (surfNum != repSurfNum) {
8758 0 : continue;
8759 : }
8760 : }
8761 :
8762 81205 : state.dataHeatBalSurf->SurfTempTerm(surfNum) =
8763 81205 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8764 81205 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8765 81205 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8766 81205 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8767 81205 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
8768 81205 : state.dataHeatBalSurf->SurfTempDiv(surfNum) =
8769 81205 : 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
8770 81205 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
8771 81205 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
8772 81205 : (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) +
8773 : iterDampConstant);
8774 : }
8775 10605 : }
8776 : }
8777 : }
8778 :
8779 : // Loop over non-window surfaces
8780 102553364 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8781 183507802 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8782 91867011 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8783 91867011 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8784 91867011 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8785 91867011 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8786 : // this loop auto-vectorizes
8787 778404749 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8788 : // Perform heat balance on the inside face of the surface ...
8789 : // The following are possibilities here (this function only does CTF, see CalcHeatBalanceInsideSurf2 for others):
8790 : // (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
8791 : // (b) the surface is adiabatic (a partition), in which case the temperature of both sides are the same
8792 : // (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
8793 : // (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
8794 : // (e) standard opaque surface with movable insulation, special two-part equation
8795 : // In the surface calculation there are the following Algorithm types for opaque surfaces that
8796 : // do not have movable insulation:
8797 : // (a) the regular CTF calc (SolutionAlgo = UseCTF)
8798 : // (b) the EMPD calc (Solutionalgo = UseEMPD)
8799 : // (c) the CondFD calc (SolutionAlgo = UseCondFD)
8800 : // (d) the HAMT calc (solutionalgo = UseHAMT).
8801 :
8802 : // For adiabatic surface:
8803 : // Adiabatic: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] + HConvIn_surf + IterDampConst));
8804 : // Adiabatic: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
8805 : // Ad+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst *
8806 : // SurfTempInsOld(SurfNum)) * TempDiv; Ad+Pool: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] +
8807 : // PoolHeatTransCoefs(SurfNum) + IterDampConst); Ad+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) +
8808 : // QPoolSurfNumerator(SurfNum) + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
8809 :
8810 : // For standard or interzone surface:
8811 : // Standard: TempDiv = (1.0 / (construct.CTFInside(0) + HConvIn_surf + IterDampConst));
8812 : // Standard: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) *
8813 : // TempDiv; Std+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst
8814 : // * SurfTempInsOld(SurfNum)) * TempDiv; Std+Pool: TempDiv = (1.0 / (construct.CTFInside(0) + PoolHeatTransCoefs(SurfNum) +
8815 : // IterDampConst); Std+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + QPoolSurfNumerator(SurfNum) +
8816 : // IterDampConst* SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) * TempDiv;
8817 :
8818 : // Composite with Adiabatic/Source/Pool flags:
8819 : // TempDiv = (1.0 / (construct.CTFInside(0) - SurfIsAdiabatic*construct.CTFCross[0]+
8820 : // SurfIsOperatingPool*PoolHeatTransCoefs(SurfNum) + IsNotPoolSurf*HConvIn_surf + IterDampConst));
8821 : // SurfTempInTmp(SurfNum) = (IsNotPoolSurf*TempTerm + IsSource*construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) +
8822 : // SurfIsOperatingPool*SurfCTFConstInPart(SurfNum) + SurfIsOperatingPool*QPoolSurfNumerator(SurfNum)
8823 : // + IterDampConst * SurfTempInsOld(SurfNum)+
8824 : // IsNotAdiabatic*IsNotSource*construct.CTFCross[0]
8825 : // * TH11) * TempDiv;
8826 :
8827 : // Calculate the current inside surface temperature
8828 686537738 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8829 686537738 : ((!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) *
8830 686537738 : (state.dataHeatBalSurf->SurfTempTerm(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum)) +
8831 686537738 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) * state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) *
8832 686537738 : state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) +
8833 686537738 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) +
8834 686537738 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum) +
8835 686537738 : iterDampConstant * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
8836 686537738 : (!state.dataHeatBalSurf->SurfIsAdiabatic(surfNum)) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) *
8837 686537738 : state.dataHeatBalSurf->SurfTempOutHist(surfNum)) *
8838 686537738 : state.dataHeatBalSurf->SurfTempDiv(surfNum);
8839 : // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
8840 : // radiation from internal sources | Convection from surface to zone air | Net radiant
8841 : // exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there
8842 : // is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot
8843 : // water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from
8844 : // an electric baseboard heater | Iterative damping term (for stability) | Current
8845 : // conduction from | the outside surface | Coefficient for conduction (current time) |
8846 : // Convection and damping term | Radiation from AFN ducts
8847 :
8848 686537738 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
8849 : }
8850 :
8851 : // Loop over non-window surfaces (includes TubularDaylightingDomes)
8852 778404749 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8853 686537738 : auto &movInsul = state.dataSurface->intMovInsuls(surfNum);
8854 :
8855 686537738 : bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && movInsul.present;
8856 686537738 : if (movableInsulPresent) { // Movable insulation present, recalc surface temps
8857 16981 : Real64 HMovInsul = movInsul.H;
8858 16981 : Real64 F1 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvInt(surfNum) + DataHeatBalSurface::IterDampConst);
8859 16981 : state.dataHeatBalSurf->SurfTempIn(surfNum) =
8860 16981 : (state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
8861 16981 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum) +
8862 16981 : F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8863 16981 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8864 16981 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8865 16981 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8866 16981 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8867 16981 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum))) /
8868 16981 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
8869 :
8870 16981 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8871 16981 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum) +
8872 16981 : HMovInsul * state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) -
8873 16981 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) -
8874 16981 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum)) /
8875 : (HMovInsul);
8876 : }
8877 :
8878 686537738 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
8879 12269820 : if (state.dataConstruction->Construct(Surface(surfNum).Construction).SourceSinkPresent) {
8880 : // Set the appropriate parameters for the radiant system
8881 : // Radiant system does not need the damping coefficient terms (hopefully)
8882 : Real64 const RadSysDiv(1.0 /
8883 2445348 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + state.dataHeatBalSurf->SurfHConvInt(surfNum)));
8884 : Real64 const TempTerm(
8885 2445348 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8886 2445348 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
8887 2445348 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8888 2445348 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8889 2445348 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8890 2445348 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / state.dataGlobal->TimeStepZoneSec));
8891 2445348 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum) =
8892 2445348 : TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
8893 : // radiation from internal sources | Convection from surface to zone air | Radiant flux
8894 : // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
8895 : // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
8896 : // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
8897 : // sides same temp) | Convection and damping term
8898 2445348 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum) =
8899 2445348 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * RadSysDiv; // Outside temp=inside temp for a partition |
8900 : // Cond term (both partition sides same temp) |
8901 : // Convection and damping term
8902 2445348 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum) =
8903 2445348 : state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * RadSysDiv; // QTF term for the source | Cond term (both
8904 : // partition sides same temp) | Convection and
8905 : // damping term
8906 :
8907 2445348 : if (Surface(surfNum).ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
8908 : // The inside coefficients of one side are equal to the outside coefficients of the other side. But,
8909 : // the inside coefficients are set up once the heat balance equation for that side has been calculated.
8910 : // For both sides to actually have been set, we have to wait until we get to the second side in the surface
8911 : // derived type. At that point, both inside coefficient sets have been evaluated.
8912 968842 : if (Surface(surfNum).ExtBoundCond <= surfNum) { // Both of the inside coefficients have now been set
8913 484421 : int OtherSideSurfNum = Surface(surfNum).ExtBoundCond;
8914 484421 : state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
8915 484421 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum);
8916 484421 : state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
8917 484421 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum);
8918 484421 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
8919 484421 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum);
8920 484421 : state.dataHeatBalFanSys->RadSysToHBConstCoef(surfNum) =
8921 484421 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
8922 484421 : state.dataHeatBalFanSys->RadSysToHBTinCoef(surfNum) =
8923 484421 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
8924 484421 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(surfNum) =
8925 484421 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
8926 : }
8927 : }
8928 : }
8929 : }
8930 : }
8931 :
8932 : // Loop over window surfaces
8933 91867011 : int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
8934 91867011 : int const lastWindowSurf = thisSpace.WindowSurfaceLast;
8935 193638700 : for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
8936 101771689 : auto &surface = state.dataSurface->Surface(surfNum);
8937 101771689 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8938 166430 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8939 166430 : if (surfNum != repSurfNum) {
8940 106590 : continue;
8941 : }
8942 : }
8943 101665099 : Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum));
8944 101665099 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(surfNum);
8945 101665099 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8946 101665099 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8947 : // Lookup up the TDD:DOME object
8948 20832 : int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
8949 20832 : int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
8950 : // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
8951 20832 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
8952 :
8953 : // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
8954 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
8955 : // = SurfWinQRadSWwinAbs(surfNum,1)/2.0
8956 20832 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surfNum));
8957 20832 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8958 20832 : (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, 1) / 2.0 +
8959 20832 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8960 20832 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8961 20832 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8962 20832 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
8963 20832 : Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
8964 20832 : (Ueff + HConvIn_surf +
8965 : DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
8966 : // solar | Convection from surface to zone air | Net radiant exchange with
8967 : // other zone surfaces | Iterative damping term (for stability) | Current
8968 : // conduction from the outside surface | Coefficient for conduction (current
8969 : // time) | Convection and damping term
8970 20832 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
8971 20832 : Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(surfNum) + Constant::Kelvin));
8972 :
8973 : // fill out report vars for components of Window Heat Gain
8974 20832 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
8975 41664 : HConvIn_surf * surface.Area *
8976 20832 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
8977 20832 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
8978 20832 : state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
8979 20832 : (Sigma_Temp_4 -
8980 20832 : (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum)));
8981 20832 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
8982 20832 : state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
8983 20832 : (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
8984 20832 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(surfNum);
8985 :
8986 : // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
8987 20832 : state.dataSurface->SurfWinHeatGain(surfNum) =
8988 20832 : state.dataSurface->SurfWinTransSolar(surfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) +
8989 20832 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) -
8990 20832 : surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum);
8991 : // Net transmitted solar | Convection | IR exchange | IR
8992 : // Zone diffuse interior shortwave reflected back into the TDD
8993 : } else { // Regular window
8994 101644267 : if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
8995 : // Get outside convection coeff for exterior window here to avoid calling
8996 : // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
8997 : // (HeatBalanceSurfaceManager USEing and WindowManager and
8998 : // WindowManager USEing HeatBalanceSurfaceManager)
8999 22385088 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
9000 22357896 : auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
9001 22357896 : assert(thisMaterial != nullptr);
9002 22357896 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
9003 22357896 : Real64 EmisOut = thisMaterial->AbsorpThermalFront; // Glass outside surface emissivity
9004 22357896 : DataSurfaces::WinShadingType const shading_flag = state.dataSurface->SurfWinShadingFlag(surfNum);
9005 22357896 : if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
9006 : // Exterior shade in place
9007 31665 : int const ConstrNumSh = Surface(surfNum).activeShadedConstruction;
9008 31665 : if (ConstrNumSh != 0) {
9009 21522 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
9010 21522 : auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
9011 21522 : RoughSurf = thisMaterial2->Roughness;
9012 21522 : EmisOut = thisMaterial2->AbsorpThermal;
9013 : }
9014 : }
9015 :
9016 : // Get the outside effective emissivity for Equivalent layer model
9017 22357896 : if (construct.WindowTypeEQL) {
9018 8109 : EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
9019 : }
9020 : // Set Exterior Convection Coefficient...
9021 22357896 : if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
9022 :
9023 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
9024 :
9025 22357896 : } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
9026 :
9027 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
9028 : // subroutine)
9029 22357896 : Convect::InitExtConvCoeff(state,
9030 : surfNum,
9031 : 0.0,
9032 : RoughSurf,
9033 : EmisOut,
9034 : TH11,
9035 22357896 : state.dataHeatBalSurf->SurfHConvExt(surfNum),
9036 22357896 : state.dataHeatBalSurf->SurfHSkyExt(surfNum),
9037 22357896 : state.dataHeatBalSurf->SurfHGrdExt(surfNum),
9038 22357896 : state.dataHeatBalSurf->SurfHAirExt(surfNum),
9039 22357896 : state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
9040 :
9041 22357896 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
9042 5882 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = 1000.0; // Reset SurfHcExt because of wetness
9043 : }
9044 :
9045 : } else { // Not Wind exposed
9046 :
9047 : // Calculate exterior heat transfer coefficients for windspeed = 0
9048 0 : Convect::InitExtConvCoeff(state,
9049 : surfNum,
9050 : 0.0,
9051 : RoughSurf,
9052 : EmisOut,
9053 : TH11,
9054 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum),
9055 0 : state.dataHeatBalSurf->SurfHSkyExt(surfNum),
9056 0 : state.dataHeatBalSurf->SurfHGrdExt(surfNum),
9057 0 : state.dataHeatBalSurf->SurfHAirExt(surfNum),
9058 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
9059 : }
9060 :
9061 : } else { // Interior Surface
9062 :
9063 27192 : if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
9064 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
9065 : } else {
9066 : // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
9067 : // same
9068 27192 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
9069 : }
9070 : }
9071 :
9072 : // Following call determines inside surface temperature of glazing, and of
9073 : // frame and/or divider, if present
9074 22385088 : Window::CalcWindowHeatBalance(
9075 22385088 : state, surfNum, state.dataHeatBalSurf->SurfHConvExt(surfNum), state.dataHeatBalSurf->SurfTempInTmp(surfNum), TH11);
9076 22385088 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
9077 : }
9078 : }
9079 : }
9080 :
9081 91867011 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
9082 91867011 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
9083 880176438 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
9084 788309427 : auto &zone = state.dataHeatBal->Zone(zoneNum);
9085 :
9086 788309427 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
9087 788309427 : Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(surfNum);
9088 788309427 : TH12 = state.dataHeatBalSurf->SurfTempIn(surfNum);
9089 788309427 : state.dataHeatBalSurf->SurfTempOut(surfNum) = TH11; // For reporting
9090 788309427 : if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
9091 : // Tubular daylighting devices are treated as one big object with an effective R value.
9092 : // The outside face temperature of the TDD:DOME and the inside face temperature of the
9093 : // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
9094 : // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
9095 : // and the outside face of the TDD:DIFFUSER for reporting.
9096 :
9097 : // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
9098 20832 : int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(surfNum)).Dome;
9099 20832 : state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
9100 20832 : state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(surfNum);
9101 :
9102 : // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
9103 : // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
9104 20832 : TH11 = state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
9105 20832 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
9106 : }
9107 :
9108 788309427 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
9109 0 : TestSurfTempCalcHeatBalanceInsideSurf(
9110 0 : state, TH12, surfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
9111 : }
9112 : }
9113 91640791 : }
9114 : } // ...end of main loops over all surfaces for inside heat balances
9115 :
9116 : // Interzone surface updating: interzone surfaces have other side temperatures
9117 : // which can vary as the simulation iterates through the inside heat
9118 : // balance. This block is intended to "lock" the opposite side (outside)
9119 : // temperatures to the correct value, namely the value calculated by the
9120 : // inside surface heat balance for the other side.
9121 : // assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
9122 : // int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
9123 326734571 : for (int SurfNum : IZSurfs) {
9124 315821998 : int const surfExtBoundCond = Surface(SurfNum).ExtBoundCond;
9125 : // Set the outside surface temperature to the inside surface temperature of the interzone pair.
9126 : // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
9127 : // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
9128 : // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
9129 315821998 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
9130 315821998 : state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
9131 315821998 : state.dataHeatBalSurf->SurfTempOutHist(SurfNum) = state.dataHeatBalSurf->SurfTempOut(SurfNum);
9132 10912573 : }
9133 :
9134 10912573 : ++state.dataHeatBal->InsideSurfIterations;
9135 :
9136 : // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
9137 10912573 : Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
9138 102553364 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
9139 183507802 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
9140 91867011 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
9141 91867011 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
9142 91867011 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
9143 778404749 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
9144 686537738 : Real64 delta = state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfTempInsOld(surfNum);
9145 686537738 : Real64 absDif = std::abs(delta);
9146 686537738 : MaxDelTemp = std::max(absDif, MaxDelTemp);
9147 : }
9148 91640791 : }
9149 : } // ...end of loop to check for convergence
9150 :
9151 10912573 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) {
9152 2693116 : Converged = true;
9153 : }
9154 :
9155 : #ifdef EP_Count_Calls
9156 : state.dataTimingsData->NumMaxInsideSurfIterations =
9157 : max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
9158 : #endif
9159 :
9160 10912573 : if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) {
9161 0 : Converged = false;
9162 : }
9163 :
9164 10912573 : if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
9165 0 : if (!state.dataGlobal->WarmupFlag) {
9166 0 : ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
9167 0 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
9168 0 : ShowWarningError(state,
9169 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max Allowed "
9170 : "Temp Diff [C] ={:.6R}",
9171 : MaxDelTemp,
9172 0 : state.dataHeatBal->MaxAllowedDelTempCondFD));
9173 0 : ShowContinueErrorTimeStamp(state, "");
9174 : } else {
9175 0 : ShowRecurringWarningErrorAtEnd(state,
9176 : "Inside surface heat balance convergence problem continues",
9177 0 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
9178 : MaxDelTemp,
9179 : MaxDelTemp,
9180 : _,
9181 : "[C]",
9182 : "[C]");
9183 : }
9184 : }
9185 0 : break; // iteration loop
9186 : }
9187 :
9188 : } // ...end of main inside heat balance iteration loop (ends when Converged)
9189 2693116 : }
9190 :
9191 3732214 : void sumSurfQdotRadHVAC(EnergyPlusData &state)
9192 : {
9193 6873660 : for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
9194 3141446 : auto const &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
9195 3141446 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = thisSurfQRadFromHVAC.HTRadSys + thisSurfQRadFromHVAC.HWBaseboard +
9196 3141446 : thisSurfQRadFromHVAC.SteamBaseboard + thisSurfQRadFromHVAC.ElecBaseboard +
9197 3141446 : thisSurfQRadFromHVAC.CoolingPanel;
9198 3732214 : }
9199 3732214 : }
9200 :
9201 0 : void TestSurfTempCalcHeatBalanceInsideSurf(EnergyPlusData &state, Real64 TH12, int const SurfNum, DataHeatBalance::ZoneData &zone, int WarmupSurfTemp)
9202 : {
9203 0 : std::string surfName = state.dataSurface->Surface(SurfNum).Name;
9204 :
9205 0 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
9206 0 : if (state.dataGlobal->WarmupFlag) {
9207 0 : ++WarmupSurfTemp;
9208 : }
9209 0 : if (!state.dataGlobal->WarmupFlag || WarmupSurfTemp > 10 || state.dataGlobal->DisplayExtraWarnings) {
9210 0 : if (TH12 < DataHeatBalSurface::MinSurfaceTempLimit) {
9211 0 : if (state.dataSurface->SurfLowTempErrCount(SurfNum) == 0) {
9212 0 : ShowSevereMessage(
9213 0 : state, format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9214 0 : ShowContinueErrorTimeStamp(state, "");
9215 0 : if (!zone.TempOutOfBoundsReported) {
9216 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9217 0 : if (zone.FloorArea > 0.0) {
9218 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9219 : } else {
9220 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
9221 : }
9222 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9223 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9224 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9225 : } else {
9226 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9227 : }
9228 0 : if (zone.IsControlled) {
9229 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9230 : } else {
9231 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9232 : }
9233 0 : zone.TempOutOfBoundsReported = true;
9234 : }
9235 0 : ShowRecurringSevereErrorAtEnd(state,
9236 0 : "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9237 0 : state.dataSurface->SurfLowTempErrCount(SurfNum),
9238 : TH12,
9239 : TH12,
9240 : _,
9241 : "C",
9242 : "C");
9243 : } else {
9244 0 : ShowRecurringSevereErrorAtEnd(state,
9245 0 : "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9246 0 : state.dataSurface->SurfLowTempErrCount(SurfNum),
9247 : TH12,
9248 : TH12,
9249 : _,
9250 : "C",
9251 : "C");
9252 : }
9253 : } else {
9254 0 : if (state.dataSurface->SurfHighTempErrCount(SurfNum) == 0) {
9255 0 : ShowSevereMessage(
9256 0 : state, format(R"(Temperature (high) out of bounds ({:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9257 0 : ShowContinueErrorTimeStamp(state, "");
9258 0 : if (!zone.TempOutOfBoundsReported) {
9259 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9260 0 : if (zone.FloorArea > 0.0) {
9261 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9262 : } else {
9263 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
9264 : }
9265 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9266 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9267 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9268 : } else {
9269 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9270 : }
9271 0 : if (zone.IsControlled) {
9272 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9273 : } else {
9274 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9275 : }
9276 0 : zone.TempOutOfBoundsReported = true;
9277 : }
9278 0 : ShowRecurringSevereErrorAtEnd(state,
9279 0 : "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9280 0 : state.dataSurface->SurfHighTempErrCount(SurfNum),
9281 : TH12,
9282 : TH12,
9283 : _,
9284 : "C",
9285 : "C");
9286 : } else {
9287 0 : ShowRecurringSevereErrorAtEnd(state,
9288 0 : "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9289 0 : state.dataSurface->SurfHighTempErrCount(SurfNum),
9290 : TH12,
9291 : TH12,
9292 : _,
9293 : "C",
9294 : "C");
9295 : }
9296 : }
9297 0 : if (zone.EnforcedReciprocity) {
9298 0 : if (WarmupSurfTemp > 3) {
9299 0 : ShowSevereError(state, format("CalcHeatBalanceInsideSurf: Zone=\"{}\" has view factor enforced reciprocity", zone.Name));
9300 0 : ShowContinueError(state, " and is having temperature out of bounds errors. Please correct zone geometry and rerun.");
9301 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
9302 : }
9303 0 : } else if (WarmupSurfTemp > 10) {
9304 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
9305 : }
9306 : }
9307 : }
9308 0 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal)) {
9309 0 : if (!state.dataGlobal->WarmupFlag) {
9310 0 : if (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal) {
9311 0 : ShowSevereError(state,
9312 0 : format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9313 0 : ShowContinueErrorTimeStamp(state, "");
9314 0 : if (!zone.TempOutOfBoundsReported) {
9315 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9316 0 : if (zone.FloorArea > 0.0) {
9317 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9318 : } else {
9319 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
9320 : }
9321 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9322 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9323 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9324 : } else {
9325 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9326 : }
9327 0 : if (zone.IsControlled) {
9328 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9329 : } else {
9330 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9331 : }
9332 0 : zone.TempOutOfBoundsReported = true;
9333 : }
9334 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9335 : } else {
9336 0 : ShowSevereError(state,
9337 0 : format(R"(Temperature (high) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9338 0 : ShowContinueErrorTimeStamp(state, "");
9339 0 : if (!zone.TempOutOfBoundsReported) {
9340 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9341 0 : if (zone.FloorArea > 0.0) {
9342 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9343 : } else {
9344 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
9345 : }
9346 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9347 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9348 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9349 : } else {
9350 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9351 : }
9352 0 : if (zone.IsControlled) {
9353 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9354 : } else {
9355 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9356 : }
9357 0 : zone.TempOutOfBoundsReported = true;
9358 : }
9359 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9360 : }
9361 : } else {
9362 0 : if (TH12 < -10000. || TH12 > 10000.) {
9363 0 : ShowSevereError(
9364 : state,
9365 0 : format(R"(CalcHeatBalanceInsideSurf: The temperature of {:.2R} C for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9366 0 : ShowContinueError(state, "..is very far out of bounds during warmup. This may be an indication of a malformed zone.");
9367 0 : ShowContinueErrorTimeStamp(state, "");
9368 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9369 : }
9370 : }
9371 : }
9372 0 : }
9373 :
9374 43041338 : void CalcOutsideSurfTemp(EnergyPlusData &state,
9375 : int const SurfNum, // Surface number DO loop counter
9376 : int const spaceNum, // Space number the current surface is attached to
9377 : int const ConstrNum, // Construction index for the current surface
9378 : Real64 const HMovInsul, // "Convection" coefficient of movable insulation
9379 : Real64 const TempExt, // Exterior temperature boundary condition
9380 : bool &ErrorFlag // Error flag for movable insulation problem
9381 : )
9382 : {
9383 :
9384 : // SUBROUTINE INFORMATION:
9385 : // AUTHOR George Walton
9386 : // DATE WRITTEN December 1979
9387 : // MODIFIED Jun 1990 (RDT for new CTF arrays)
9388 : // Jul 2000 (RJL for Moisture algorithms)
9389 : // Sep 2000 (RKS for new radiant exchange algorithm)
9390 : // Dec 2000 (RKS for radiant system model addition)
9391 : // Aug 2010 (BG added radiant heat flow rate reporting)
9392 : // RE-ENGINEERED Mar 1998 (RKS)
9393 :
9394 : // PURPOSE OF THIS SUBROUTINE:
9395 : // This subroutine performs a heat balance on the outside face of each
9396 : // surface in the building. NOTE that this also sets some coefficients
9397 : // that are needed for radiant system modeling. Thus, it is extremely
9398 : // important that if someone makes changes to the heat balance equations
9399 : // at a later date that they must also make changes to the coefficient
9400 : // setting portion of this subroutine as well.
9401 :
9402 : // METHODOLOGY EMPLOYED:
9403 : // Various boundary conditions are set and additional parameters are set-
9404 : // up. Then, the proper heat balance equation is selected based on the
9405 : // presence of movable insulation, thermal mass of the surface construction,
9406 : // and convection model being used.
9407 :
9408 : // REFERENCES:
9409 : // (I)BLAST legacy routine HBOUT
9410 : // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
9411 :
9412 : // Determine whether or not movable insulation is present
9413 43041338 : bool MovInsulPresent = (HMovInsul > 0.0); // .TRUE. if movable insulation is currently present for surface
9414 : bool QuickConductionSurf; // .TRUE. if the cross CTF term is relatively large
9415 : Real64 F1; // Intermediate calculation variable
9416 : Real64 F2; // Intermediate calculation variable
9417 : // Determine whether this surface is a "slow conductive" or "quick conductive"
9418 : // surface. Designates are inherited from BLAST. Basically, a "quick" surface
9419 : // requires the inside heat balance to be accounted for in the heat balance
9420 : // while a "slow" surface can used the last time step's value for inside
9421 : // surface temperature.
9422 43041338 : auto &s_mat = state.dataMaterial;
9423 :
9424 43041338 : auto &surface = state.dataSurface->Surface(SurfNum);
9425 43041338 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
9426 43041338 : if (construct.CTFCross[0] > 0.01) {
9427 4728312 : QuickConductionSurf = true;
9428 4728312 : F1 = construct.CTFCross[0] / (construct.CTFInside[0] + state.dataHeatBalSurf->SurfHConvInt(SurfNum));
9429 : } else {
9430 38313026 : QuickConductionSurf = false;
9431 : }
9432 :
9433 43041338 : Real64 TSky = state.dataEnvrn->SkyTemp;
9434 43041338 : Real64 TGround = state.dataEnvrn->OutDryBulbTemp;
9435 43041338 : Real64 TSrdSurfs = 0.0;
9436 :
9437 43041338 : if (surface.SurfHasSurroundingSurfProperty) {
9438 5412 : int SrdSurfsNum = surface.SurfSurroundingSurfacesNum;
9439 5412 : if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched != nullptr) {
9440 0 : TSky = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched->getCurrentVal();
9441 : }
9442 5412 : if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched != nullptr) {
9443 0 : TGround = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched->getCurrentVal();
9444 : }
9445 5412 : TSrdSurfs = state.dataSurface->Surface(SurfNum).SrdSurfTemp;
9446 : }
9447 43041338 : if (surface.UseSurfPropertyGndSurfTemp) {
9448 8118 : TGround = state.dataSurface->GroundSurfsProperty(surface.SurfPropertyGndSurfIndex).SurfsTempAvg;
9449 : }
9450 :
9451 : // Now, calculate the outside surface temperature using the proper heat balance equation.
9452 : // Each case has been separated out into its own IF-THEN block for clarity. Additional
9453 : // cases can simply be added anywhere in the following section. This is the last step
9454 : // in the main loop. Once the proper heat balance is done, the simulation goes on to
9455 : // the next SurfNum.
9456 :
9457 : // Outside heat balance case: Tubular daylighting device
9458 43041338 : Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum));
9459 43041338 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
9460 :
9461 : // Lookup up the TDD:DIFFUSER object
9462 4050 : int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
9463 4050 : int SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser;
9464 4050 : int spaceNum2 = state.dataSurface->Surface(SurfNum2).spaceNum;
9465 4050 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(PipeNum).Reff; // 1 / effective R value between TDD:DOME and TDD:DIFFUSER
9466 4050 : F1 = Ueff / (Ueff + state.dataHeatBalSurf->SurfHConvInt(SurfNum2));
9467 :
9468 : // Similar to opaque surface but inside conditions of TDD:DIFFUSER are used, and no embedded sources/sinks.
9469 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
9470 : // SurfOpaqQRadSWOutAbs(SurfNum) does not apply for TDD:DOME, must use SurfWinQRadSWwinAbs(SurfNum,1)/2.0 instead.
9471 : //+Construct(ConstrNum)%CTFSourceOut[0] & TDDs cannot be radiant systems
9472 : // *SurfQsrcHist(1,SurfNum) &
9473 : //+Construct(ConstrNum)%CTFSourceIn[0] & TDDs cannot be radiant systems
9474 : // *SurfQsrcHist(1,SurfNum) &
9475 4050 : TH11 = (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
9476 4050 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9477 4050 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) +
9478 4050 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9479 4050 : F1 * (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum2, 1) / 2.0 + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum2) +
9480 4050 : state.dataHeatBalSurf->SurfHConvInt(SurfNum2) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum2).MAT +
9481 4050 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum2))) /
9482 4050 : (Ueff + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9483 4050 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9484 4050 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9485 4050 : F1 * Ueff); // Instead of SurfOpaqQRadSWOutAbs(SurfNum) | ODB used to approx ground surface temp | Use TDD:DIFFUSER surface | Use
9486 : // TDD:DIFFUSER surface | Use TDD:DIFFUSER surface and zone | Use TDD:DIFFUSER surface
9487 :
9488 : // Outside heat balance case: No movable insulation, slow conduction
9489 43037288 : } else if ((!MovInsulPresent) && (!QuickConductionSurf)) {
9490 : // Add LWR from surrounding surfaces
9491 38304929 : if (surface.OSCMPtr == 0) {
9492 38163314 : if (construct.SourceSinkPresent) {
9493 83175 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9494 83175 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9495 83175 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9496 83175 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9497 83175 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9498 83175 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
9499 83175 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9500 83175 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9501 83175 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
9502 : } else {
9503 38080139 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9504 38080139 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9505 38080139 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9506 38080139 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9507 38080139 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
9508 38080139 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9509 38080139 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9510 38080139 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
9511 : }
9512 : // Outside Heat Balance case: Other Side Conditions Model
9513 : } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
9514 : // local copies of variables for clarity in radiation terms
9515 : // TODO: - int OSCMPtr; // "Pointer" to OSCM data structure (other side conditions from a model)
9516 : Real64 RadTemp =
9517 141615 : state.dataSurface->OSCM(surface.OSCMPtr).TRad; // local value for Effective radiation temperature for OtherSideConditions model
9518 141615 : Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad; // local value for effective (linearized) radiation coefficient
9519 :
9520 : // patterned after "No movable insulation, slow conduction," but with new radiation terms and no sun,
9521 141615 : if (construct.SourceSinkPresent) {
9522 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9523 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9524 0 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9525 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
9526 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
9527 : } else {
9528 141615 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9529 141615 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9530 141615 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
9531 141615 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
9532 : }
9533 : }
9534 : // Outside heat balance case: No movable insulation, quick conduction
9535 43037288 : } else if ((!MovInsulPresent) && (QuickConductionSurf)) {
9536 4728312 : if (surface.OSCMPtr == 0) {
9537 4658112 : if (construct.SourceSinkPresent) {
9538 24140 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9539 24140 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9540 24140 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9541 24140 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9542 24140 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9543 24140 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9544 24140 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9545 24140 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9546 24140 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9547 24140 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9548 24140 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9549 24140 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9550 24140 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9551 24140 : F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
9552 : } else {
9553 4633972 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9554 4633972 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9555 4633972 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9556 4633972 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9557 4633972 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9558 4633972 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9559 4633972 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9560 4633972 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9561 4633972 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9562 4633972 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9563 4633972 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9564 4633972 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9565 4633972 : F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
9566 : }
9567 : // Outside Heat Balance case: Other Side Conditions Model
9568 : } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
9569 : // local copies of variables for clarity in radiation terms
9570 70200 : Real64 RadTemp = state.dataSurface->OSCM(surface.OSCMPtr).TRad;
9571 70200 : Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad;
9572 : // patterned after "No movable insulation, quick conduction," but with new radiation terms and no sun,
9573 70200 : if (construct.SourceSinkPresent) {
9574 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9575 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9576 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9577 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9578 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9579 0 : construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9580 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9581 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9582 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
9583 0 : F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
9584 : } else {
9585 70200 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9586 70200 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9587 70200 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9588 70200 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9589 70200 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9590 70200 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9591 70200 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
9592 70200 : F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
9593 : }
9594 : }
9595 : // Outside heat balance case: Movable insulation, slow conduction
9596 4732359 : } else if ((MovInsulPresent) && (!QuickConductionSurf)) {
9597 :
9598 4047 : F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9599 4047 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9600 4047 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
9601 :
9602 4047 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9603 4047 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9604 4047 : F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
9605 4047 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9606 4047 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9607 4047 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
9608 4047 : (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul); // ODB used to approx ground surface temp
9609 :
9610 : // Outside heat balance case: Movable insulation, quick conduction
9611 0 : } else if ((MovInsulPresent) && (QuickConductionSurf)) {
9612 :
9613 0 : F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9614 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9615 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
9616 :
9617 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9618 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9619 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9620 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9621 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)) +
9622 0 : F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
9623 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9624 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9625 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
9626 0 : (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul - F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp
9627 :
9628 : } // ...end of outside heat balance cases IF-THEN block
9629 :
9630 : // multiply out linearized radiation coeffs for reporting
9631 : Real64 const HExtSurf_fac(
9632 43041338 : -(state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * (TH11 - TSky) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) * (TH11 - TempExt) +
9633 43041338 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * (TH11 - TGround) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * (TH11 - TSrdSurfs)));
9634 43041338 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = HExtSurf_fac;
9635 :
9636 : // Set the radiant system heat balance coefficients if this surface is also a radiant system
9637 43041338 : if (construct.SourceSinkPresent) {
9638 :
9639 107315 : if (MovInsulPresent) {
9640 : // Note: if movable insulation is ever added back in correctly, the heat balance equations above must be fixed
9641 0 : ShowSevereError(state, "Exterior movable insulation is not valid with embedded sources/sinks");
9642 0 : ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
9643 0 : ShowContinueError(state,
9644 0 : format("exterior movable insulation {} for a surface with that construction.",
9645 0 : s_mat->materials(state.dataSurface->extMovInsuls(SurfNum).matNum)->Name));
9646 0 : ShowContinueError(state,
9647 : "This is not currently allowed because the heat balance equations do not currently accommodate this combination.");
9648 0 : ErrorFlag = true;
9649 0 : return;
9650 :
9651 : } else {
9652 107315 : Real64 const RadSysDiv(1.0 / (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) +
9653 107315 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) +
9654 107315 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) +
9655 107315 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)));
9656 :
9657 107315 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
9658 107315 : (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9659 107315 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9660 107315 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9661 107315 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround) *
9662 : RadSysDiv; // ODB used to approx ground surface temp
9663 :
9664 107315 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = construct.CTFCross[0] * RadSysDiv;
9665 :
9666 107315 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = construct.CTFSourceOut[0] * RadSysDiv;
9667 : }
9668 : }
9669 : }
9670 :
9671 8124 : void CalcExteriorVentedCavity(EnergyPlusData &state, int const SurfNum) // index of surface
9672 : {
9673 :
9674 : // SUBROUTINE INFORMATION:
9675 : // AUTHOR B Griffith
9676 : // DATE WRITTEN January 2005
9677 :
9678 : // PURPOSE OF THIS SUBROUTINE:
9679 : // manages calculating the temperatures of baffle and air cavity for
9680 : // multi-skin configuration.
9681 :
9682 : // METHODOLOGY EMPLOYED:
9683 : // derived from CalcPassiveTranspiredCollector
9684 :
9685 : // local working variables
9686 : Real64 HrPlen;
9687 : Real64 HcPlen;
9688 : Real64 Isc;
9689 : Real64 MdotVent;
9690 : Real64 VdotWind;
9691 : Real64 VdotThermal;
9692 :
9693 8124 : int CavNum = state.dataSurface->SurfExtCavNum(SurfNum);
9694 8124 : Real64 TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
9695 8124 : Real64 OutHumRatExt = Psychrometrics::PsyWFnTdbTwbPb(
9696 8124 : state, state.dataSurface->SurfOutDryBulbTemp(SurfNum), state.dataSurface->SurfOutWetBulbTemp(SurfNum), state.dataEnvrn->OutBaroPress);
9697 8124 : Real64 RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, OutHumRatExt);
9698 8124 : Real64 holeArea = state.dataHeatBal->ExtVentedCavity(CavNum).ActualArea * state.dataHeatBal->ExtVentedCavity(CavNum).Porosity;
9699 : // Aspect Ratio of gap
9700 8124 : Real64 AspRat = state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL * 2.0 / state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick;
9701 8124 : Real64 TmpTscoll = state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast;
9702 8124 : Real64 TmpTaPlen = state.dataHeatBal->ExtVentedCavity(CavNum).TairLast;
9703 :
9704 : // all the work is done in this routine located in GeneralRoutines.cc
9705 :
9706 32496 : for (int iter = 1; iter <= 3; ++iter) { // this is a sequential solution approach.
9707 :
9708 48744 : TranspiredCollector::CalcPassiveExteriorBaffleGap(state,
9709 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).SurfPtrs,
9710 : holeArea,
9711 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).Cv,
9712 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).Cd,
9713 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL,
9714 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).SolAbsorp,
9715 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).LWEmitt,
9716 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).Tilt,
9717 : AspRat,
9718 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick,
9719 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).BaffleRoughness,
9720 24372 : state.dataHeatBal->ExtVentedCavity(CavNum).QdotSource,
9721 : TmpTscoll,
9722 : TmpTaPlen,
9723 : HcPlen,
9724 : HrPlen,
9725 : Isc,
9726 : MdotVent,
9727 : VdotWind,
9728 : VdotThermal);
9729 :
9730 : } // sequential solution
9731 : // now fill results into derived types
9732 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).Isc = Isc;
9733 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav = TmpTaPlen;
9734 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle = TmpTscoll;
9735 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen = HrPlen;
9736 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen = HcPlen;
9737 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveACH =
9738 16248 : (MdotVent / RhoAir) *
9739 8124 : (1.0 / (state.dataHeatBal->ExtVentedCavity(CavNum).ProjArea * state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick)) *
9740 : Constant::rSecsInHour;
9741 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotVent = MdotVent;
9742 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotWind = VdotWind * RhoAir;
9743 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotTherm = VdotThermal * RhoAir;
9744 :
9745 : // now do some updates
9746 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).TairLast = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
9747 8124 : state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
9748 :
9749 : // update the OtherSideConditionsModel coefficients.
9750 8124 : int thisOSCM = state.dataHeatBal->ExtVentedCavity(CavNum).OSCMPtr;
9751 :
9752 8124 : state.dataSurface->OSCM(thisOSCM).TConv = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
9753 8124 : state.dataSurface->OSCM(thisOSCM).HConv = state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen;
9754 8124 : state.dataSurface->OSCM(thisOSCM).TRad = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
9755 8124 : state.dataSurface->OSCM(thisOSCM).HRad = state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen;
9756 8124 : }
9757 :
9758 834366 : void GatherComponentLoadsSurfAbsFact(EnergyPlusData &state)
9759 : {
9760 : // SUBROUTINE INFORMATION:
9761 : // AUTHOR Jason Glazer
9762 : // DATE WRITTEN September 2012
9763 :
9764 : // PURPOSE OF THIS SUBROUTINE:
9765 : // Gather values during sizing used for surface absorption factors
9766 :
9767 : // METHODOLOGY EMPLOYED:
9768 : // Save sequence of values for report during sizing.
9769 :
9770 : // This is by surface, so it works for both space and zone component loads
9771 834366 : if (state.dataGlobal->CompLoadReportIsReq && !state.dataGlobal->isPulseZoneSizing) {
9772 36642 : int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
9773 36642 : auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
9774 2683542 : for (int jSurf = 1; jSurf <= state.dataSurface->TotSurfaces; ++jSurf) {
9775 2646900 : auto const &surface = state.dataSurface->Surface(jSurf);
9776 2646900 : if (!surface.HeatTransSurf || surface.Zone == 0) {
9777 164700 : continue; // Skip non-heat transfer surfaces
9778 : }
9779 2482200 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
9780 0 : continue; // Skip tubular daylighting device domes
9781 : }
9782 2482200 : surfCLDayTS.surf[jSurf - 1].ITABSFseq = state.dataHeatBalSurf->SurfAbsThermalInt(jSurf);
9783 2482200 : surfCLDayTS.surf[jSurf - 1].TMULTseq = state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).radThermAbsMult;
9784 : }
9785 : }
9786 834366 : }
9787 :
9788 56107751 : Real64 GetSurfIncidentSolarMultiplier(EnergyPlusData &state, int SurfNum)
9789 : {
9790 56107751 : if (!state.dataSurface->Surface(SurfNum).hasIncSolMultiplier) {
9791 56087909 : return 1.0;
9792 19842 : } else if (state.dataSurface->SurfIncSolMultiplier(SurfNum).sched != nullptr) {
9793 19842 : return state.dataSurface->SurfIncSolMultiplier(SurfNum).sched->getCurrentVal() * state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
9794 : } else {
9795 0 : return state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
9796 : }
9797 : }
9798 :
9799 803 : void InitSurfacePropertyViewFactors(EnergyPlusData &state)
9800 : {
9801 :
9802 : // purpose:
9803 : // Initializes sky and ground surfaces view factors of exterior surfaces
9804 : // used by SurfaceProperty:LocalEnvironment
9805 : // view factors are constant hence should be set only once
9806 :
9807 803 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9808 799 : return;
9809 : }
9810 4 : if (!state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
9811 0 : return;
9812 : }
9813 :
9814 414 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9815 410 : auto &Surface = state.dataSurface->Surface(SurfNum);
9816 410 : if (Surface.SurfHasSurroundingSurfProperty || Surface.IsSurfPropertyGndSurfacesDefined) {
9817 :
9818 18 : int GndSurfsNum = 0;
9819 18 : int SrdSurfsNum = 0;
9820 18 : Real64 SrdSurfsViewFactor = 0.0;
9821 18 : Real64 SurfsSkyViewFactor = 0.0;
9822 18 : Real64 GroundSurfsViewFactor = 0.0;
9823 18 : bool IsSkyViewFactorSet = false;
9824 18 : bool IsGroundViewFactorSet = false;
9825 18 : bool SetGroundViewFactorObject = false;
9826 18 : if (Surface.SurfHasSurroundingSurfProperty) {
9827 6 : SrdSurfsNum = Surface.SurfSurroundingSurfacesNum;
9828 6 : auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
9829 6 : SurfsSkyViewFactor = SrdSurfsProperty.SkyViewFactor;
9830 6 : IsSkyViewFactorSet = SrdSurfsProperty.IsSkyViewFactorSet;
9831 6 : if (SurfsSkyViewFactor > 0.0) {
9832 4 : SrdSurfsViewFactor += SurfsSkyViewFactor;
9833 : }
9834 6 : if (!Surface.IsSurfPropertyGndSurfacesDefined) {
9835 5 : SrdSurfsViewFactor += SrdSurfsProperty.GroundViewFactor;
9836 5 : IsGroundViewFactorSet = SrdSurfsProperty.IsGroundViewFactorSet;
9837 5 : GroundSurfsViewFactor = SrdSurfsProperty.GroundViewFactor;
9838 : }
9839 14 : for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
9840 8 : SrdSurfsViewFactor += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
9841 : }
9842 : }
9843 18 : if (Surface.IsSurfPropertyGndSurfacesDefined) {
9844 13 : GndSurfsNum = Surface.SurfPropertyGndSurfIndex;
9845 13 : IsGroundViewFactorSet = state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet;
9846 13 : GroundSurfsViewFactor = state.dataSurface->GroundSurfsProperty(GndSurfsNum).SurfsViewFactorSum;
9847 13 : SrdSurfsViewFactor += GroundSurfsViewFactor;
9848 : }
9849 :
9850 : // Check if the sum of all defined view factors > 1.0
9851 18 : if (SrdSurfsViewFactor > 1.0) {
9852 0 : ShowSevereError(state, format("Illegal surrounding surfaces view factors for {}.", Surface.Name));
9853 0 : ShowContinueError(state, " The sum of sky, ground, and all surrounding surfaces view factors should be less than or equal to 1.0.");
9854 : }
9855 18 : if (IsSkyViewFactorSet && IsGroundViewFactorSet) {
9856 : // If both surface sky and ground view factor defined, overwrite with the defined value
9857 4 : Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
9858 4 : Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
9859 14 : } else if (IsSkyViewFactorSet && !IsGroundViewFactorSet) {
9860 : // If only sky view factor defined, ground view factor = 1 - all other defined view factors.
9861 2 : Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
9862 2 : Surface.ViewFactorGroundIR = 1 - SrdSurfsViewFactor;
9863 2 : if (GndSurfsNum > 0) {
9864 0 : SetGroundViewFactorObject = true;
9865 0 : state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
9866 : } else {
9867 2 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
9868 : }
9869 12 : } else if (!IsSkyViewFactorSet && IsGroundViewFactorSet) {
9870 : // If only ground view factor defined, sky view factor = 1 - all other defined view factors.
9871 12 : Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
9872 12 : Surface.ViewFactorSkyIR = 1 - SrdSurfsViewFactor;
9873 12 : if (SrdSurfsNum > 0) {
9874 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
9875 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
9876 : }
9877 : } else {
9878 : // If neither ground nor sky view factor specified, continue to use the original proportion.
9879 0 : Surface.ViewFactorSkyIR *= 1 - SrdSurfsViewFactor;
9880 0 : Surface.ViewFactorGroundIR *= 1 - SrdSurfsViewFactor;
9881 0 : if (SrdSurfsNum > 0) {
9882 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
9883 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
9884 0 : if (GndSurfsNum == 0) {
9885 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
9886 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsGroundViewFactorSet = true;
9887 : }
9888 : }
9889 0 : if (GndSurfsNum > 0) {
9890 0 : SetGroundViewFactorObject = true;
9891 0 : state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
9892 : }
9893 : }
9894 18 : if (SetGroundViewFactorObject) {
9895 0 : ReSetGroundSurfacesViewFactor(state, SurfNum);
9896 : }
9897 : }
9898 : }
9899 : }
9900 :
9901 3699480 : void GetGroundSurfacesTemperatureAverage(EnergyPlusData &state)
9902 : {
9903 : // returns ground surfaces average temperature (deg C)
9904 : // ground surfaces viewed by a building exterior surface
9905 : // ground surfaces temperature weighed using view factors
9906 :
9907 3699480 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9908 3692044 : return;
9909 : }
9910 :
9911 620862 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9912 613426 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
9913 595837 : continue;
9914 : }
9915 17589 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9916 17589 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9917 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9918 0 : continue;
9919 : }
9920 17589 : Real64 GndSurfaceTemp = 0.0;
9921 17589 : Real64 GndSurfViewFactor = 0.0;
9922 17589 : Real64 GndSurfaceTempSum = 0.0;
9923 59532 : for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
9924 41943 : GndSurfViewFactor = GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor;
9925 41943 : if (GndSurfViewFactor == 0.0) {
9926 0 : continue;
9927 : }
9928 41943 : if (GndSurfsProperty.GndSurfs(gSurfNum).tempSched == nullptr) {
9929 1353 : continue;
9930 : }
9931 40590 : GndSurfaceTemp = GndSurfsProperty.GndSurfs(gSurfNum).tempSched->getCurrentVal();
9932 40590 : GndSurfaceTempSum += GndSurfViewFactor * pow_4(GndSurfaceTemp + Constant::Kelvin);
9933 : }
9934 17589 : if (GndSurfaceTempSum == 0.0) {
9935 1353 : GndSurfsProperty.SurfsTempAvg = 0.0;
9936 1353 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9937 1353 : continue;
9938 : }
9939 16236 : GndSurfsProperty.SurfsTempAvg = root_4(GndSurfaceTempSum / GndSurfsProperty.SurfsViewFactorSum) - Constant::Kelvin;
9940 : }
9941 : }
9942 :
9943 2800078 : void GetGroundSurfacesReflectanceAverage(EnergyPlusData &state)
9944 : {
9945 : // returns ground surfaces average reflectance (dimensionless)
9946 : // ground reflectance viewed by a building exterior surface
9947 : // ground surfaces reflectance weighed using view factors
9948 :
9949 2800078 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9950 2792642 : return;
9951 : }
9952 620862 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9953 :
9954 613426 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
9955 595837 : continue;
9956 : }
9957 17589 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9958 17589 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9959 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9960 0 : continue;
9961 : }
9962 17589 : Real64 GndSurfRefl = 0.0;
9963 17589 : Real64 GndSurfsReflSum = 0.0;
9964 59532 : for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
9965 41943 : if (GndSurfsProperty.GndSurfs(gSurfNum).reflSched == nullptr) {
9966 1353 : continue;
9967 : }
9968 40590 : GndSurfRefl = GndSurfsProperty.GndSurfs(gSurfNum).reflSched->getCurrentVal();
9969 40590 : GndSurfsReflSum += GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor * GndSurfRefl;
9970 : }
9971 17589 : if (GndSurfsReflSum == 0.0) {
9972 1353 : GndSurfsProperty.SurfsReflAvg = 0.0;
9973 1353 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9974 1353 : continue;
9975 : }
9976 16236 : GndSurfsProperty.SurfsReflAvg = GndSurfsReflSum / GndSurfsProperty.SurfsViewFactorSum;
9977 : }
9978 : }
9979 :
9980 0 : void ReSetGroundSurfacesViewFactor(EnergyPlusData &state, int const SurfNum)
9981 : {
9982 : // resets ground view factors based on view factors identity
9983 : // the ground view factor value is set to the first element
9984 : // when the ground view factor input field is blank
9985 :
9986 0 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
9987 0 : return;
9988 : }
9989 0 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9990 0 : GndSurfsProperty.SurfsViewFactorSum = state.dataSurface->Surface(SurfNum).ViewFactorGroundIR;
9991 :
9992 0 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9993 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9994 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9995 0 : return;
9996 : }
9997 0 : GndSurfsProperty.GndSurfs(1).ViewFactor = GndSurfsProperty.SurfsViewFactorSum;
9998 : }
9999 :
10000 3699480 : void GetSurroundingSurfacesTemperatureAverage(EnergyPlusData &state)
10001 : {
10002 : // returns surrounding surfaces average temperature (deg C)
10003 : // surrounding surfaces viewed by an exterior surface
10004 : // surrounding surfaces temperature weighed using view factors
10005 :
10006 3699480 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
10007 3692044 : return;
10008 : }
10009 :
10010 620862 : for (auto &surface : state.dataSurface->Surface) {
10011 613426 : if (!surface.SurfHasSurroundingSurfProperty) {
10012 605308 : continue;
10013 : }
10014 : // local vars
10015 8118 : Real64 SrdSurfaceTemp = 0.0;
10016 8118 : Real64 SrdSurfaceTempSum = 0.0;
10017 8118 : auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(surface.SurfSurroundingSurfacesNum);
10018 18942 : for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
10019 10824 : SrdSurfaceTemp = SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() + Constant::Kelvin;
10020 10824 : SrdSurfaceTempSum += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor * pow_4(SrdSurfaceTemp);
10021 : }
10022 8118 : surface.SrdSurfTemp = root_4(SrdSurfaceTempSum / surface.ViewFactorSrdSurfs) - Constant::Kelvin;
10023 7436 : }
10024 : }
10025 : } // namespace EnergyPlus::HeatBalanceSurfaceManager
|