Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <algorithm>
50 : #include <cassert>
51 : #include <cmath>
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Array.functions.hh>
54 : #include <ObjexxFCL/Array1D.hh>
55 : #include <ObjexxFCL/Array2D.hh>
56 : #include <ObjexxFCL/Fmath.hh>
57 : #include <ObjexxFCL/string.functions.hh>
58 :
59 : // EnergyPlus Headers
60 : #include <AirflowNetwork/Solver.hpp>
61 : #include <EnergyPlus/ChilledCeilingPanelSimple.hh>
62 : #include <EnergyPlus/Construction.hh>
63 : #include <EnergyPlus/ConvectionCoefficients.hh>
64 : #include <EnergyPlus/CurveManager.hh>
65 : #include <EnergyPlus/Data/EnergyPlusData.hh>
66 : #include <EnergyPlus/DataContaminantBalance.hh>
67 : #include <EnergyPlus/DataDaylighting.hh>
68 : #include <EnergyPlus/DataDaylightingDevices.hh>
69 : #include <EnergyPlus/DataEnvironment.hh>
70 : #include <EnergyPlus/DataHeatBalFanSys.hh>
71 : #include <EnergyPlus/DataHeatBalSurface.hh>
72 : #include <EnergyPlus/DataHeatBalance.hh>
73 : #include <EnergyPlus/DataLoopNode.hh>
74 : #include <EnergyPlus/DataMoistureBalance.hh>
75 : #include <EnergyPlus/DataMoistureBalanceEMPD.hh>
76 : #include <EnergyPlus/DataRoomAirModel.hh>
77 : #include <EnergyPlus/DataRuntimeLanguage.hh>
78 : #include <EnergyPlus/DataSizing.hh>
79 : #include <EnergyPlus/DataSurfaces.hh>
80 : #include <EnergyPlus/DataSystemVariables.hh>
81 : #include <EnergyPlus/DataViewFactorInformation.hh>
82 : #include <EnergyPlus/DataWindowEquivalentLayer.hh>
83 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
84 : #include <EnergyPlus/DataZoneEquipment.hh>
85 : #include <EnergyPlus/DaylightingDevices.hh>
86 : #include <EnergyPlus/DaylightingManager.hh>
87 : #include <EnergyPlus/DisplayRoutines.hh>
88 : #include <EnergyPlus/EcoRoofManager.hh>
89 : #include <EnergyPlus/ElectricBaseboardRadiator.hh>
90 : #include <EnergyPlus/ExtendedHeatIndex.hh>
91 : #include <EnergyPlus/FileSystem.hh>
92 : #include <EnergyPlus/HWBaseboardRadiator.hh>
93 : #include <EnergyPlus/HeatBalFiniteDiffManager.hh>
94 : #include <EnergyPlus/HeatBalanceAirManager.hh>
95 : #include <EnergyPlus/HeatBalanceHAMTManager.hh>
96 : #include <EnergyPlus/HeatBalanceIntRadExchange.hh>
97 : #include <EnergyPlus/HeatBalanceKivaManager.hh>
98 : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
99 : #include <EnergyPlus/HighTempRadiantSystem.hh>
100 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
101 : #include <EnergyPlus/InternalHeatGains.hh>
102 : #include <EnergyPlus/LowTempRadiantSystem.hh>
103 : #include <EnergyPlus/MoistureBalanceEMPDManager.hh>
104 : #include <EnergyPlus/OutputProcessor.hh>
105 : #include <EnergyPlus/OutputReportPredefined.hh>
106 : #include <EnergyPlus/OutputReportTabular.hh>
107 : #include <EnergyPlus/Psychrometrics.hh>
108 : #include <EnergyPlus/ScheduleManager.hh>
109 : #include <EnergyPlus/SolarShading.hh>
110 : #include <EnergyPlus/SteamBaseboardRadiator.hh>
111 : #include <EnergyPlus/SurfaceGeometry.hh>
112 : #include <EnergyPlus/SwimmingPool.hh>
113 : #include <EnergyPlus/ThermalComfort.hh>
114 : #include <EnergyPlus/TranspiredCollector.hh>
115 : #include <EnergyPlus/UtilityRoutines.hh>
116 : #include <EnergyPlus/WindowComplexManager.hh>
117 : #include <EnergyPlus/WindowEquivalentLayer.hh>
118 : #include <EnergyPlus/WindowManager.hh>
119 : #include <EnergyPlus/WindowManagerExteriorData.hh>
120 : #include <EnergyPlus/WindowManagerExteriorThermal.hh>
121 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
122 : #include <WCECommon.hpp>
123 : #include <WCEMultiLayerOptics.hpp>
124 : #include <WCESingleLayerOptics.hpp>
125 : #include <WCETarcog.hpp>
126 :
127 : namespace EnergyPlus::HeatBalanceSurfaceManager {
128 :
129 : // Module containing the routines dealing with the Heat Balance of the surfaces
130 :
131 : // MODULE INFORMATION:
132 : // MODIFIED DJS (PSU Dec 2006) to add ecoroof
133 :
134 : // PURPOSE OF THIS MODULE:
135 : // To encapsulate the data and algorithms required to
136 : // manage the simulation of the surface heat balance for the building.
137 :
138 : // REFERENCES:
139 : // The heat balance method is outlined in the "TARP Reference Manual", NIST, NBSIR 83-2655, Feb 1983.
140 : // The methods are also summarized in many BSO Theses and papers.
141 :
142 : // OTHER NOTES:
143 : // This module was created from IBLAST subroutines
144 :
145 249946 : void ManageSurfaceHeatBalance(EnergyPlusData &state)
146 : {
147 :
148 : // SUBROUTINE INFORMATION:
149 : // AUTHOR Richard Liesen
150 : // DATE WRITTEN January 1998
151 :
152 : // PURPOSE OF THIS SUBROUTINE:
153 : // This subroutine manages the heat surface balance method of calculating
154 : // building thermal loads. It is called from the HeatBalanceManager
155 : // at the time step level. This driver manages the calls to all of
156 : // the other drivers and simulation algorithms.
157 :
158 249946 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
159 103 : DisplayString(state, "Initializing Surfaces");
160 : }
161 249946 : 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 249946 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
166 103 : DisplayString(state, "Calculate Outside Surface Heat Balance");
167 : }
168 249946 : CalcHeatBalanceOutsideSurf(state);
169 249946 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
170 103 : DisplayString(state, "Calculate Inside Surface Heat Balance");
171 : }
172 249946 : 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 249946 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
177 103 : DisplayString(state, "Calculate Air Heat Balance");
178 : }
179 249946 : 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 249945 : UpdateFinalSurfaceHeatBalance(state);
185 :
186 : // Before we leave the Surface Manager the thermal histories need to be updated
187 249945 : if (state.dataHeatBal->AnyCTF || state.dataHeatBal->AnyEMPD) {
188 200973 : UpdateThermalHistories(state); // Update the thermal histories
189 : }
190 :
191 249945 : if (state.dataHeatBal->AnyCondFD) {
192 342804 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
193 293832 : auto const &surface = state.dataSurface->Surface(SurfNum);
194 293832 : int const ConstrNum = surface.Construction;
195 293832 : if (ConstrNum <= 0) {
196 0 : continue; // Shading surface, not really a heat transfer surface
197 : }
198 293832 : if (state.dataConstruction->Construct(ConstrNum).TypeIsWindow) {
199 0 : continue; // Windows simulated in Window module
200 : }
201 293832 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CondFD) {
202 0 : continue;
203 : }
204 293832 : state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).UpdateMoistureBalance();
205 : }
206 : }
207 :
208 249945 : ThermalComfort::ManageThermalComfort(state, false); // "Record keeping" for the zone
209 :
210 249945 : ReportSurfaceHeatBalance(state);
211 249945 : if (state.dataGlobal->ZoneSizingCalc) {
212 83022 : OutputReportTabular::GatherComponentLoadsSurface(state);
213 : }
214 :
215 249945 : CalcThermalResilience(state);
216 :
217 249945 : if (state.dataOutRptTab->displayThermalResilienceSummary) {
218 69935 : ReportThermalResilience(state);
219 : }
220 :
221 249945 : if (state.dataOutRptTab->displayCO2ResilienceSummary) {
222 38 : ReportCO2Resilience(state);
223 : }
224 :
225 249945 : if (state.dataOutRptTab->displayVisualResilienceSummary) {
226 38 : ReportVisualResilience(state);
227 : }
228 :
229 249945 : state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime = false;
230 249945 : }
231 :
232 : // Beginning Initialization Section of the Module
233 : //******************************************************************************
234 :
235 249957 : void UpdateVariableAbsorptances(EnergyPlusData &state)
236 : {
237 249957 : auto &s_mat = state.dataMaterial;
238 249960 : for (int surfNum : state.dataSurface->AllVaryAbsOpaqSurfaceList) {
239 3 : auto const &thisConstruct = state.dataConstruction->Construct(state.dataSurface->Surface(surfNum).Construction);
240 3 : auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
241 3 : assert(thisMaterial != nullptr);
242 3 : if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::Scheduled) {
243 1 : if (thisMaterial->absorpThermalVarSched != nullptr) {
244 1 : state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
245 : }
246 1 : 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 2 : if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceTemperature) {
252 2 : 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 2 : if (thisMaterial->absorpThermalVarCurve != nullptr) {
261 2 : state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) =
262 2 : max(min(thisMaterial->absorpThermalVarCurve->value(state, triggerValue), 0.9999), 0.0001);
263 : }
264 2 : if (thisMaterial->absorpSolarVarCurve != nullptr) {
265 2 : state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) =
266 2 : max(min(thisMaterial->absorpSolarVarCurve->value(state, triggerValue), 0.9999), 0.0001);
267 : }
268 : }
269 249957 : }
270 249957 : }
271 :
272 249956 : 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 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
300 112 : 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 249956 : DataSurfaces::SetSurfaceOutBulbTempAt(state);
312 249956 : DataSurfaces::CheckSurfaceOutBulbTempAt(state);
313 :
314 249956 : DataSurfaces::SetSurfaceWindSpeedAt(state);
315 249956 : DataSurfaces::SetSurfaceWindDirAt(state);
316 249956 : if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
317 21 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
318 18 : if (state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode > 0) {
319 1 : auto const &linkedNode = state.dataLoopNodes->Node(state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode);
320 1 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) = linkedNode.OutAirDryBulb;
321 1 : state.dataSurface->SurfOutWetBulbTemp(SurfNum) = linkedNode.OutAirWetBulb;
322 1 : state.dataSurface->SurfOutWindSpeed(SurfNum) = linkedNode.OutAirWindSpeed;
323 1 : state.dataSurface->SurfOutWindDir(SurfNum) = linkedNode.OutAirWindDir;
324 : }
325 : }
326 : }
327 : // Overwriting surface and zone level environmental data with EMS override value
328 249956 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
329 867072 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
330 750999 : if (state.dataSurface->SurfOutDryBulbTempEMSOverrideOn(SurfNum)) {
331 0 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) = state.dataSurface->SurfOutDryBulbTempEMSOverrideValue(SurfNum);
332 : }
333 750999 : if (state.dataSurface->SurfOutWetBulbTempEMSOverrideOn(SurfNum)) {
334 0 : state.dataSurface->SurfOutWetBulbTemp(SurfNum) = state.dataSurface->SurfOutWetBulbTempEMSOverrideValue(SurfNum);
335 : }
336 750999 : if (state.dataSurface->SurfWindSpeedEMSOverrideOn(SurfNum)) {
337 0 : state.dataSurface->SurfOutWindSpeed(SurfNum) = state.dataSurface->SurfWindSpeedEMSOverrideValue(SurfNum);
338 : }
339 750999 : if (state.dataSurface->SurfWindDirEMSOverrideOn(SurfNum)) {
340 0 : state.dataSurface->SurfOutWindDir(SurfNum) = state.dataSurface->SurfWindDirEMSOverrideValue(SurfNum);
341 : }
342 750999 : if (state.dataSurface->SurfViewFactorGroundEMSOverrideOn(SurfNum)) {
343 1354 : state.dataSurface->Surface(SurfNum).ViewFactorGround = state.dataSurface->SurfViewFactorGroundEMSOverrideValue(SurfNum);
344 : }
345 : }
346 : }
347 :
348 : // Do the Begin Simulation initializations
349 249956 : if (state.dataGlobal->BeginSimFlag) {
350 112 : AllocateSurfaceHeatBalArrays(state); // Allocate the Module Arrays before any inits take place
351 224 : state.dataHeatBalSurf->InterZoneWindow =
352 112 : std::any_of(state.dataViewFactor->EnclSolInfo.begin(),
353 224 : state.dataViewFactor->EnclSolInfo.end(),
354 140 : [](DataViewFactorInformation::EnclosureViewFactorInformation const &e) { return e.HasInterZoneWindow; });
355 : }
356 249956 : if (state.dataGlobal->BeginSimFlag || state.dataGlobal->AnySurfPropOverridesInModel) {
357 244 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
358 281 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
359 149 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
360 149 : int const firstSurf = thisSpace.HTSurfaceFirst;
361 149 : int const lastSurf = thisSpace.HTSurfaceLast;
362 941 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
363 792 : int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // SurfActiveConstruction set above
364 792 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
365 792 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
366 792 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
367 792 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisConstruct.OutsideRoughness;
368 792 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisConstruct.OutsideAbsorpSolar;
369 792 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisConstruct.OutsideAbsorpThermal;
370 : }
371 132 : }
372 : }
373 : }
374 :
375 : // variable thermal solar absorptance overrides
376 249956 : UpdateVariableAbsorptances(state);
377 :
378 : // Do the Begin Environment initializations
379 249956 : if (state.dataGlobal->BeginEnvrnFlag) {
380 483 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
381 103 : DisplayString(state, "Initializing Temperature and Flux Histories");
382 : }
383 483 : InitThermalAndFluxHistories(state); // Set initial temperature and flux histories
384 : }
385 :
386 : // Calc movable insulation properties
387 249956 : if (state.dataSurface->AnyMovableInsulation) {
388 0 : EvalOutsideMovableInsulation(state);
389 0 : 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 249956 : 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 249956 : SolarShading::TimestepInitComplexFenestration(state);
400 :
401 : // Calculate exterior-surface multipliers that account for anisotropy of
402 : // sky radiance
403 249956 : if (state.dataEnvrn->SunIsUp && state.dataEnvrn->DifSolarRad > 0.0) {
404 71212 : SolarShading::AnisoSkyViewFactors(state);
405 : } else {
406 178744 : 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 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
412 112 : DisplayString(state, "Initializing Window Shading");
413 : }
414 :
415 249956 : SolarShading::WindowShadingManager(state);
416 :
417 249956 : 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 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
422 112 : DisplayString(state, "Computing Interior Absorption Factors");
423 : }
424 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
425 112 : HeatBalanceIntRadExchange::InitInteriorRadExchange(state);
426 : }
427 249956 : ComputeIntThermalAbsorpFactors(state);
428 :
429 : // Calculate factors for diffuse solar absorbed by room surfaces and interior shades
430 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
431 112 : DisplayString(state, "Computing Interior Diffuse Solar Absorption Factors");
432 : }
433 249956 : ComputeIntSWAbsorpFactors(state);
434 :
435 249956 : if (state.dataHeatBalSurf->InterZoneWindow) {
436 1 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
437 0 : DisplayString(state, "Computing Interior Diffuse Solar Exchange through Interzone Windows");
438 : }
439 1 : ComputeDifSolExcZonesWIZWindows(state);
440 : }
441 :
442 249956 : Dayltg::initDaylighting(state, state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime);
443 :
444 499912 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
445 249956 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, "Main");
446 :
447 249956 : if (state.dataSurface->AirflowWindows) {
448 0 : 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 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
454 112 : DisplayString(state, "Initializing Solar Heat Gains");
455 : }
456 :
457 249956 : InitSolarHeatGains(state);
458 :
459 249956 : Dayltg::manageDaylighting(state);
460 :
461 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
462 112 : DisplayString(state, "Initializing Internal Heat Gains");
463 : }
464 249956 : InternalHeatGains::ManageInternalHeatGains(state, false);
465 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
466 112 : DisplayString(state, "Initializing Interior Solar Distribution");
467 : }
468 249956 : InitIntSolarDistribution(state);
469 :
470 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
471 112 : DisplayString(state, "Initializing Interior Convection Coefficients");
472 : }
473 249956 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempInTmp);
474 :
475 249956 : if (state.dataGlobal->BeginSimFlag) { // Now's the time to report surfaces, if desired
476 : // if (firstTime) CALL DisplayString('Reporting Surfaces')
477 : // CALL ReportSurfaces
478 112 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
479 112 : DisplayString(state, "Gathering Information for Predefined Reporting");
480 : }
481 112 : GatherForPredefinedReport(state);
482 : }
483 :
484 : // Initialize the temperature history terms for conduction through the surfaces
485 249956 : if (state.dataHeatBal->AnyCondFD) {
486 48972 : HeatBalFiniteDiffManager::InitHeatBalFiniteDiff(state);
487 : }
488 :
489 586606 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
490 706903 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
491 370253 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
492 370253 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
493 370253 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
494 2350605 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
495 1980352 : auto const &surface = state.dataSurface->Surface(SurfNum);
496 1980352 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
497 293832 : surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) {
498 293832 : 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 1686520 : int const ConstrNum = surface.Construction;
504 1686520 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
505 1686520 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) = 0.0;
506 1686520 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) = 0.0;
507 1686520 : if (construct.NumCTFTerms <= 1) {
508 626878 : continue;
509 : }
510 :
511 7592810 : 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 6533168 : Real64 const ctf_cross(construct.CTFCross[Term]);
523 :
524 6533168 : Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
525 6533168 : Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
526 6533168 : Real64 const QH11(state.dataHeatBalSurf->SurfOutsideFluxHist(Term + 1)(SurfNum));
527 6533168 : Real64 const QH12(state.dataHeatBalSurf->SurfInsideFluxHist(Term + 1)(SurfNum));
528 6533168 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) +=
529 6533168 : ctf_cross * TH11 - construct.CTFInside[Term] * TH12 + construct.CTFFlux[Term] * QH12;
530 :
531 6533168 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) +=
532 6533168 : construct.CTFOutside[Term] * TH11 - ctf_cross * TH12 + construct.CTFFlux[Term] * QH11;
533 : }
534 : }
535 336650 : }
536 : }
537 249956 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
538 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
539 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
540 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
541 0 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
542 0 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
543 0 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
544 0 : auto const &surface = state.dataSurface->Surface(SurfNum);
545 0 : int const ConstrNum = surface.Construction;
546 0 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
547 0 : if (!construct.SourceSinkPresent) {
548 0 : continue;
549 : }
550 0 : if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
551 0 : surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) {
552 0 : continue;
553 : }
554 0 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) = 0.0;
555 0 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) = 0.0;
556 0 : if (construct.NumCTFTerms <= 1) {
557 0 : continue;
558 : }
559 0 : for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
560 0 : Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
561 0 : Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
562 0 : Real64 const QsrcHist1(state.dataHeatBalSurf->SurfQsrcHist(SurfNum, Term + 1));
563 :
564 0 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += construct.CTFSourceIn[Term] * QsrcHist1;
565 :
566 0 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += construct.CTFSourceOut[Term] * QsrcHist1;
567 :
568 0 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) +=
569 0 : construct.CTFTSourceOut[Term] * TH11 + construct.CTFTSourceIn[Term] * TH12 + construct.CTFTSourceQ[Term] * QsrcHist1 +
570 0 : construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTsrcHist(SurfNum, Term + 1);
571 :
572 0 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) +=
573 0 : construct.CTFTUserOut[Term] * TH11 + construct.CTFTUserIn[Term] * TH12 + construct.CTFTUserSource[Term] * QsrcHist1 +
574 0 : construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTuserHist(SurfNum, Term + 1);
575 : }
576 : }
577 0 : } // ...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 586606 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
583 706903 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
584 370253 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
585 370253 : int const firstSurf = thisSpace.HTSurfaceFirst;
586 370253 : int const lastSurf = thisSpace.HTSurfaceLast;
587 2439169 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
588 2068916 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) = 0.0;
589 2068916 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) = 0.0;
590 2068916 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) = 0.0;
591 2068916 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = 0.0;
592 2068916 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = 0.0;
593 2068916 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = 0.0;
594 :
595 2068916 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
596 2068916 : state.dataHeatBalFanSys->QPVSysSource(SurfNum) = 0.0;
597 2068916 : state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = 0.0;
598 2068916 : state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = 0.0;
599 :
600 : } // ...end of Zone Surf loop
601 336650 : }
602 : } // ...end of Zone loop
603 :
604 249980 : for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
605 24 : auto &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
606 24 : thisSurfQRadFromHVAC.HTRadSys = 0.0;
607 24 : thisSurfQRadFromHVAC.HWBaseboard = 0.0;
608 24 : thisSurfQRadFromHVAC.SteamBaseboard = 0.0;
609 24 : thisSurfQRadFromHVAC.ElecBaseboard = 0.0;
610 24 : thisSurfQRadFromHVAC.CoolingPanel = 0.0;
611 249956 : }
612 :
613 249956 : if (state.dataGlobal->ZoneSizingCalc) {
614 83022 : GatherComponentLoadsSurfAbsFact(state);
615 : }
616 :
617 249956 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
618 112 : DisplayString(state, "Completed Initializing Surface Heat Balance");
619 : }
620 249956 : state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime = false;
621 249956 : }
622 :
623 114 : 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 114 : 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 114 : int SurfaceClassCount = int(DataSurfaces::SurfaceClass::Num);
645 114 : Array1D_int numSurfaces(SurfaceClassCount);
646 114 : Array1D_int numExtSurfaces(SurfaceClassCount);
647 : int frameDivNum;
648 : bool isExterior;
649 114 : 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 114 : Real64 windowAreaWMult(0.0);
661 114 : Real64 fenTotArea(0.0);
662 114 : Real64 fenTotAreaNorth(0.0);
663 114 : Real64 fenTotAreaNonNorth(0.0);
664 114 : Real64 ufactArea(0.0);
665 114 : Real64 ufactAreaNorth(0.0);
666 114 : Real64 ufactAreaNonNorth(0.0);
667 114 : Real64 shgcArea(0.0);
668 114 : Real64 shgcAreaNorth(0.0);
669 114 : Real64 shgcAreaNonNorth(0.0);
670 114 : Real64 vistranArea(0.0);
671 114 : Real64 vistranAreaNorth(0.0);
672 114 : Real64 vistranAreaNonNorth(0.0);
673 114 : Real64 intFenTotArea(0.0);
674 114 : Real64 intUfactArea(0.0);
675 114 : Real64 intShgcArea(0.0);
676 114 : Real64 intVistranArea(0.0);
677 : bool isNorth;
678 :
679 114 : 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 114 : 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 114 : 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 114 : 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 114 : 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 114 : 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 114 : numSurfaces = 0;
769 114 : numExtSurfaces = 0;
770 :
771 114 : computedNetArea.allocate(state.dataSurface->TotSurfaces);
772 114 : computedNetArea = 0.0; // start at zero, add wall area and subtract window and door area
773 :
774 : // set up for EIO <FenestrationAssembly> output
775 114 : if (state.dataHeatBal->TotFrameDivider > 0 && state.dataGeneral->Constructions) {
776 0 : 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 114 : std::vector<std::pair<int, int>> uniqConsFrame;
783 114 : std::pair<int, int> consAndFrame;
784 :
785 : // set up for EIO <FenestrationShadedState> output
786 114 : bool fenestrationShadedStateHeaderShown(false);
787 : static constexpr std::string_view FenestrationShadedStateFormat("FenestrationShadedState,{},{:.3R},{:.3R},{:.3R},{},{},{:.3R},{:.3R},{:.3R}\n");
788 114 : std::vector<std::pair<int, int>> uniqShdConsFrame;
789 114 : std::pair<int, int> shdConsAndFrame;
790 :
791 948 : for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
792 834 : auto &surface = state.dataSurface->Surface(iSurf);
793 834 : surfName = surface.Name;
794 : // only exterior surfaces including underground
795 834 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
796 216 : (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
797 618 : isExterior = true;
798 618 : switch (surface.Class) {
799 543 : case DataSurfaces::SurfaceClass::Wall:
800 : case DataSurfaces::SurfaceClass::Floor:
801 : case DataSurfaces::SurfaceClass::Roof: {
802 543 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
803 543 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
804 543 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
805 543 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
806 543 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpCons, surfName, construct.Name);
807 543 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpZone, surfName, thisZone.Name);
808 543 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpSpace, surfName, thisSpace.Name);
809 543 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
810 543 : OutputReportPredefined::PreDefTableEntry(
811 543 : state, state.dataOutRptPredefined->pdchOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
812 543 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpGrArea, surfName, surface.GrossArea * mult);
813 543 : computedNetArea(iSurf) += surface.GrossArea * mult;
814 543 : 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 543 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
818 543 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpAzimuth, surfName, curAzimuth);
819 543 : curTilt = surface.Tilt;
820 543 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpTilt, surfName, curTilt);
821 543 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
822 362 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
823 80 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "N");
824 282 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
825 82 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "E");
826 200 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
827 121 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "S");
828 79 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
829 79 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "W");
830 : }
831 : }
832 543 : } break;
833 58 : case DataSurfaces::SurfaceClass::Window:
834 : case DataSurfaces::SurfaceClass::TDD_Dome: {
835 58 : auto &construct = state.dataConstruction->Construct(surface.Construction);
836 58 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
837 58 : mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
838 58 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
839 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenCons, surfName, construct.Name);
840 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenZone, surfName, thisZone.Name);
841 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSpace, surfName, thisSpace.Name);
842 : // if the construction report is requested the SummerSHGC is already calculated
843 58 : if (construct.SummerSHGC != 0) {
844 39 : SHGCSummer = construct.SummerSHGC;
845 39 : TransVisNorm = construct.VisTransNorm;
846 : } else {
847 : // must calculate Summer SHGC
848 19 : if (!construct.WindowTypeEQL) {
849 19 : Window::CalcNominalWindowCond(state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
850 19 : construct.SummerSHGC = SHGCSummer;
851 19 : construct.VisTransNorm = TransVisNorm;
852 19 : construct.SolTransNorm = TransSolNorm;
853 : }
854 : }
855 : // include the frame area if present
856 58 : windowArea = surface.GrossArea;
857 58 : frameArea = 0.0;
858 58 : dividerArea = 0.0;
859 58 : frameDivNum = surface.FrameDivider;
860 58 : if (frameDivNum != 0) {
861 3 : auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
862 3 : frameWidth = frameDivider.FrameWidth;
863 3 : frameArea = (surface.Height + 2.0 * frameWidth) * (surface.Width + 2.0 * frameWidth) - (surface.Height * surface.Width);
864 3 : windowArea += frameArea;
865 3 : dividerArea = frameDivider.DividerWidth * (frameDivider.HorDividers * surface.Width + frameDivider.VertDividers * surface.Height -
866 3 : frameDivider.HorDividers * frameDivider.VertDividers * frameDivider.DividerWidth);
867 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameDivName, surfName, frameDivider.Name);
868 3 : OutputReportPredefined::PreDefTableEntry(
869 3 : state, state.dataOutRptPredefined->pdchFenFrameConductance, surfName, frameDivider.FrameConductance, 3);
870 3 : OutputReportPredefined::PreDefTableEntry(
871 3 : 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 3 : std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
875 3 : const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
876 3 : const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
877 3 : const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
878 :
879 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemNfrcType, surfName, NFRCname);
880 :
881 3 : Real64 uValueAssembly = 0.0;
882 3 : Real64 shgcAssembly = 0.0;
883 3 : Real64 vtAssembly = 0.0;
884 :
885 3 : Window::GetWindowAssemblyNfrcForReport(
886 : state, iSurf, surface.Construction, windowWidth, windowHeight, vision, uValueAssembly, shgcAssembly, vtAssembly);
887 3 : 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 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemUfact, surfName, uValueAssembly, 3);
893 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemSHGC, surfName, shgcAssembly, 3);
894 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemVisTr, surfName, vtAssembly, 3);
895 :
896 : // output EIO <FenestrationAssembly> for each unique combination of construction and frame/divider
897 3 : if (state.dataGeneral->Constructions) {
898 0 : consAndFrame = std::make_pair(surface.Construction, frameDivNum);
899 0 : if (std::find(uniqConsFrame.begin(), uniqConsFrame.end(), consAndFrame) == uniqConsFrame.end()) {
900 0 : uniqConsFrame.push_back(consAndFrame);
901 0 : print(state.files.eio,
902 : FenestrationAssemblyFormat,
903 0 : construct.Name,
904 0 : frameDivider.Name,
905 : NFRCname,
906 : uValueAssembly,
907 : shgcAssembly,
908 : vtAssembly);
909 : }
910 : }
911 : }
912 58 : windowAreaWMult = windowArea * mult;
913 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAreaOf1, surfName, windowArea);
914 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameAreaOf1, surfName, frameArea);
915 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDividerAreaOf1, surfName, dividerArea);
916 116 : OutputReportPredefined::PreDefTableEntry(
917 58 : state, state.dataOutRptPredefined->pdchFenGlassAreaOf1, surfName, windowArea - (frameArea + dividerArea));
918 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, surfName, windowAreaWMult);
919 58 : computedNetArea(surface.BaseSurf) -= windowAreaWMult;
920 58 : nomUfact = state.dataHeatBal->NominalU(surface.Construction);
921 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, surfName, nomUfact, 3);
922 :
923 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, surfName, SHGCSummer, 3);
924 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, surfName, TransVisNorm, 3);
925 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenParent, surfName, surface.BaseSurfName);
926 58 : curAzimuth = surface.Azimuth;
927 : // Round to two decimals, like the display in tables
928 58 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
929 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAzimuth, surfName, curAzimuth);
930 58 : isNorth = false;
931 58 : curTilt = surface.Tilt;
932 58 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenTilt, surfName, curTilt);
933 58 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
934 55 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
935 11 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "N");
936 11 : isNorth = true;
937 44 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
938 9 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "E");
939 35 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
940 29 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "S");
941 6 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
942 6 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "W");
943 : }
944 : }
945 :
946 : // Report table for every shading control state
947 58 : const unsigned int totalStates = surface.windowShadingControlList.size();
948 58 : if (frameDivNum != 0) {
949 3 : auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
950 3 : for (unsigned int i = 0; i < totalStates; ++i) {
951 0 : const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
952 0 : const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
953 0 : const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
954 :
955 0 : const int stateConstrNum = surface.shadedConstructionList[i];
956 0 : const Real64 stateUValue = Window::GetIGUUValueForNFRCReport(state, iSurf, stateConstrNum, windowWidth, windowHeight);
957 0 : const Real64 stateSHGC = Window::GetSHGCValueForNFRCReporting(state, iSurf, stateConstrNum, windowWidth, windowHeight);
958 0 : std::string const &constructionName = state.dataConstruction->Construct(stateConstrNum).Name;
959 :
960 0 : OutputReportPredefined::PreDefTableEntry(
961 0 : state, state.dataOutRptPredefined->pdchFenShdFrameDiv, constructionName, frameDivider.Name);
962 0 : OutputReportPredefined::PreDefTableEntry(
963 0 : state, state.dataOutRptPredefined->pdchFenShdUfact, constructionName, stateUValue, 3);
964 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenShdSHGC, constructionName, stateSHGC, 3);
965 0 : OutputReportPredefined::PreDefTableEntry(state,
966 0 : state.dataOutRptPredefined->pdchFenShdVisTr,
967 : constructionName,
968 0 : state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
969 0 : 3);
970 :
971 0 : Real64 stateAssemblyUValue{0.0};
972 0 : Real64 stateAssemblySHGC{0.0};
973 0 : Real64 stateAssemblyVT{0.0};
974 :
975 0 : Window::GetWindowAssemblyNfrcForReport(
976 : state, iSurf, stateConstrNum, windowWidth, windowHeight, vision, stateAssemblyUValue, stateAssemblySHGC, stateAssemblyVT);
977 :
978 0 : std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
979 0 : OutputReportPredefined::PreDefTableEntry(
980 0 : state, state.dataOutRptPredefined->pdchFenShdAssemNfrcType, constructionName, NFRCname);
981 :
982 0 : OutputReportPredefined::PreDefTableEntry(
983 0 : state, state.dataOutRptPredefined->pdchFenShdAssemUfact, constructionName, stateAssemblyUValue, 3);
984 0 : OutputReportPredefined::PreDefTableEntry(
985 0 : state, state.dataOutRptPredefined->pdchFenShdAssemSHGC, constructionName, stateAssemblySHGC, 3);
986 0 : OutputReportPredefined::PreDefTableEntry(
987 0 : state, state.dataOutRptPredefined->pdchFenShdAssemVisTr, constructionName, stateAssemblyVT, 3);
988 :
989 0 : if (state.dataGeneral->Constructions) {
990 0 : if (!fenestrationShadedStateHeaderShown) {
991 0 : 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 0 : fenestrationShadedStateHeaderShown = true;
997 : }
998 :
999 0 : shdConsAndFrame = std::make_pair(stateConstrNum, frameDivNum);
1000 0 : if (std::find(uniqShdConsFrame.begin(), uniqShdConsFrame.end(), shdConsAndFrame) == uniqShdConsFrame.end()) {
1001 0 : uniqShdConsFrame.push_back(shdConsAndFrame);
1002 0 : print(state.files.eio,
1003 : FenestrationShadedStateFormat,
1004 : constructionName,
1005 : stateUValue,
1006 : stateSHGC,
1007 0 : state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
1008 0 : frameDivider.Name,
1009 : NFRCname,
1010 : stateAssemblyUValue,
1011 : stateAssemblySHGC,
1012 : stateAssemblyVT);
1013 : }
1014 : }
1015 : }
1016 : }
1017 :
1018 58 : curWSC = surface.activeWindowShadingControl;
1019 : // compute totals for area weighted averages
1020 58 : fenTotArea += windowAreaWMult;
1021 58 : ufactArea += nomUfact * windowAreaWMult;
1022 58 : shgcArea += SHGCSummer * windowAreaWMult;
1023 58 : vistranArea += TransVisNorm * windowAreaWMult;
1024 58 : if (isNorth) {
1025 11 : fenTotAreaNorth += windowAreaWMult;
1026 11 : ufactAreaNorth += nomUfact * windowAreaWMult;
1027 11 : shgcAreaNorth += SHGCSummer * windowAreaWMult;
1028 11 : vistranAreaNorth += TransVisNorm * windowAreaWMult;
1029 : } else {
1030 47 : fenTotAreaNonNorth += windowAreaWMult;
1031 47 : ufactAreaNonNorth += nomUfact * windowAreaWMult;
1032 47 : shgcAreaNonNorth += SHGCSummer * windowAreaWMult;
1033 47 : vistranAreaNonNorth += TransVisNorm * windowAreaWMult;
1034 : }
1035 : // shading
1036 58 : if (surface.HasShadeControl) {
1037 8 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "Yes");
1038 16 : OutputReportPredefined::PreDefTableEntry(
1039 16 : state, state.dataOutRptPredefined->pdchWscName, surfName, state.dataSurface->WindowShadingControl(curWSC).Name);
1040 : // shading report
1041 16 : OutputReportPredefined::PreDefTableEntry(
1042 : state,
1043 8 : state.dataOutRptPredefined->pdchWscShading,
1044 : surfName,
1045 8 : WindowShadingTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).ShadingType)]);
1046 16 : OutputReportPredefined::PreDefTableEntry(
1047 : state,
1048 8 : state.dataOutRptPredefined->pdchWscControl,
1049 : surfName,
1050 8 : WindowShadingControlTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).shadingControlType)]);
1051 :
1052 : // output list of all possible shading constructions for shaded windows including those with storms
1053 8 : std::string names;
1054 16 : for (int construction : surface.shadedConstructionList) {
1055 8 : if (!names.empty()) {
1056 0 : names.append("; ");
1057 : }
1058 8 : names.append(state.dataConstruction->Construct(construction).Name);
1059 8 : }
1060 8 : 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 8 : }
1066 8 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscShadCons, surfName, names);
1067 :
1068 8 : if (state.dataSurface->WindowShadingControl(curWSC).GlareControlIsActive) {
1069 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "Yes");
1070 : } else {
1071 8 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "No");
1072 : }
1073 8 : } else {
1074 50 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "No");
1075 : }
1076 58 : } break;
1077 1 : case DataSurfaces::SurfaceClass::Door: {
1078 1 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1079 1 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1080 1 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1081 2 : OutputReportPredefined::PreDefTableEntry(
1082 2 : state, state.dataOutRptPredefined->pdchDrCons, surfName, state.dataConstruction->Construct(surface.Construction).Name);
1083 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrZone, surfName, thisZone.Name);
1084 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrSpace, surfName, thisSpace.Name);
1085 1 : OutputReportPredefined::PreDefTableEntry(
1086 1 : state, state.dataOutRptPredefined->pdchDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1087 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrGrArea, surfName, surface.GrossArea * mult);
1088 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrParent, surfName, surface.BaseSurfName);
1089 1 : computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
1090 1 : } break;
1091 16 : default:
1092 16 : break;
1093 : }
1094 618 : } else {
1095 : // interior surfaces
1096 216 : isExterior = false;
1097 216 : if ((surface.Class == DataSurfaces::SurfaceClass::Wall) || (surface.Class == DataSurfaces::SurfaceClass::Floor) ||
1098 18 : (surface.Class == DataSurfaces::SurfaceClass::Roof) || (surface.Class == DataSurfaces::SurfaceClass::IntMass)) {
1099 214 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1100 214 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1101 214 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1102 214 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1103 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpCons, surfName, construct.Name);
1104 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpZone, surfName, thisZone.Name);
1105 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpSpace, surfName, thisSpace.Name);
1106 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAdjSurf, surfName, surface.ExtBoundCondName);
1107 428 : OutputReportPredefined::PreDefTableEntry(
1108 214 : state, state.dataOutRptPredefined->pdchIntOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
1109 214 : OutputReportPredefined::PreDefTableEntry(
1110 214 : state, state.dataOutRptPredefined->pdchIntOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1111 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpGrArea, surfName, surface.GrossArea * mult);
1112 214 : computedNetArea(iSurf) += surface.GrossArea * mult;
1113 214 : 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 214 : curAzimuth = round(curAzimuth * 100.0) / 100.0;
1117 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAzimuth, surfName, curAzimuth);
1118 214 : curTilt = surface.Tilt;
1119 214 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpTilt, surfName, curTilt);
1120 214 : if ((curTilt >= 60.0) && (curTilt < 180.0)) {
1121 126 : if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
1122 67 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "N");
1123 59 : } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
1124 36 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "E");
1125 23 : } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
1126 13 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "S");
1127 10 : } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
1128 10 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "W");
1129 : }
1130 : }
1131 : // interior window report
1132 216 : } else if ((surface.Class == DataSurfaces::SurfaceClass::Window) || (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)) {
1133 0 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1134 0 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1135 0 : mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
1136 0 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1137 0 : if (!has_prefix(surface.Name,
1138 : "iz-")) { // don't count created interzone surfaces that are mirrors of other surfaces
1139 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenCons, surfName, construct.Name);
1140 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenZone, surfName, thisZone.Name);
1141 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSpace, surfName, thisSpace.Name);
1142 : // include the frame area if present
1143 0 : windowArea = surface.GrossArea;
1144 0 : 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 0 : windowAreaWMult = windowArea * mult;
1150 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenAreaOf1, surfName, windowArea);
1151 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, surfName, windowAreaWMult);
1152 0 : computedNetArea(surface.BaseSurf) -= windowAreaWMult;
1153 0 : nomUfact = state.dataHeatBal->NominalU(surface.Construction);
1154 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, surfName, nomUfact, 3);
1155 0 : 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 0 : if (construct.SummerSHGC != 0) {
1159 0 : SHGCSummer = construct.SummerSHGC;
1160 0 : 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 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, surfName, SHGCSummer, 3);
1169 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, surfName, TransVisNorm, 3);
1170 : // compute totals for area weighted averages
1171 0 : intShgcArea += SHGCSummer * windowAreaWMult;
1172 0 : intVistranArea += TransVisNorm * windowAreaWMult;
1173 : }
1174 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenParent, surfName, surface.BaseSurfName);
1175 : // compute totals for area weighted averages
1176 0 : intFenTotArea += windowAreaWMult;
1177 0 : intUfactArea += nomUfact * windowAreaWMult;
1178 : }
1179 2 : } else if (surface.Class == DataSurfaces::SurfaceClass::Door) {
1180 2 : auto const &construct = state.dataConstruction->Construct(surface.Construction);
1181 2 : auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
1182 2 : mult = thisZone.Multiplier * thisZone.ListMultiplier;
1183 2 : auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
1184 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrCons, surfName, construct.Name);
1185 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrZone, surfName, thisZone.Name);
1186 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrSpace, surfName, thisSpace.Name);
1187 2 : OutputReportPredefined::PreDefTableEntry(
1188 2 : state, state.dataOutRptPredefined->pdchIntDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
1189 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrGrArea, surfName, surface.GrossArea * mult);
1190 2 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrParent, surfName, surface.BaseSurfName);
1191 2 : computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
1192 : }
1193 : }
1194 834 : int currSurfaceClass = int(surface.Class);
1195 834 : assert(currSurfaceClass < int(DataSurfaces::SurfaceClass::Num));
1196 834 : assert(currSurfaceClass > int(DataSurfaces::SurfaceClass::None));
1197 834 : ++numSurfaces(currSurfaceClass);
1198 834 : if (isExterior) {
1199 618 : ++numExtSurfaces(currSurfaceClass);
1200 : }
1201 834 : if (surface.Class == DataSurfaces::SurfaceClass::Window) {
1202 58 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::GlassDoor || surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
1203 4 : ++numSurfaces((int)surface.OriginalClass);
1204 4 : if (isExterior) {
1205 4 : ++numExtSurfaces((int)surface.OriginalClass);
1206 : }
1207 : }
1208 : }
1209 114 : }
1210 : // for fins and overhangs just add them explicitly since not otherwise classified
1211 114 : int totOverhangs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang") +
1212 114 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang:Projection");
1213 114 : numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
1214 114 : numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
1215 114 : int totFins = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin") +
1216 114 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin:Projection");
1217 114 : numSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
1218 114 : numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
1219 : // go through all the surfaces again and this time insert the net area results
1220 948 : for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
1221 834 : auto const &surface = state.dataSurface->Surface(iSurf);
1222 834 : DataSurfaces::SurfaceClass const SurfaceClass(surface.Class);
1223 : // exterior surfaces including underground
1224 834 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
1225 216 : (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
1226 618 : if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
1227 : (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
1228 543 : surfName = surface.Name;
1229 543 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpNetArea, surfName, computedNetArea(iSurf));
1230 : }
1231 : } else {
1232 216 : if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
1233 : (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
1234 211 : surfName = surface.Name;
1235 211 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpNetArea, surfName, computedNetArea(iSurf));
1236 : }
1237 : } // interior surfaces
1238 114 : }
1239 : // total
1240 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Total or Average", fenTotArea);
1241 114 : if (fenTotArea > 0.0) {
1242 24 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", ufactArea / fenTotArea, 3);
1243 24 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", shgcArea / fenTotArea, 3);
1244 24 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", vistranArea / fenTotArea, 3);
1245 : } else {
1246 90 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", "-");
1247 90 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", "-");
1248 90 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", "-");
1249 : }
1250 : // north
1251 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "North Total or Average", fenTotAreaNorth);
1252 114 : if (fenTotAreaNorth > 0.0) {
1253 12 : OutputReportPredefined::PreDefTableEntry(
1254 12 : state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", ufactAreaNorth / fenTotAreaNorth, 3);
1255 12 : OutputReportPredefined::PreDefTableEntry(
1256 12 : state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", shgcAreaNorth / fenTotAreaNorth, 3);
1257 12 : OutputReportPredefined::PreDefTableEntry(
1258 18 : state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", vistranAreaNorth / fenTotAreaNorth, 3);
1259 : } else {
1260 108 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", "-");
1261 108 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", "-");
1262 108 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", "-");
1263 : }
1264 : // non-north
1265 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Non-North Total or Average", fenTotAreaNonNorth);
1266 114 : if (fenTotAreaNonNorth > 0.0) {
1267 46 : OutputReportPredefined::PreDefTableEntry(
1268 46 : state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", ufactAreaNonNorth / fenTotAreaNonNorth, 3);
1269 46 : OutputReportPredefined::PreDefTableEntry(
1270 46 : state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", shgcAreaNonNorth / fenTotAreaNonNorth, 3);
1271 46 : OutputReportPredefined::PreDefTableEntry(
1272 69 : state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", vistranAreaNonNorth / fenTotAreaNonNorth, 3);
1273 : } else {
1274 91 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", "-");
1275 91 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", "-");
1276 91 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", "-");
1277 : }
1278 : // interior fenestration totals
1279 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, "Total or Average", intFenTotArea);
1280 114 : if (intFenTotArea > 0.0) {
1281 0 : OutputReportPredefined::PreDefTableEntry(
1282 0 : state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", intUfactArea / intFenTotArea, 3);
1283 0 : OutputReportPredefined::PreDefTableEntry(
1284 0 : state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", intShgcArea / intFenTotArea, 3);
1285 0 : OutputReportPredefined::PreDefTableEntry(
1286 0 : state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", intVistranArea / intFenTotArea, 3);
1287 : } else {
1288 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", "-");
1289 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", "-");
1290 114 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", "-");
1291 : }
1292 : // counts
1293 114 : OutputReportPredefined::PreDefTableEntry(
1294 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Wall", numSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
1295 114 : OutputReportPredefined::PreDefTableEntry(
1296 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Wall", numExtSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
1297 114 : OutputReportPredefined::PreDefTableEntry(
1298 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Floor", numSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
1299 114 : OutputReportPredefined::PreDefTableEntry(
1300 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Floor", numExtSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
1301 114 : OutputReportPredefined::PreDefTableEntry(
1302 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Roof", numSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
1303 114 : OutputReportPredefined::PreDefTableEntry(
1304 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Roof", numExtSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
1305 114 : OutputReportPredefined::PreDefTableEntry(
1306 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Internal Mass", numSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
1307 114 : OutputReportPredefined::PreDefTableEntry(
1308 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Internal Mass", numExtSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
1309 114 : OutputReportPredefined::PreDefTableEntry(
1310 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Building Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
1311 114 : OutputReportPredefined::PreDefTableEntry(
1312 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Building Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
1313 114 : OutputReportPredefined::PreDefTableEntry(
1314 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Fixed Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
1315 114 : OutputReportPredefined::PreDefTableEntry(
1316 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Fixed Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
1317 114 : OutputReportPredefined::PreDefTableEntry(
1318 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Window", numSurfaces(int(DataSurfaces::SurfaceClass::Window)));
1319 114 : OutputReportPredefined::PreDefTableEntry(
1320 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Window", numExtSurfaces(int(DataSurfaces::SurfaceClass::Window)));
1321 114 : OutputReportPredefined::PreDefTableEntry(
1322 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Door", numSurfaces(int(DataSurfaces::SurfaceClass::Door)));
1323 114 : OutputReportPredefined::PreDefTableEntry(
1324 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::Door)));
1325 114 : OutputReportPredefined::PreDefTableEntry(
1326 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Glass Door", numSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
1327 114 : OutputReportPredefined::PreDefTableEntry(
1328 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Glass Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
1329 114 : OutputReportPredefined::PreDefTableEntry(
1330 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
1331 114 : OutputReportPredefined::PreDefTableEntry(
1332 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
1333 114 : OutputReportPredefined::PreDefTableEntry(
1334 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Overhang", numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
1335 114 : OutputReportPredefined::PreDefTableEntry(
1336 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Overhang", numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
1337 114 : OutputReportPredefined::PreDefTableEntry(
1338 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Fin", numSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
1339 114 : OutputReportPredefined::PreDefTableEntry(
1340 114 : state, state.dataOutRptPredefined->pdchSurfCntExt, "Fin", numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
1341 114 : OutputReportPredefined::PreDefTableEntry(
1342 114 : state, state.dataOutRptPredefined->pdchSurfCntTot, "Tubular Daylighting Device Dome", numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
1343 114 : OutputReportPredefined::PreDefTableEntry(state,
1344 114 : state.dataOutRptPredefined->pdchSurfCntExt,
1345 : "Tubular Daylighting Device Dome",
1346 114 : numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
1347 114 : OutputReportPredefined::PreDefTableEntry(state,
1348 114 : state.dataOutRptPredefined->pdchSurfCntTot,
1349 : "Tubular Daylighting Device Diffuser",
1350 114 : numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
1351 114 : OutputReportPredefined::PreDefTableEntry(state,
1352 114 : state.dataOutRptPredefined->pdchSurfCntExt,
1353 : "Tubular Daylighting Device Diffuser",
1354 114 : numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
1355 114 : }
1356 :
1357 145 : 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 145 : state.dataHeatBalSurf->SurfCTFConstInPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1369 145 : state.dataHeatBalSurf->SurfCTFConstOutPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1370 145 : state.dataHeatBalSurf->SurfCTFCross0.dimension(state.dataSurface->TotSurfaces, 0.0);
1371 145 : state.dataHeatBalSurf->SurfCTFInside0.dimension(state.dataSurface->TotSurfaces, 0.0);
1372 145 : state.dataHeatBalSurf->SurfTempOutHist.dimension(state.dataSurface->TotSurfaces, 0.0);
1373 145 : state.dataHeatBalSurf->SurfCTFSourceIn0.dimension(state.dataSurface->TotSurfaces, 0.0);
1374 145 : state.dataHeatBalSurf->SurfQSourceSinkHist.dimension(state.dataSurface->TotSurfaces, 0.0);
1375 145 : state.dataHeatBalSurf->SurfIsAdiabatic.dimension(state.dataSurface->TotSurfaces, 0);
1376 145 : state.dataHeatBalSurf->SurfIsSourceOrSink.dimension(state.dataSurface->TotSurfaces, 0);
1377 145 : state.dataHeatBalSurf->SurfIsOperatingPool.dimension(state.dataSurface->TotSurfaces, 0);
1378 145 : state.dataHeatBalSurf->SurfTempTerm.dimension(state.dataSurface->TotSurfaces, 0);
1379 145 : state.dataHeatBalSurf->SurfTempDiv.dimension(state.dataSurface->TotSurfaces, 0);
1380 145 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
1381 2 : state.dataHeatBalFanSys->CTFTsrcConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1382 2 : state.dataHeatBalFanSys->CTFTuserConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
1383 : }
1384 :
1385 145 : state.dataHeatBal->SurfTempEffBulkAir.dimension(state.dataSurface->TotSurfaces, DataHeatBalance::ZoneInitialTemp);
1386 145 : state.dataHeatBalSurf->SurfHConvInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1387 145 : state.dataHeatBalSurf->SurfHConvExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1388 145 : state.dataHeatBalSurf->SurfHAirExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1389 145 : state.dataHeatBalSurf->SurfHSkyExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1390 145 : state.dataHeatBalSurf->SurfHGrdExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1391 145 : state.dataHeatBalSurf->SurfHSrdSurfExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1392 :
1393 145 : state.dataHeatBalSurf->SurfTempIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1394 145 : state.dataHeatBalSurf->SurfTempInsOld.dimension(state.dataSurface->TotSurfaces, 0.0);
1395 145 : state.dataHeatBalSurf->SurfTempInTmp.dimension(state.dataSurface->TotSurfaces, 0.0);
1396 145 : state.dataHeatBalSurfMgr->RefAirTemp.dimension(state.dataSurface->TotSurfaces, 0.0);
1397 145 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs.dimension(state.dataSurface->TotSurfaces, 0.0);
1398 :
1399 145 : state.dataHeatBal->SurfWinQRadSWwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL + 1, 0.0);
1400 145 : state.dataHeatBal->SurfWinInitialDifSolwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL, 0.0);
1401 145 : state.dataHeatBalSurf->SurfQRadSWOutMvIns.dimension(state.dataSurface->TotSurfaces, 0.0);
1402 145 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1403 145 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside.dimension(state.dataSurface->TotSurfaces, 0.0);
1404 145 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside.dimension(state.dataSurface->TotSurfaces, 0.0);
1405 :
1406 145 : state.dataHeatBalSurf->SurfInsideTempHist.allocate(Construction::MaxCTFTerms);
1407 145 : state.dataHeatBalSurf->SurfOutsideTempHist.allocate(Construction::MaxCTFTerms);
1408 145 : state.dataHeatBalSurf->SurfInsideFluxHist.allocate(Construction::MaxCTFTerms);
1409 145 : state.dataHeatBalSurf->SurfOutsideFluxHist.allocate(Construction::MaxCTFTerms);
1410 2900 : for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
1411 2755 : state.dataHeatBalSurf->SurfInsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1412 2755 : state.dataHeatBalSurf->SurfOutsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1413 2755 : state.dataHeatBalSurf->SurfInsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1414 2755 : state.dataHeatBalSurf->SurfOutsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
1415 : }
1416 :
1417 145 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
1418 26 : state.dataHeatBalSurf->SurfCurrNumHist.dimension(state.dataSurface->TotSurfaces, 0);
1419 :
1420 26 : state.dataHeatBalSurf->SurfInsideTempHistMaster.allocate(Construction::MaxCTFTerms);
1421 26 : state.dataHeatBalSurf->SurfOutsideTempHistMaster.allocate(Construction::MaxCTFTerms);
1422 26 : state.dataHeatBalSurf->SurfInsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
1423 26 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
1424 :
1425 520 : for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
1426 494 : state.dataHeatBalSurf->SurfInsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1427 494 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1428 494 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1429 494 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
1430 : }
1431 : }
1432 :
1433 145 : state.dataHeatBalSurf->SurfTempOut.dimension(state.dataSurface->TotSurfaces, 0.0);
1434 145 : state.dataHeatBalSurf->SurfTempInMovInsRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1435 145 : state.dataHeatBalSurf->SurfQConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1436 145 : state.dataHeatBalSurf->SurfQdotConvInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1437 145 : state.dataHeatBalSurf->SurfQdotConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1438 :
1439 145 : state.dataHeatBalSurf->SurfQRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1440 145 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1441 :
1442 145 : state.dataHeatBalSurf->SurfQRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1443 145 : state.dataHeatBalSurf->SurfQdotRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1444 145 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1445 :
1446 145 : state.dataHeatBalSurf->SurfQRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1447 145 : state.dataHeatBalSurf->SurfQdotRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1448 :
1449 145 : state.dataHeatBalSurf->SurfQRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1450 145 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1451 :
1452 145 : state.dataHeatBalSurf->SurfQRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1453 145 : state.dataHeatBalSurf->SurfQdotRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1454 145 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1455 :
1456 145 : state.dataHeatBalSurf->SurfQConvOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1457 145 : state.dataHeatBalSurf->SurfQdotConvOutPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1458 145 : state.dataHeatBalSurf->SurfQdotConvOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1459 :
1460 145 : state.dataHeatBalSurf->SurfQdotRadOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1461 145 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1462 145 : state.dataHeatBalSurf->SurfQRadOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1463 :
1464 145 : state.dataHeatBalSurf->SurfQAirExtReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1465 145 : state.dataHeatBalSurf->SurfQHeatEmiReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1466 :
1467 145 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1468 145 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport.dimension(state.dataSurface->TotSurfaces, 0.0);
1469 :
1470 145 : state.dataHeatBalSurf->SurfOpaqInsFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1471 145 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1472 145 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1473 145 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1474 145 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1475 :
1476 145 : state.dataHeatBalSurf->SurfOpaqOutFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1477 145 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1478 145 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1479 145 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1480 145 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1481 :
1482 145 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1483 145 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1484 145 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1485 145 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1486 145 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1487 :
1488 145 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1489 145 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
1490 145 : state.dataHeatBalSurf->SurfOpaqStorageCond.dimension(state.dataSurface->TotSurfaces, 0.0);
1491 145 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
1492 145 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
1493 :
1494 145 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed.dimension(state.dataSurface->TotSurfaces, 0.0);
1495 :
1496 145 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1497 145 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1498 :
1499 145 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
1500 145 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
1501 145 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
1502 :
1503 145 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1504 145 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
1505 :
1506 145 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
1507 2 : state.dataHeatBalSurf->SurfTempSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1508 2 : state.dataHeatBalSurf->SurfTempUserLoc.dimension(state.dataSurface->TotSurfaces, 0.0);
1509 2 : state.dataHeatBalSurf->SurfTsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1510 2 : state.dataHeatBalSurf->SurfTuserHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1511 2 : state.dataHeatBalSurf->SurfQsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1512 2 : state.dataHeatBalSurf->SurfTsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1513 2 : state.dataHeatBalSurf->SurfTuserHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1514 2 : state.dataHeatBalSurf->SurfQsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
1515 : }
1516 :
1517 145 : state.dataHeatBalFanSys->RadSysTiHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1518 145 : state.dataHeatBalFanSys->RadSysTiHBToutCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1519 145 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1520 145 : state.dataHeatBalFanSys->RadSysToHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1521 145 : state.dataHeatBalFanSys->RadSysToHBTinCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1522 145 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
1523 145 : state.dataHeatBalFanSys->QRadSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1524 145 : state.dataHeatBalFanSys->TCondFDSourceNode.dimension(state.dataSurface->TotSurfaces, 15.0);
1525 145 : state.dataHeatBalFanSys->surfQRadFromHVAC.allocate(state.dataSurface->TotSurfaces);
1526 145 : state.dataHeatBalFanSys->QRadSurfAFNDuct.dimension(state.dataSurface->TotSurfaces, 0.0);
1527 :
1528 : // allocate terms used for pool surface heat balance
1529 145 : state.dataHeatBalFanSys->QPoolSurfNumerator.dimension(state.dataSurface->TotSurfaces, 0.0);
1530 145 : state.dataHeatBalFanSys->PoolHeatTransCoefs.dimension(state.dataSurface->TotSurfaces, 0.0);
1531 :
1532 : // allocate term used as sink for PV electricity
1533 145 : state.dataHeatBalFanSys->QPVSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
1534 :
1535 : // Allocate the moisture balance arrays
1536 145 : state.dataMstBal->TempOutsideAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1537 145 : state.dataMstBal->RhoVaporAirOut.dimension(state.dataSurface->TotSurfaces, 0.0);
1538 145 : state.dataMstBal->RhoVaporSurfIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1539 145 : state.dataMstBal->RhoVaporAirIn.dimension(state.dataSurface->TotSurfaces, 0.0);
1540 145 : state.dataMstBal->HConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1541 145 : state.dataMstBal->HMassConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1542 145 : state.dataMstBal->HConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1543 145 : state.dataMstBal->HMassConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1544 145 : state.dataMstBal->HSkyFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1545 145 : state.dataMstBal->HGrndFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1546 145 : state.dataMstBal->HAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
1547 :
1548 145 : state.dataSurface->SurfSkySolarInc.dimension(state.dataSurface->TotSurfaces, 0);
1549 145 : state.dataSurface->SurfGndSolarInc.dimension(state.dataSurface->TotSurfaces, 0);
1550 :
1551 145 : state.dataHeatBalSurf->SurfAbsSolarExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1552 145 : state.dataHeatBalSurf->SurfAbsThermalExt.dimension(state.dataSurface->TotSurfaces, 0.0);
1553 145 : state.dataHeatBalSurf->SurfRoughnessExt.dimension(state.dataSurface->TotSurfaces, Material::SurfaceRoughness::Invalid);
1554 145 : state.dataHeatBalSurf->SurfAbsSolarInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1555 145 : state.dataHeatBalSurf->SurfAbsThermalInt.dimension(state.dataSurface->TotSurfaces, 0.0);
1556 :
1557 145 : DisplayString(state, "Setting up Surface Reporting Variables");
1558 : // Setup surface report variables CurrentModuleObject='Opaque Surfaces'
1559 1164 : for (int loop = 1; loop <= state.dataSurface->TotSurfaces; ++loop) {
1560 1019 : auto &surface = state.dataSurface->Surface(loop);
1561 1019 : if (!surface.HeatTransSurf) {
1562 24 : continue;
1563 : }
1564 1990 : SetupOutputVariable(state,
1565 : "Surface Inside Face Temperature",
1566 : Constant::Units::C,
1567 995 : state.dataHeatBalSurf->SurfTempIn(loop),
1568 : OutputProcessor::TimeStepType::Zone,
1569 : OutputProcessor::StoreType::Average,
1570 995 : surface.Name);
1571 1990 : SetupOutputVariable(state,
1572 : "Surface Inside Face Interior Movable Insulation Temperature",
1573 : Constant::Units::C,
1574 995 : state.dataHeatBalSurf->SurfTempInMovInsRep(loop),
1575 : OutputProcessor::TimeStepType::Zone,
1576 : OutputProcessor::StoreType::Average,
1577 995 : surface.Name);
1578 :
1579 995 : if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
1580 1990 : SetupOutputVariable(state,
1581 : "Surface Outside Face Temperature",
1582 : Constant::Units::C,
1583 995 : state.dataHeatBalSurf->SurfTempOut(loop),
1584 : OutputProcessor::TimeStepType::Zone,
1585 : OutputProcessor::StoreType::Average,
1586 995 : surface.Name);
1587 : }
1588 :
1589 1990 : SetupOutputVariable(state,
1590 : "Surface Inside Face Adjacent Air Temperature",
1591 : Constant::Units::C,
1592 995 : state.dataHeatBal->SurfTempEffBulkAir(loop),
1593 : OutputProcessor::TimeStepType::Zone,
1594 : OutputProcessor::StoreType::Average,
1595 995 : surface.Name);
1596 1990 : SetupOutputVariable(state,
1597 : "Surface Inside Face Convection Heat Transfer Coefficient",
1598 : Constant::Units::W_m2K,
1599 995 : state.dataHeatBalSurf->SurfHConvInt(loop),
1600 : OutputProcessor::TimeStepType::Zone,
1601 : OutputProcessor::StoreType::Average,
1602 995 : surface.Name);
1603 1990 : SetupOutputVariable(state,
1604 : "Surface Inside Face Convection Heat Gain Rate",
1605 : Constant::Units::W,
1606 995 : state.dataHeatBalSurf->SurfQdotConvInRep(loop),
1607 : OutputProcessor::TimeStepType::Zone,
1608 : OutputProcessor::StoreType::Average,
1609 995 : surface.Name);
1610 1990 : SetupOutputVariable(state,
1611 : "Surface Inside Face Convection Heat Gain Rate per Area",
1612 : Constant::Units::W_m2,
1613 995 : state.dataHeatBalSurf->SurfQdotConvInPerArea(loop),
1614 : OutputProcessor::TimeStepType::Zone,
1615 : OutputProcessor::StoreType::Average,
1616 995 : surface.Name);
1617 1990 : SetupOutputVariable(state,
1618 : "Surface Inside Face Convection Heat Gain Energy",
1619 : Constant::Units::J,
1620 995 : state.dataHeatBalSurf->SurfQConvInRep(loop),
1621 : OutputProcessor::TimeStepType::Zone,
1622 : OutputProcessor::StoreType::Sum,
1623 995 : surface.Name);
1624 :
1625 1990 : SetupOutputVariable(state,
1626 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate",
1627 : Constant::Units::W,
1628 995 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(loop),
1629 : OutputProcessor::TimeStepType::Zone,
1630 : OutputProcessor::StoreType::Average,
1631 995 : surface.Name);
1632 1990 : SetupOutputVariable(state,
1633 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate per Area",
1634 : Constant::Units::W_m2,
1635 995 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(loop),
1636 : OutputProcessor::TimeStepType::Zone,
1637 : OutputProcessor::StoreType::Average,
1638 995 : surface.Name);
1639 1990 : SetupOutputVariable(state,
1640 : "Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy",
1641 : Constant::Units::J,
1642 995 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(loop),
1643 : OutputProcessor::TimeStepType::Zone,
1644 : OutputProcessor::StoreType::Sum,
1645 995 : surface.Name);
1646 :
1647 995 : if (surface.Class != DataSurfaces::SurfaceClass::Window) {
1648 1880 : SetupOutputVariable(state,
1649 : "Surface Inside Face Solar Radiation Heat Gain Rate",
1650 : Constant::Units::W,
1651 940 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(loop),
1652 : OutputProcessor::TimeStepType::Zone,
1653 : OutputProcessor::StoreType::Average,
1654 940 : surface.Name);
1655 1880 : SetupOutputVariable(state,
1656 : "Surface Inside Face Solar Radiation Heat Gain Rate per Area",
1657 : Constant::Units::W_m2,
1658 940 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(loop),
1659 : OutputProcessor::TimeStepType::Zone,
1660 : OutputProcessor::StoreType::Average,
1661 940 : surface.Name);
1662 1880 : SetupOutputVariable(state,
1663 : "Surface Inside Face Solar Radiation Heat Gain Energy",
1664 : Constant::Units::J,
1665 940 : state.dataHeatBalSurf->SurfQRadSolarInRep(loop),
1666 : OutputProcessor::TimeStepType::Zone,
1667 : OutputProcessor::StoreType::Sum,
1668 940 : surface.Name);
1669 :
1670 1880 : SetupOutputVariable(state,
1671 : "Surface Inside Face Lights Radiation Heat Gain Rate",
1672 : Constant::Units::W,
1673 940 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(loop),
1674 : OutputProcessor::TimeStepType::Zone,
1675 : OutputProcessor::StoreType::Average,
1676 940 : surface.Name);
1677 1880 : SetupOutputVariable(state,
1678 : "Surface Inside Face Lights Radiation Heat Gain Rate per Area",
1679 : Constant::Units::W_m2,
1680 940 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(loop),
1681 : OutputProcessor::TimeStepType::Zone,
1682 : OutputProcessor::StoreType::Average,
1683 940 : surface.Name);
1684 1880 : SetupOutputVariable(state,
1685 : "Surface Inside Face Lights Radiation Heat Gain Energy",
1686 : Constant::Units::J,
1687 940 : state.dataHeatBalSurf->SurfQRadLightsInRep(loop),
1688 : OutputProcessor::TimeStepType::Zone,
1689 : OutputProcessor::StoreType::Sum,
1690 940 : surface.Name);
1691 : }
1692 :
1693 1990 : SetupOutputVariable(state,
1694 : "Surface Inside Face Internal Gains Radiation Heat Gain Rate",
1695 : Constant::Units::W,
1696 995 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(loop),
1697 : OutputProcessor::TimeStepType::Zone,
1698 : OutputProcessor::StoreType::Average,
1699 995 : surface.Name);
1700 1990 : SetupOutputVariable(state,
1701 : "Surface Inside Face Internal Gains Radiation Heat Gain Rate per Area",
1702 : Constant::Units::W_m2,
1703 995 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(loop),
1704 : OutputProcessor::TimeStepType::Zone,
1705 : OutputProcessor::StoreType::Average,
1706 995 : surface.Name);
1707 1990 : SetupOutputVariable(state,
1708 : "Surface Inside Face Internal Gains Radiation Heat Gain Energy",
1709 : Constant::Units::J,
1710 995 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(loop),
1711 : OutputProcessor::TimeStepType::Zone,
1712 : OutputProcessor::StoreType::Sum,
1713 995 : surface.Name);
1714 :
1715 1990 : SetupOutputVariable(state,
1716 : "Surface Inside Face System Radiation Heat Gain Rate",
1717 : Constant::Units::W,
1718 995 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(loop),
1719 : OutputProcessor::TimeStepType::Zone,
1720 : OutputProcessor::StoreType::Average,
1721 995 : surface.Name);
1722 1990 : SetupOutputVariable(state,
1723 : "Surface Inside Face System Radiation Heat Gain Rate per Area",
1724 : Constant::Units::W_m2,
1725 995 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(loop),
1726 : OutputProcessor::TimeStepType::Zone,
1727 : OutputProcessor::StoreType::Average,
1728 995 : surface.Name);
1729 1990 : SetupOutputVariable(state,
1730 : "Surface Inside Face System Radiation Heat Gain Energy",
1731 : Constant::Units::J,
1732 995 : state.dataHeatBalSurf->SurfQRadHVACInRep(loop),
1733 : OutputProcessor::TimeStepType::Zone,
1734 : OutputProcessor::StoreType::Sum,
1735 995 : surface.Name);
1736 :
1737 995 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment || state.dataGlobal->DisplayAdvancedReportVariables) {
1738 1432 : SetupOutputVariable(state,
1739 : "Surface Outside Face Outdoor Air Drybulb Temperature",
1740 : Constant::Units::C,
1741 716 : state.dataSurface->SurfOutDryBulbTemp(loop),
1742 : OutputProcessor::TimeStepType::Zone,
1743 : OutputProcessor::StoreType::Average,
1744 716 : surface.Name);
1745 1432 : SetupOutputVariable(state,
1746 : "Surface Outside Face Outdoor Air Wetbulb Temperature",
1747 : Constant::Units::C,
1748 716 : state.dataSurface->SurfOutWetBulbTemp(loop),
1749 : OutputProcessor::TimeStepType::Zone,
1750 : OutputProcessor::StoreType::Average,
1751 716 : surface.Name);
1752 1432 : SetupOutputVariable(state,
1753 : "Surface Outside Face Outdoor Air Wind Speed",
1754 : Constant::Units::m_s,
1755 716 : state.dataSurface->SurfOutWindSpeed(loop),
1756 : OutputProcessor::TimeStepType::Zone,
1757 : OutputProcessor::StoreType::Average,
1758 716 : surface.Name);
1759 1432 : SetupOutputVariable(state,
1760 : "Surface Outside Face Outdoor Air Wind Direction",
1761 : Constant::Units::deg,
1762 716 : state.dataSurface->SurfOutWindDir(loop),
1763 : OutputProcessor::TimeStepType::Zone,
1764 : OutputProcessor::StoreType::Average,
1765 716 : surface.Name);
1766 1432 : SetupOutputVariable(state,
1767 : "Surface Outside Face Convection Heat Gain Rate",
1768 : Constant::Units::W,
1769 716 : state.dataHeatBalSurf->SurfQdotConvOutRep(loop),
1770 : OutputProcessor::TimeStepType::Zone,
1771 : OutputProcessor::StoreType::Average,
1772 716 : surface.Name);
1773 1432 : SetupOutputVariable(state,
1774 : "Surface Outside Face Convection Heat Gain Rate per Area",
1775 : Constant::Units::W_m2,
1776 716 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(loop),
1777 : OutputProcessor::TimeStepType::Zone,
1778 : OutputProcessor::StoreType::Average,
1779 716 : surface.Name);
1780 1432 : SetupOutputVariable(state,
1781 : "Surface Outside Face Convection Heat Gain Energy",
1782 : Constant::Units::J,
1783 716 : state.dataHeatBalSurf->SurfQConvOutReport(loop),
1784 : OutputProcessor::TimeStepType::Zone,
1785 : OutputProcessor::StoreType::Sum,
1786 716 : surface.Name);
1787 1432 : SetupOutputVariable(state,
1788 : "Surface Outside Face Convection Heat Transfer Coefficient",
1789 : Constant::Units::W_m2K,
1790 716 : state.dataHeatBalSurf->SurfHConvExt(loop),
1791 : OutputProcessor::TimeStepType::Zone,
1792 : OutputProcessor::StoreType::Average,
1793 716 : surface.Name);
1794 1432 : SetupOutputVariable(state,
1795 : "Surface Outside Face Net Thermal Radiation Heat Gain Rate",
1796 : Constant::Units::W,
1797 716 : state.dataHeatBalSurf->SurfQdotRadOutRep(loop),
1798 : OutputProcessor::TimeStepType::Zone,
1799 : OutputProcessor::StoreType::Average,
1800 716 : surface.Name);
1801 1432 : SetupOutputVariable(state,
1802 : "Surface Outside Face Net Thermal Radiation Heat Gain Rate per Area",
1803 : Constant::Units::W_m2,
1804 716 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(loop),
1805 : OutputProcessor::TimeStepType::Zone,
1806 : OutputProcessor::StoreType::Average,
1807 716 : surface.Name);
1808 1432 : SetupOutputVariable(state,
1809 : "Surface Outside Face Net Thermal Radiation Heat Gain Energy",
1810 : Constant::Units::J,
1811 716 : state.dataHeatBalSurf->SurfQRadOutReport(loop),
1812 : OutputProcessor::TimeStepType::Zone,
1813 : OutputProcessor::StoreType::Sum,
1814 716 : surface.Name);
1815 1432 : SetupOutputVariable(state,
1816 : "Surface Outside Face Thermal Radiation to Air Heat Transfer Coefficient",
1817 : Constant::Units::W_m2K,
1818 716 : state.dataHeatBalSurf->SurfHAirExt(loop),
1819 : OutputProcessor::TimeStepType::Zone,
1820 : OutputProcessor::StoreType::Average,
1821 716 : surface.Name);
1822 1432 : SetupOutputVariable(state,
1823 : "Surface Outside Face Thermal Radiation to Sky Heat Transfer Coefficient",
1824 : Constant::Units::W_m2K,
1825 716 : state.dataHeatBalSurf->SurfHSkyExt(loop),
1826 : OutputProcessor::TimeStepType::Zone,
1827 : OutputProcessor::StoreType::Average,
1828 716 : surface.Name);
1829 1432 : SetupOutputVariable(state,
1830 : "Surface Outside Face Thermal Radiation to Ground Heat Transfer Coefficient",
1831 : Constant::Units::W_m2K,
1832 716 : state.dataHeatBalSurf->SurfHGrdExt(loop),
1833 : OutputProcessor::TimeStepType::Zone,
1834 : OutputProcessor::StoreType::Average,
1835 716 : surface.Name);
1836 1432 : SetupOutputVariable(state,
1837 : "Surface Outside Face Thermal Radiation to Air Heat Transfer Rate",
1838 : Constant::Units::W,
1839 716 : state.dataHeatBalSurf->SurfQAirExtReport(loop),
1840 : OutputProcessor::TimeStepType::Zone,
1841 : OutputProcessor::StoreType::Average,
1842 716 : surface.Name);
1843 1432 : SetupOutputVariable(state,
1844 : "Surface Outside Face Heat Emission to Air Rate",
1845 : Constant::Units::W,
1846 716 : state.dataHeatBalSurf->SurfQHeatEmiReport(loop),
1847 : OutputProcessor::TimeStepType::Zone,
1848 : OutputProcessor::StoreType::Average,
1849 716 : surface.Name);
1850 :
1851 716 : if (surface.Class != DataSurfaces::SurfaceClass::Window) {
1852 1322 : SetupOutputVariable(state,
1853 : "Surface Outside Face Solar Radiation Heat Gain Rate",
1854 : Constant::Units::W,
1855 661 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(loop),
1856 : OutputProcessor::TimeStepType::Zone,
1857 : OutputProcessor::StoreType::Average,
1858 661 : surface.Name);
1859 1322 : SetupOutputVariable(state,
1860 : "Surface Outside Face Solar Radiation Heat Gain Rate per Area",
1861 : Constant::Units::W_m2,
1862 661 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(loop),
1863 : OutputProcessor::TimeStepType::Zone,
1864 : OutputProcessor::StoreType::Average,
1865 661 : surface.Name);
1866 1322 : SetupOutputVariable(state,
1867 : "Surface Outside Face Solar Radiation Heat Gain Energy",
1868 : Constant::Units::J,
1869 661 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(loop),
1870 : OutputProcessor::TimeStepType::Zone,
1871 : OutputProcessor::StoreType::Sum,
1872 661 : surface.Name);
1873 : }
1874 : }
1875 995 : if (surface.Class == DataSurfaces::SurfaceClass::Floor || surface.Class == DataSurfaces::SurfaceClass::Wall ||
1876 223 : surface.Class == DataSurfaces::SurfaceClass::IntMass || surface.Class == DataSurfaces::SurfaceClass::Roof ||
1877 58 : surface.Class == DataSurfaces::SurfaceClass::Door) {
1878 : // IF (DisplayAdvancedReportVariables) THEN !CurrentModuleObject='Opaque Surfaces(Advanced)'
1879 1876 : SetupOutputVariable(state,
1880 : "Surface Inside Face Conduction Heat Transfer Rate",
1881 : Constant::Units::W,
1882 938 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(loop),
1883 : OutputProcessor::TimeStepType::Zone,
1884 : OutputProcessor::StoreType::Average,
1885 938 : surface.Name);
1886 1876 : SetupOutputVariable(state,
1887 : "Surface Inside Face Conduction Heat Gain Rate",
1888 : Constant::Units::W,
1889 938 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(loop),
1890 : OutputProcessor::TimeStepType::Zone,
1891 : OutputProcessor::StoreType::Average,
1892 938 : surface.Name);
1893 1876 : SetupOutputVariable(state,
1894 : "Surface Inside Face Conduction Heat Loss Rate",
1895 : Constant::Units::W,
1896 938 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(loop),
1897 : OutputProcessor::TimeStepType::Zone,
1898 : OutputProcessor::StoreType::Average,
1899 938 : surface.Name);
1900 1876 : SetupOutputVariable(state,
1901 : "Surface Inside Face Conduction Heat Transfer Rate per Area",
1902 : Constant::Units::W_m2,
1903 938 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(loop),
1904 : OutputProcessor::TimeStepType::Zone,
1905 : OutputProcessor::StoreType::Average,
1906 938 : surface.Name);
1907 1876 : SetupOutputVariable(state,
1908 : "Surface Inside Face Conduction Heat Transfer Energy",
1909 : Constant::Units::J,
1910 938 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(loop),
1911 : OutputProcessor::TimeStepType::Zone,
1912 : OutputProcessor::StoreType::Sum,
1913 938 : surface.Name);
1914 :
1915 938 : if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
1916 1876 : SetupOutputVariable(state,
1917 : "Surface Outside Face Conduction Heat Transfer Rate",
1918 : Constant::Units::W,
1919 938 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(loop),
1920 : OutputProcessor::TimeStepType::Zone,
1921 : OutputProcessor::StoreType::Average,
1922 938 : surface.Name);
1923 1876 : SetupOutputVariable(state,
1924 : "Surface Outside Face Conduction Heat Gain Rate",
1925 : Constant::Units::W,
1926 938 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(loop),
1927 : OutputProcessor::TimeStepType::Zone,
1928 : OutputProcessor::StoreType::Average,
1929 938 : surface.Name);
1930 1876 : SetupOutputVariable(state,
1931 : "Surface Outside Face Conduction Heat Loss Rate",
1932 : Constant::Units::W,
1933 938 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(loop),
1934 : OutputProcessor::TimeStepType::Zone,
1935 : OutputProcessor::StoreType::Average,
1936 938 : surface.Name);
1937 1876 : SetupOutputVariable(state,
1938 : "Surface Outside Face Conduction Heat Transfer Rate per Area",
1939 : Constant::Units::W_m2,
1940 938 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(loop),
1941 : OutputProcessor::TimeStepType::Zone,
1942 : OutputProcessor::StoreType::Average,
1943 938 : surface.Name);
1944 1876 : SetupOutputVariable(state,
1945 : "Surface Outside Face Conduction Heat Transfer Energy",
1946 : Constant::Units::J,
1947 938 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(loop),
1948 : OutputProcessor::TimeStepType::Zone,
1949 : OutputProcessor::StoreType::Sum,
1950 938 : surface.Name);
1951 :
1952 1876 : SetupOutputVariable(state,
1953 : "Surface Average Face Conduction Heat Transfer Rate",
1954 : Constant::Units::W,
1955 938 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(loop),
1956 : OutputProcessor::TimeStepType::Zone,
1957 : OutputProcessor::StoreType::Average,
1958 938 : surface.Name);
1959 1876 : SetupOutputVariable(state,
1960 : "Surface Average Face Conduction Heat Gain Rate",
1961 : Constant::Units::W,
1962 938 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(loop),
1963 : OutputProcessor::TimeStepType::Zone,
1964 : OutputProcessor::StoreType::Average,
1965 938 : surface.Name);
1966 1876 : SetupOutputVariable(state,
1967 : "Surface Average Face Conduction Heat Loss Rate",
1968 : Constant::Units::W,
1969 938 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(loop),
1970 : OutputProcessor::TimeStepType::Zone,
1971 : OutputProcessor::StoreType::Average,
1972 938 : surface.Name);
1973 1876 : SetupOutputVariable(state,
1974 : "Surface Average Face Conduction Heat Transfer Rate per Area",
1975 : Constant::Units::W_m2,
1976 938 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(loop),
1977 : OutputProcessor::TimeStepType::Zone,
1978 : OutputProcessor::StoreType::Average,
1979 938 : surface.Name);
1980 1876 : SetupOutputVariable(state,
1981 : "Surface Average Face Conduction Heat Transfer Energy",
1982 : Constant::Units::J,
1983 938 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(loop),
1984 : OutputProcessor::TimeStepType::Zone,
1985 : OutputProcessor::StoreType::Sum,
1986 938 : surface.Name);
1987 :
1988 1876 : SetupOutputVariable(state,
1989 : "Surface Heat Storage Rate",
1990 : Constant::Units::W,
1991 938 : state.dataHeatBalSurf->SurfOpaqStorageCond(loop),
1992 : OutputProcessor::TimeStepType::Zone,
1993 : OutputProcessor::StoreType::Average,
1994 938 : surface.Name);
1995 1876 : SetupOutputVariable(state,
1996 : "Surface Heat Storage Gain Rate",
1997 : Constant::Units::W,
1998 938 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(loop),
1999 : OutputProcessor::TimeStepType::Zone,
2000 : OutputProcessor::StoreType::Average,
2001 938 : surface.Name);
2002 1876 : SetupOutputVariable(state,
2003 : "Surface Heat Storage Loss Rate",
2004 : Constant::Units::W,
2005 938 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(loop),
2006 : OutputProcessor::TimeStepType::Zone,
2007 : OutputProcessor::StoreType::Average,
2008 938 : surface.Name);
2009 1876 : SetupOutputVariable(state,
2010 : "Surface Heat Storage Rate per Area",
2011 : Constant::Units::W_m2,
2012 938 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux(loop),
2013 : OutputProcessor::TimeStepType::Zone,
2014 : OutputProcessor::StoreType::Average,
2015 938 : surface.Name);
2016 1876 : SetupOutputVariable(state,
2017 : "Surface Heat Storage Energy",
2018 : Constant::Units::J,
2019 938 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(loop),
2020 : OutputProcessor::TimeStepType::Zone,
2021 : OutputProcessor::StoreType::Sum,
2022 938 : surface.Name);
2023 : }
2024 :
2025 : // ENDIF
2026 : // CurrentModuleObject='Opaque Surfaces'
2027 :
2028 1876 : SetupOutputVariable(state,
2029 : "Surface Inside Face Beam Solar Radiation Heat Gain Rate",
2030 : Constant::Units::W,
2031 938 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(loop),
2032 : OutputProcessor::TimeStepType::Zone,
2033 : OutputProcessor::StoreType::Average,
2034 938 : surface.Name);
2035 : }
2036 995 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
2037 2 : SetupOutputVariable(state,
2038 : "Surface Internal Source Location Temperature",
2039 : Constant::Units::C,
2040 1 : state.dataHeatBalSurf->SurfTempSource(loop),
2041 : OutputProcessor::TimeStepType::Zone,
2042 : OutputProcessor::StoreType::Average,
2043 1 : surface.Name);
2044 2 : SetupOutputVariable(state,
2045 : "Surface Internal User Specified Location Temperature",
2046 : Constant::Units::C,
2047 1 : state.dataHeatBalSurf->SurfTempUserLoc(loop),
2048 : OutputProcessor::TimeStepType::Zone,
2049 : OutputProcessor::StoreType::Average,
2050 1 : surface.Name);
2051 : }
2052 :
2053 995 : if (surface.Class == DataSurfaces::SurfaceClass::Window) { // CurrentModuleObject='Windows'
2054 55 : auto &surfShade = state.dataSurface->surfShades(loop);
2055 110 : SetupOutputVariable(state,
2056 : "Surface Shading Device Is On Time Fraction",
2057 : Constant::Units::None,
2058 55 : state.dataSurface->SurfWinFracTimeShadingDeviceOn(loop),
2059 : OutputProcessor::TimeStepType::Zone,
2060 : OutputProcessor::StoreType::Average,
2061 55 : surface.Name);
2062 55 : SetupOutputVariable(state,
2063 : "Surface Storm Window On Off Status",
2064 : Constant::Units::None,
2065 55 : state.dataSurface->SurfWinStormWinFlag(loop),
2066 : OutputProcessor::TimeStepType::Zone,
2067 : OutputProcessor::StoreType::Average,
2068 55 : surface.Name);
2069 110 : SetupOutputVariable(state,
2070 : "Surface Window Blind Slat Angle",
2071 : Constant::Units::deg,
2072 55 : surfShade.blind.slatAngDeg,
2073 : OutputProcessor::TimeStepType::Zone,
2074 : OutputProcessor::StoreType::Average,
2075 55 : surface.Name);
2076 : }
2077 : // IF (DisplayAdvancedReportVariables) THEN !CurrentModuleObject='Opaque Surfaces(Advanced)'
2078 995 : SetupOutputVariable(state,
2079 : "Surface Inside Face Convection Classification Index",
2080 : Constant::Units::None,
2081 995 : state.dataSurface->surfIntConv(loop).convClassRpt,
2082 : OutputProcessor::TimeStepType::Zone,
2083 : OutputProcessor::StoreType::Average,
2084 995 : surface.Name);
2085 995 : SetupOutputVariable(state,
2086 : "Surface Inside Face Convection Model Equation Index",
2087 : Constant::Units::None,
2088 995 : state.dataSurface->surfIntConv(loop).hcModelEqRpt,
2089 : OutputProcessor::TimeStepType::Zone,
2090 : OutputProcessor::StoreType::Average,
2091 995 : surface.Name);
2092 995 : SetupOutputVariable(state,
2093 : "Surface Inside Face Convection Reference Air Index",
2094 : Constant::Units::None,
2095 995 : state.dataSurface->SurfTAirRefRpt(loop),
2096 : OutputProcessor::TimeStepType::Zone,
2097 : OutputProcessor::StoreType::Average,
2098 995 : surface.Name);
2099 995 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
2100 715 : SetupOutputVariable(state,
2101 : "Surface Outside Face Convection Classification Index",
2102 : Constant::Units::None,
2103 715 : state.dataSurface->surfExtConv(loop).convClassRpt,
2104 : OutputProcessor::TimeStepType::Zone,
2105 : OutputProcessor::StoreType::Average,
2106 715 : surface.Name);
2107 715 : SetupOutputVariable(state,
2108 : "Surface Outside Face Forced Convection Model Equation Index",
2109 : Constant::Units::None,
2110 715 : state.dataSurface->surfExtConv(loop).hfModelEqRpt,
2111 : OutputProcessor::TimeStepType::Zone,
2112 : OutputProcessor::StoreType::Average,
2113 715 : surface.Name);
2114 715 : SetupOutputVariable(state,
2115 : "Surface Outside Face Natural Convection Model Equation Index",
2116 : Constant::Units::None,
2117 715 : state.dataSurface->surfExtConv(loop).hnModelEqRpt,
2118 : OutputProcessor::TimeStepType::Zone,
2119 : OutputProcessor::StoreType::Average,
2120 715 : surface.Name);
2121 : }
2122 :
2123 1990 : SetupOutputVariable(state,
2124 : "Surface Inside Face Heat Source Gain Rate per Area",
2125 : Constant::Units::W_m2,
2126 995 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(loop),
2127 : OutputProcessor::TimeStepType::Zone,
2128 : OutputProcessor::StoreType::Average,
2129 995 : surface.Name);
2130 1990 : SetupOutputVariable(state,
2131 : "Surface Outside Face Heat Source Gain Rate per Area",
2132 : Constant::Units::W_m2,
2133 995 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(loop),
2134 : OutputProcessor::TimeStepType::Zone,
2135 : OutputProcessor::StoreType::Average,
2136 995 : surface.Name);
2137 :
2138 : // ENDIF
2139 995 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
2140 1 : SetupOutputVariable(state,
2141 : "Surface Construction Index",
2142 : Constant::Units::None,
2143 1 : surface.Construction,
2144 : OutputProcessor::TimeStepType::Zone,
2145 : OutputProcessor::StoreType::Average,
2146 1 : surface.Name);
2147 : }
2148 : }
2149 580 : SetupOutputVariable(state,
2150 : "Site Total Surface Heat Emission to Air",
2151 : Constant::Units::J,
2152 145 : state.dataHeatBalSurf->SumSurfaceHeatEmission,
2153 : OutputProcessor::TimeStepType::Zone,
2154 : OutputProcessor::StoreType::Sum,
2155 : "Environment");
2156 145 : }
2157 :
2158 483 : void InitThermalAndFluxHistories(EnergyPlusData &state)
2159 : {
2160 :
2161 : // SUBROUTINE INFORMATION:
2162 : // AUTHOR George Walton
2163 : // DATE WRITTEN March 1978
2164 : // RE-ENGINEERED Feb98 (RKS)
2165 :
2166 : // PURPOSE OF THIS SUBROUTINE:
2167 : // This subroutine sets the initial temperature and flux histories
2168 : // needed for a stable and reasonable heat balance solution starting
2169 : // point.
2170 :
2171 : // METHODOLOGY EMPLOYED:
2172 : // This subroutine assumes that the simulation is at steady state at
2173 : // the beginning and then begins to vary. Thus, the temperatures, the
2174 : // fluxes. and their histories can all be set to the same value. Some
2175 : // of the initializations depend on the surface characteristics. This
2176 : // requires a DO loop to perform the proper calculation.
2177 :
2178 : // REFERENCES:
2179 : // (I)BLAST legacy routine INITTH
2180 :
2181 : // First do the "bulk" initializations of arrays sized to NumOfZones
2182 1157 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2183 674 : new (&state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum)) ZoneTempPredictorCorrector::ZoneHeatBalanceData();
2184 : // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
2185 674 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
2186 674 : thisZoneHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
2187 674 : thisZoneHB.airHumRat = state.dataEnvrn->OutHumRat;
2188 674 : state.dataHeatBalFanSys->TempTstatAir(zoneNum) = DataHeatBalance::ZoneInitialTemp;
2189 : }
2190 1205 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
2191 722 : thisEnclosure.MRT = DataHeatBalance::ZoneInitialTemp;
2192 483 : }
2193 : // Reset spaceHeatBalance even if doSpaceHeatBalance is false, because spaceHB is used to gether zoneHB in some cases
2194 1255 : for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
2195 772 : new (&thisSpaceHB) ZoneTempPredictorCorrector::SpaceHeatBalanceData();
2196 : // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
2197 772 : thisSpaceHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
2198 772 : thisSpaceHB.airHumRat = state.dataEnvrn->OutHumRat;
2199 483 : }
2200 :
2201 : // "Bulk" initializations of arrays sized to TotSurfaces
2202 1157 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2203 1446 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2204 772 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2205 772 : int const firstSurf = thisSpace.HTSurfaceFirst;
2206 772 : int const lastSurf = thisSpace.HTSurfaceLast;
2207 4894 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2208 4122 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = DataHeatBalance::SurfInitialTemp;
2209 4122 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp; // module level array
2210 4122 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = DataHeatBalance::SurfInitialTemp; // module level array
2211 4122 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) = DataHeatBalance::SurfInitialConvCoeff; // module level array
2212 4122 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
2213 4122 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
2214 4122 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
2215 4122 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
2216 4122 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = 0.0;
2217 4122 : state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = 0.0;
2218 4122 : state.dataHeatBalSurf->SurfQConvInRep(SurfNum) = 0.0;
2219 4122 : state.dataHeatBalSurf->SurfQdotConvInRep(SurfNum) = 0.0;
2220 4122 : state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum) = 0.0;
2221 4122 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(SurfNum) = 0.0;
2222 4122 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(SurfNum) = 0.0;
2223 4122 : state.dataHeatBalSurf->SurfQRadSolarInRep(SurfNum) = 0.0;
2224 4122 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(SurfNum) = 0.0;
2225 4122 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(SurfNum) = 0.0;
2226 4122 : state.dataHeatBalSurf->SurfQRadLightsInRep(SurfNum) = 0.0;
2227 4122 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(SurfNum) = 0.0;
2228 4122 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(SurfNum) = 0.0;
2229 4122 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(SurfNum) = 0.0;
2230 4122 : state.dataHeatBalSurf->SurfQRadHVACInRep(SurfNum) = 0.0;
2231 4122 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(SurfNum) = 0.0;
2232 4122 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) = 0.0;
2233 4122 : state.dataHeatBalSurf->SurfQConvOutReport(SurfNum) = 0.0;
2234 4122 : state.dataHeatBalSurf->SurfQdotConvOutRep(SurfNum) = 0.0;
2235 4122 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = 0.0;
2236 4122 : state.dataHeatBalSurf->SurfQRadOutReport(SurfNum) = 0.0;
2237 4122 : state.dataHeatBalSurf->SurfQdotRadOutRep(SurfNum) = 0.0;
2238 4122 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = 0.0;
2239 4122 : state.dataHeatBalSurf->SurfQAirExtReport(SurfNum) = 0.0;
2240 4122 : state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) = 0.0;
2241 : } // end of Surf array
2242 772 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
2243 772 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
2244 772 : if (firstSurfOpaq >= 0) {
2245 4668 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
2246 3896 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = 0.0;
2247 3896 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 0.0;
2248 3896 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(SurfNum) = 0.0;
2249 3896 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
2250 : } // end of Zone Surf
2251 : }
2252 772 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2253 772 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2254 772 : if (firstSurfWin >= 0) {
2255 998 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2256 : // Initialize window frame and divider temperatures
2257 226 : state.dataSurface->SurfWinFrameTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
2258 226 : state.dataSurface->SurfWinFrameTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
2259 226 : state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
2260 226 : state.dataSurface->SurfWinDividerTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
2261 226 : state.dataSurface->SurfWinDividerTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
2262 226 : state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
2263 :
2264 : // Initialize previous-timestep shading indicators
2265 226 : state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) = DataSurfaces::WinShadingType::NoShade;
2266 226 : state.dataSurface->SurfWinShadingFlag(SurfNum) = DataSurfaces::WinShadingType::NoShade;
2267 : } // end of Zone Surf
2268 : }
2269 674 : }
2270 : } // end of Zone
2271 :
2272 : // "Bulk" initializations of temperature arrays with dimensions (TotSurface,MaxCTFTerms,2)
2273 1157 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2274 1446 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2275 772 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2276 772 : int const firstSurf = thisSpace.HTSurfaceFirst;
2277 772 : int const lastSurf = thisSpace.HTSurfaceLast;
2278 15440 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2279 92986 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2280 78318 : state.dataHeatBalSurf->SurfInsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2281 78318 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2282 78318 : state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
2283 78318 : state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
2284 : }
2285 : }
2286 674 : }
2287 : }
2288 483 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
2289 236 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2290 252 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2291 126 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2292 126 : int const firstSurf = thisSpace.HTSurfaceFirst;
2293 126 : int const lastSurf = thisSpace.HTSurfaceLast;
2294 888 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2295 762 : state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
2296 : }
2297 2520 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2298 16872 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2299 14478 : state.dataHeatBalSurf->SurfInsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2300 14478 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
2301 14478 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
2302 14478 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
2303 : }
2304 : }
2305 126 : }
2306 : }
2307 : }
2308 483 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
2309 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2310 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2311 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2312 0 : int const firstSurf = thisSpace.HTSurfaceFirst;
2313 0 : int const lastSurf = thisSpace.HTSurfaceLast;
2314 0 : for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
2315 0 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2316 0 : state.dataHeatBalSurf->SurfTsrcHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2317 0 : state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2318 0 : state.dataHeatBalSurf->SurfTuserHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2319 0 : state.dataHeatBalSurf->SurfTuserHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
2320 0 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, CTFTermNum) = 0.0;
2321 0 : state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, CTFTermNum) = 0.0;
2322 : }
2323 : }
2324 0 : }
2325 : }
2326 : }
2327 483 : state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
2328 :
2329 : // Perform other initializations that depend on the surface characteristics
2330 4190 : for (int CTFTermNum = 1; CTFTermNum <= state.dataHeatBal->MaxCTFTerms + 1; ++CTFTermNum) {
2331 38215 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2332 34508 : auto &surface = state.dataSurface->Surface(SurfNum);
2333 : // Reset outside boundary conditions if necessary
2334 34508 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
2335 21363 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
2336 13145 : } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
2337 2689 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
2338 2689 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
2339 10456 : } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
2340 0 : state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
2341 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
2342 : }
2343 : // Initialize the flux histories
2344 34508 : state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) =
2345 34508 : state.dataConstruction->Construct(surface.Construction).UValue *
2346 34508 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum));
2347 34508 : state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2348 3707 : }
2349 : }
2350 4605 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2351 4122 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
2352 0 : state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TbaffleLast = 20.0;
2353 0 : state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TairLast = 20.0;
2354 : }
2355 483 : }
2356 : // Initialize Kiva convection algorithms
2357 483 : for (int SurfNum : state.dataSurface->AllHTKivaSurfaceList) {
2358 0 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = KIVA_CONST_CONV(3.076);
2359 0 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].f = KIVA_HF_DEF;
2360 0 : state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].out = KIVA_CONST_CONV(0.0);
2361 483 : }
2362 483 : if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
2363 872 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
2364 762 : auto &surface = state.dataSurface->Surface(SurfNum);
2365 762 : if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
2366 11880 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2367 11286 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
2368 : }
2369 762 : } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
2370 0 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2371 0 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
2372 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
2373 : }
2374 168 : } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
2375 0 : for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
2376 0 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
2377 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
2378 : }
2379 : }
2380 3046 : for (int CTFTermNum = 2; CTFTermNum <= state.dataConstruction->Construct(surface.Construction).NumCTFTerms + 1; ++CTFTermNum) {
2381 2284 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2382 2284 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
2383 : }
2384 110 : }
2385 : }
2386 :
2387 483 : if (state.dataSurface->TotOSCM >= 1) {
2388 2 : for (int OSCMnum = 1; OSCMnum <= state.dataSurface->TotOSCM; ++OSCMnum) {
2389 1 : auto &thisOSC = state.dataSurface->OSCM(OSCMnum);
2390 1 : thisOSC.TConv = 20.0;
2391 1 : thisOSC.HConv = 4.0;
2392 1 : thisOSC.TRad = 20.0;
2393 1 : thisOSC.HRad = 4.0;
2394 : }
2395 : }
2396 483 : }
2397 :
2398 3 : void EvalOutsideMovableInsulation(EnergyPlusData &state)
2399 : {
2400 : // This subroutine determines whether or not outside movable insulation on opaque surfaces is present at the current time.
2401 3 : auto &s_mat = state.dataMaterial;
2402 3 : auto &s_surf = state.dataSurface;
2403 :
2404 6 : for (int SurfNum : s_surf->extMovInsulSurfNums) {
2405 3 : auto &movInsul = s_surf->extMovInsuls(SurfNum);
2406 3 : Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
2407 3 : if (MovInsulSchedVal <= 0) { // Movable insulation not present at current time
2408 0 : movInsul.present = false;
2409 0 : int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
2410 0 : auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
2411 0 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisMaterial->AbsorpSolar;
2412 0 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisMaterial->AbsorpThermal;
2413 0 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisMaterial->Roughness;
2414 0 : continue;
2415 0 : }
2416 :
2417 3 : auto const *mat = s_mat->materials(movInsul.matNum);
2418 3 : movInsul.present = true;
2419 3 : movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
2420 3 : if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) {
2421 2 : auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
2422 2 : assert(matGlass != nullptr);
2423 2 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
2424 2 : } else {
2425 1 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = mat->AbsorpSolar;
2426 : }
2427 3 : state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = mat->AbsorpThermal;
2428 3 : state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = mat->Roughness;
2429 3 : }
2430 3 : }
2431 :
2432 3 : void EvalInsideMovableInsulation(EnergyPlusData &state)
2433 : {
2434 3 : auto &s_mat = state.dataMaterial;
2435 3 : auto &s_surf = state.dataSurface;
2436 : // This subroutine determines whether or not inside movable insulation is present at the current time.
2437 6 : for (int SurfNum : s_surf->intMovInsulSurfNums) {
2438 3 : auto &movInsul = s_surf->intMovInsuls(SurfNum);
2439 3 : Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
2440 3 : if (MovInsulSchedVal <= 0.0) { // Movable insulation not present at current time
2441 0 : movInsul.present = false;
2442 0 : int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
2443 0 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
2444 0 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
2445 0 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
2446 0 : continue;
2447 0 : }
2448 :
2449 3 : auto const *mat = s_mat->materials(movInsul.matNum);
2450 :
2451 3 : movInsul.present = true;
2452 3 : movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
2453 3 : if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) { // Glass is insulating?
2454 2 : auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
2455 2 : assert(matGlass != nullptr);
2456 2 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
2457 2 : } else {
2458 1 : state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = mat->AbsorpSolar;
2459 : }
2460 3 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = mat->AbsorpThermal;
2461 3 : }
2462 3 : }
2463 :
2464 249960 : void InitSolarHeatGains(EnergyPlusData &state)
2465 : {
2466 :
2467 : // SUBROUTINE INFORMATION:
2468 : // AUTHOR Anonymous
2469 : // DATE WRITTEN July 1977
2470 : // MODIFIED Mar99 (FW): handle movable interior shades and
2471 : // switchable glazing
2472 : // Oct99 (FW): account for Window5 glass calculation approach
2473 : // May01 (FW): handle interior and exterior blinds
2474 : // Sep03 (FW): initialize SurfaceWindow%FrameQRadOutAbs
2475 : // May06 (RR): handle exterior window screens
2476 : // RE-ENGINEERED Feb98 (RKS)
2477 :
2478 : // PURPOSE OF THIS SUBROUTINE:
2479 : // This subroutine initializes the arrays associated with solar heat
2480 : // gains for both individual surfaces and for zones. As a result,
2481 : // this routine sets the following variable arrays:
2482 : // QBV(unused), QDV, QC, QD; SurfOpaqQRadSWOutAbs and SurfOpaqQRadSWInAbs (for opaque surfaces);
2483 : // SurfWinQRadSWwinAbs (for windows)
2484 :
2485 : // METHODOLOGY EMPLOYED:
2486 : // If the sun is down, all of the pertinent arrays are zeroed. If the
2487 : // sun is up, various calculations are made.
2488 :
2489 : // REFERENCES:
2490 : // (I)BLAST legacy routine QSUN
2491 :
2492 249960 : auto &s_mat = state.dataMaterial;
2493 249960 : auto &Surface = state.dataSurface->Surface;
2494 :
2495 : // Using/Aliasing
2496 : using Dayltg::TransTDD;
2497 : using SolarShading::CalcInteriorSolarDistribution;
2498 : using namespace DataWindowEquivalentLayer;
2499 : using SolarShading::SurfaceScheduledSolarInc;
2500 : using SolarShading::WindowScheduledSolarAbs;
2501 :
2502 : // Why are these globals?
2503 249960 : auto &AbsDiffWin = state.dataHeatBalSurfMgr->AbsDiffWin;
2504 249960 : auto &AbsDiffWinGnd = state.dataHeatBalSurfMgr->AbsDiffWinGnd;
2505 249960 : auto &AbsDiffWinSky = state.dataHeatBalSurfMgr->AbsDiffWinSky;
2506 :
2507 586612 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2508 336652 : state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = 0.0;
2509 336652 : state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = 0.0;
2510 336652 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = 0.0;
2511 336652 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = 0.0;
2512 336652 : state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) = 0.0;
2513 336652 : state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) = 0.0;
2514 :
2515 336652 : state.dataHeatBal->ZoneWinHeatGain(zoneNum) = 0.0;
2516 336652 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = 0.0;
2517 336652 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = 0.0;
2518 336652 : state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) = 0.0;
2519 336652 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = 0.0;
2520 336652 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = 0.0;
2521 336652 : state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) = 0.0;
2522 336652 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = 0.0;
2523 336652 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = 0.0;
2524 : }
2525 602838 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2526 352878 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0;
2527 : }
2528 586612 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2529 706907 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2530 370255 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2531 370255 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
2532 370255 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
2533 2350615 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
2534 1980360 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = 0.0;
2535 1980360 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = 0.0;
2536 1980360 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) = 0.0;
2537 1980360 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) = 0.0;
2538 1980360 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = 0.0;
2539 1980360 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum) = 0.0;
2540 1980360 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
2541 1980360 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(SurfNum) = 0.0;
2542 1980360 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(SurfNum) = 0.0;
2543 : }
2544 :
2545 370255 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2546 370255 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2547 458825 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2548 : // Faster "inline" than calling SurfaceWindow( SurfNum ).InitSolarHeatGains()
2549 88570 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = 0.0;
2550 88570 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = 0.0;
2551 88570 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = 0.0;
2552 88570 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = 0.0;
2553 88570 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = 0.0;
2554 88570 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = 0.0;
2555 88570 : state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) = 0.0;
2556 88570 : state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = 0.0;
2557 88570 : state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = 0.0;
2558 88570 : state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0;
2559 : }
2560 :
2561 458825 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2562 88570 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0;
2563 88570 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0;
2564 88570 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0;
2565 88570 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0;
2566 88570 : state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0;
2567 88570 : state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0;
2568 88570 : state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
2569 88570 : state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0;
2570 88570 : state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
2571 : }
2572 458825 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2573 88570 : state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0;
2574 88570 : state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0;
2575 88570 : state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0;
2576 88570 : state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0;
2577 88570 : state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0;
2578 88570 : state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
2579 88570 : state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0;
2580 : }
2581 2962040 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
2582 3211775 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2583 619990 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = 0.0;
2584 : }
2585 : }
2586 336652 : }
2587 : }
2588 249960 : if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
2589 924 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2590 810 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
2591 810 : state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
2592 : }
2593 : }
2594 : bool currSolRadPositive =
2595 249960 : state.dataEnvrn->SunIsUp && (state.dataEnvrn->BeamSolarRad + state.dataEnvrn->GndSolarRad + state.dataEnvrn->DifSolarRad > 0.0);
2596 249960 : bool sunset = (!currSolRadPositive) && state.dataEnvrn->PreviousSolRadPositive;
2597 249960 : bool sunIsUpNoRad = state.dataEnvrn->SunIsUp && (!currSolRadPositive);
2598 249960 : bool resetSolar = state.dataGlobal->BeginEnvrnFlag || sunIsUpNoRad ||
2599 249960 : sunset; // Reset at (1) Beginning of simulation (2) sunset time, and SunIsUp but not solar time.
2600 249960 : state.dataEnvrn->PreviousSolRadPositive = currSolRadPositive;
2601 :
2602 249960 : if (currSolRadPositive || resetSolar) {
2603 1166401 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2604 1043435 : state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
2605 1043435 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) = 0.0;
2606 1043435 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) = 0.0;
2607 1043435 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) = 0.0;
2608 1043435 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
2609 :
2610 1043435 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) = 0.0;
2611 1043435 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = 0.0;
2612 1043435 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = 0.0;
2613 1043435 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = 0.0;
2614 :
2615 1043435 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) = 0.0;
2616 1043435 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) = 0.0;
2617 1043435 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = 0.0;
2618 1043435 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) = 0.0;
2619 1043435 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = 0.0;
2620 :
2621 1043435 : state.dataSurface->SurfSkySolarInc(SurfNum) = 0.0;
2622 1043435 : state.dataSurface->SurfGndSolarInc(SurfNum) = 0.0;
2623 : }
2624 298568 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2625 175602 : state.dataHeatBal->ZoneTransSolar(enclNum) = 0.0;
2626 175602 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclNum) = 0.0;
2627 175602 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclNum) = 0.0;
2628 175602 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclNum) = 0.0;
2629 175602 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclNum) = 0.0;
2630 175602 : state.dataHeatBal->ZoneTransSolarEnergy(enclNum) = 0.0;
2631 175602 : state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclNum) = 0.0;
2632 175602 : state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclNum) = 0.0;
2633 175602 : state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclNum) = 0.0;
2634 175602 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0;
2635 : }
2636 290055 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
2637 351922 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2638 184833 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
2639 184833 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
2640 184833 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
2641 229898 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2642 45065 : state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = 0.0;
2643 45065 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = 0.0;
2644 45065 : state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = 0.0;
2645 45065 : state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum) = 0.0;
2646 45065 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
2647 45065 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0;
2648 45065 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0;
2649 45065 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum) = 0.0;
2650 45065 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum) = 0.0;
2651 45065 : state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0;
2652 : }
2653 229898 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2654 45065 : state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = 0.0;
2655 45065 : state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = 0.0;
2656 45065 : state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = 0.0;
2657 45065 : state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = 0.0;
2658 45065 : state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = 0.0;
2659 45065 : state.dataSurface->SurfWinScTsolBmBm(SurfNum) = 0.0;
2660 45065 : state.dataSurface->SurfWinScTsolBmDif(SurfNum) = 0.0;
2661 45065 : state.dataSurface->SurfWinScTsolDifDif(SurfNum) = 0.0;
2662 45065 : state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = 0.0;
2663 45065 : state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = 0.0;
2664 45065 : state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = 0.0;
2665 45065 : state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = 0.0;
2666 45065 : state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = 0.0;
2667 : }
2668 229898 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2669 45065 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfNum) = 0.0;
2670 45065 : state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
2671 45065 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
2672 45065 : state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
2673 45065 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
2674 45065 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
2675 45065 : state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
2676 45065 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
2677 45065 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
2678 : }
2679 229898 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2680 45065 : state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
2681 45065 : state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
2682 45065 : state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
2683 45065 : state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
2684 45065 : state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
2685 45065 : state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
2686 45065 : state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfNum) = 0.0;
2687 45065 : state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0;
2688 45065 : state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0;
2689 : }
2690 :
2691 229898 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2692 45065 : state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0;
2693 45065 : state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0;
2694 45065 : state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0;
2695 45065 : state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0;
2696 45065 : state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0;
2697 45065 : state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0;
2698 45065 : state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0;
2699 45065 : state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0;
2700 45065 : state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0;
2701 45065 : state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0;
2702 45065 : state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = 0;
2703 45065 : state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) = 0.0;
2704 45065 : state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = 0.0;
2705 : }
2706 1467106 : for (int Lay = 1; Lay <= state.dataHeatBal->MaxSolidWinLayers; Lay++) {
2707 1597758 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2708 315485 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = 0.0;
2709 : }
2710 : }
2711 1293831 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL; Lay++) {
2712 1379388 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
2713 270390 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay) = 0.0;
2714 : }
2715 : }
2716 167089 : }
2717 : }
2718 : }
2719 249960 : if (resetSolar) {
2720 122048 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
2721 70297 : state.dataHeatBal->EnclSolQD(enclosureNum) = 0.0;
2722 70297 : state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) = 0.0;
2723 : }
2724 :
2725 : // TTD domes are currently not considered in the window list of a zone
2726 51751 : if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) {
2727 0 : for (auto &e : state.dataDaylightingDevicesData->TDDPipe) {
2728 0 : e.TransSolBeam = 0.0;
2729 0 : e.TransSolDiff = 0.0;
2730 0 : e.TransVisBeam = 0.0;
2731 0 : e.TransVisDiff = 0.0;
2732 0 : e.TransmittedSolar = 0.0;
2733 0 : int SurfDome = e.Dome;
2734 0 : state.dataSurface->SurfWinTransSolar(SurfDome) = 0.0;
2735 0 : state.dataHeatBal->SurfQRadSWOutIncident(SurfDome) = 0.0;
2736 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfDome) = 0.0;
2737 0 : for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
2738 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfDome, Lay) = 0.0;
2739 : }
2740 : }
2741 : }
2742 :
2743 51751 : if (state.dataSurface->CalcSolRefl) {
2744 0 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2745 0 : state.dataSurface->SurfBmToBmReflFacObs(SurfNum) = 0.0;
2746 0 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) = 0.0;
2747 0 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = 0.0;
2748 : }
2749 : }
2750 471547 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2751 419796 : state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0;
2752 419796 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = 0.0;
2753 419796 : state.dataHeatBal->SurfSWInAbsTotalReport(SurfNum) = 0.0;
2754 419796 : state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0;
2755 419796 : state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0;
2756 419796 : state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
2757 419796 : state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
2758 : }
2759 : }
2760 249960 : if (currSolRadPositive) { // Sun is up, calculate solar quantities
2761 71216 : assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
2762 : state.dataSurface->SurfReflFacBmToDiffSolObs)); // For linear indexing
2763 71216 : assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
2764 : state.dataSurface->SurfReflFacBmToDiffSolGnd)); // For linear indexing
2765 71216 : Real64 GndReflSolarRad = 0.0;
2766 71216 : Real64 GndSolarRadInc = max(state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad, 0.0);
2767 :
2768 694866 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2769 623650 : state.dataSurface->Surface(SurfNum).IncSolMultiplier = GetSurfIncidentSolarMultiplier(state, SurfNum);
2770 : }
2771 694866 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2772 623650 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2773 623650 : state.dataSurface->SurfSkySolarInc(SurfNum) =
2774 623650 : state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2775 623650 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2776 0 : GndReflSolarRad = GndSolarRadInc * SurfIncSolarMultiplier *
2777 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2778 0 : Surface(SurfNum).GndReflSolarRad = GndReflSolarRad;
2779 : } else {
2780 623650 : GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
2781 : }
2782 623650 : state.dataSurface->SurfGndSolarInc(SurfNum) = GndReflSolarRad * Surface(SurfNum).ViewFactorGround;
2783 623650 : state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2784 623650 : state.dataSurface->SurfWinBmGndSolarInc(SurfNum) = 0.0;
2785 : }
2786 71216 : if (state.dataSurface->CalcSolRefl) {
2787 : // [ lSH ] == ( HourOfDay, SurfNum ) // [ lSP ] == ( PreviousHour, SurfNum )
2788 0 : Array1D<Real64>::size_type lSH = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->HourOfDay, 1) - 1;
2789 0 : Array1D<Real64>::size_type lSP = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->PreviousHour, 1) - 1;
2790 : // For Complex Fenestrations:
2791 0 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
2792 0 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2793 :
2794 0 : Real64 GndSurfReflectance = 0.0;
2795 0 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2796 0 : GndSurfReflectance =
2797 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2798 : } else {
2799 0 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2800 : }
2801 0 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2802 0 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2803 0 : state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) =
2804 0 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2805 0 : state.dataSurface->SurfWinBmGndSolarInc(SurfNum) =
2806 0 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2807 0 : state.dataSurface->SurfBmToBmReflFacObs(SurfNum) =
2808 0 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToBmSolObs[lSH + SurfNum] +
2809 0 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToBmSolObs[lSP + SurfNum];
2810 0 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) =
2811 0 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolObs[lSH + SurfNum] +
2812 0 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolObs[lSP + SurfNum];
2813 0 : state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) =
2814 0 : state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSH + SurfNum] +
2815 0 : state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSP + SurfNum];
2816 : // TH2 CR 9056
2817 0 : state.dataSurface->SurfSkySolarInc(SurfNum) +=
2818 0 : currBeamSolarRad * (state.dataSurface->SurfBmToBmReflFacObs(SurfNum) + state.dataSurface->SurfBmToDiffReflFacObs(SurfNum)) +
2819 0 : currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
2820 0 : state.dataSurface->SurfGndSolarInc(SurfNum) =
2821 0 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) +
2822 0 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2823 0 : state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
2824 : }
2825 : }
2826 :
2827 71216 : SolarShading::CalcWindowProfileAngles(state);
2828 :
2829 71216 : if (state.dataHeatBal->CalcWindowRevealReflection) {
2830 0 : SolarShading::CalcBeamSolarOnWinRevealSurface(state);
2831 : }
2832 :
2833 71216 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() && state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
2834 0 : SolarShading::CalcAbsorbedOnExteriorOpaqueSurfaces(state);
2835 0 : if (state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
2836 0 : SolarShading::CalcInteriorSolarDistributionWCESimple(state);
2837 : }
2838 : } else {
2839 71216 : SolarShading::CalcInteriorSolarDistribution(state);
2840 : }
2841 :
2842 176522 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
2843 :
2844 : // TH 3/24/2010 - QBV is not used!
2845 : // unused QBV(ZoneNum) = (CBZone(ZoneNum) + EnclSolDB(ZoneNum))*BeamSolarRad
2846 :
2847 : // RJH 08/30/07 - QDV does not seem to ever be used. NOT USED!
2848 : // QDV(ZoneNum) = EnclSolDS(ZoneNum)*DifSolarRad &
2849 : // +EnclSolDG(ZoneNum)*GndSolarRad
2850 :
2851 : // Original QD calc used only for EnclSolQSDifSol and daylighting calcs
2852 : // QDforDaylight(ZoneNum) = EnclSolDB(ZoneNum)*BeamSolarRad &
2853 : // +EnclSolDS(ZoneNum)*DifSolarRad &
2854 : // +EnclSolDG(ZoneNum)*GndSolarRad
2855 :
2856 : // Beam from interior windows (EnclSolDBIntWin) reflected from floor is counted in DayltgInterReflIllFrIntWins,
2857 : // EnclSolDB needs to subtract this part since it is already counted in EnclSolDB.
2858 : // Use EnclSolInitialDifSolReflW (Rob's previous work) as it better counts initial distribution of
2859 : // diffuse solar rather than using weighted area*absorptance
2860 105306 : state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) =
2861 105306 : (state.dataHeatBal->EnclSolDB(enclosureNum) - state.dataHeatBal->EnclSolDBIntWin(enclosureNum)) * state.dataEnvrn->BeamSolarRad +
2862 105306 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) + state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
2863 :
2864 : // to exclude diffuse solar now absorbed/transmitted in CalcWinTransDifSolInitialDistribution
2865 : // EnclSolDB(ZoneNum) is Diffuse Solar from beam reflected from interior surfaces
2866 : // and transmitted through interior windows
2867 : // EnclSolDB is a factor that when multiplied by BeamSolarRad [W/m2] gives Watts
2868 : // QD(ZoneNum) = EnclSolDB(ZoneNum)*BeamSolarRad &
2869 : // +EnclSolDS(ZoneNum)*DifSolarRad &
2870 : // +EnclSolDG(ZoneNum)*GndSolarRad
2871 210612 : state.dataHeatBal->EnclSolQD(enclosureNum) = state.dataHeatBal->EnclSolDB(enclosureNum) * state.dataEnvrn->BeamSolarRad +
2872 105306 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) +
2873 105306 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
2874 : }
2875 :
2876 : // Flux of diffuse solar in each zone
2877 :
2878 176522 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2879 105306 : state.dataHeatBal->EnclSolQSDifSol(enclNum) = state.dataHeatBal->EnclSolQDforDaylight(enclNum);
2880 : }
2881 :
2882 71216 : if (state.dataHeatBalSurf->InterZoneWindow) {
2883 0 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2884 0 : if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclNum)) {
2885 0 : Real64 EnclSolQSDifSol_sum(0.0); // Accumulator
2886 0 : int lZone(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.index(enclNum,
2887 0 : 1)); // Tuned Linear indexing
2888 0 : for (int otherEnclNum = 1; otherEnclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++otherEnclNum, ++lZone) {
2889 0 : if ((otherEnclNum != enclNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(otherEnclNum))) {
2890 0 : EnclSolQSDifSol_sum += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[lZone] *
2891 0 : state.dataHeatBal->EnclSolQDforDaylight(otherEnclNum); // [ lZone ] == ( enclNum, otherEnclNum )
2892 : }
2893 : }
2894 0 : state.dataHeatBal->EnclSolQSDifSol(enclNum) += EnclSolQSDifSol_sum;
2895 : }
2896 : }
2897 : }
2898 :
2899 176522 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
2900 105306 : if (state.dataHeatBalSurf->InterZoneWindow) {
2901 0 : state.dataHeatBal->EnclSolQSDifSol(enclNum) *=
2902 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclNum, enclNum) * state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
2903 : } else {
2904 105306 : state.dataHeatBal->EnclSolQSDifSol(enclNum) *= state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
2905 : }
2906 : }
2907 :
2908 : // RJH - 09-12-07 commented out report variable calcs here since they refer to old distribution method
2909 : // DO SurfNum = 1, TotSurfaces
2910 : // IF (.NOT. Surface(SurfNum)%HeatTransSurf) CYCLE
2911 : //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
2912 : // IF (Surface(SurfNum)%Class == SurfaceClass::Shading) CYCLE
2913 : // ZoneNum = Surface(SurfNum)%Zone
2914 : // Diffuse solar entering zone through exterior windows is assumed to be uniformly
2915 : // distributed on inside face of surfaces of zone
2916 : // DifIncInsSurfIntensRep(SurfNum) = (EnclSolDS(ZoneNum)*DifSolarRad + EnclSolDG(ZoneNum)*GndSolarRad) / &
2917 : // Zone(ZoneNum)%TotalSurfArea
2918 : // DifIncInsSurfAmountRep(SurfNum) = (Surface(SurfNum)%Area + SurfaceWindow(SurfNum)%DividerArea) * &
2919 : // DifIncInsSurfIntensRep(SurfNum)
2920 : // DifIncInsSurfAmountRepEnergy(SurfNum) = DifIncInsSurfAmountRep(SurfNum) * TimeStepZoneSec
2921 : // END DO
2922 :
2923 : // Calculate Exterior Incident Short Wave (i.e. Solar) Radiation on shading surfaces
2924 71216 : if (state.dataSurface->BuildingShadingCount || state.dataSurface->FixedShadingCount || state.dataSurface->AttachedShadingCount) {
2925 14980 : for (int SurfNum = state.dataSurface->ShadingSurfaceFirst; SurfNum <= state.dataSurface->ShadingSurfaceLast; SurfNum++) {
2926 11984 : Real64 GndSurfReflectance = 0.0;
2927 11984 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2928 0 : GndSurfReflectance =
2929 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2930 : } else {
2931 11984 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2932 : }
2933 : // Cosine of incidence angle and solar incident on outside of surface, for reporting
2934 11984 : Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
2935 11984 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = CosInc;
2936 11984 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2937 11984 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2938 11984 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2939 : // Incident direct (unreflected) beam
2940 11984 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
2941 11984 : currBeamSolarRad * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) * CosInc;
2942 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
2943 11984 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2944 : // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
2945 11984 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2946 : // Incident diffuse solar from beam-to-diffuse reflection from ground
2947 11984 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
2948 11984 : currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2949 : // Incident diffuse solar from sky diffuse reflection from ground
2950 11984 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
2951 11984 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
2952 : // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
2953 : // in SkySolarInc.
2954 11984 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
2955 11984 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
2956 11984 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
2957 : }
2958 : }
2959 :
2960 71216 : Array1D<Real64> currBeamSolar(state.dataSurface->TotSurfaces); // Local variable for BeamSolarRad
2961 :
2962 462416 : for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
2963 391200 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
2964 : // Regular surface
2965 391200 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
2966 391200 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
2967 : // Cosine of incidence angle and solar incident on outside of surface, for reporting
2968 391200 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
2969 391200 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
2970 :
2971 : // Report variables for various incident solar quantities
2972 : // Incident direct (unreflected) beam
2973 391200 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
2974 391200 : currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
2975 391200 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum);
2976 :
2977 391200 : Real64 GndSurfReflectance = 0.0;
2978 391200 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
2979 0 : GndSurfReflectance =
2980 0 : state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
2981 : } else {
2982 391200 : GndSurfReflectance = state.dataEnvrn->GndReflectance;
2983 : }
2984 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
2985 391200 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
2986 : // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
2987 391200 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
2988 : // Incident diffuse solar from beam-to-diffuse reflection from ground
2989 391200 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
2990 391200 : currBeamSolar(SurfNum) * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
2991 :
2992 : // Incident diffuse solar from sky diffuse reflection from ground
2993 391200 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
2994 391200 : currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
2995 : // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
2996 : // in SkySolarInc.
2997 : // SurfQRadSWOutIncident(SurfNum) = SurfQRadSWOutIncidentBeam(SurfNum) + SkySolarInc + GndSolarInc
2998 : // TH2 CR 9056
2999 391200 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
3000 391200 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
3001 391200 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
3002 :
3003 391200 : if (state.dataSurface->CalcSolRefl) {
3004 : // Incident beam solar from beam-to-beam (specular) reflection from obstructions
3005 0 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = state.dataSurface->SurfBmToBmReflFacObs(SurfNum) * currBeamSolar(SurfNum);
3006 : // Incident diffuse solar from beam-to-diffuse reflection from obstructions
3007 0 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) =
3008 0 : state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) * currBeamSolar(SurfNum);
3009 : // Incident diffuse solar from sky diffuse reflection from obstructions
3010 0 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
3011 : // TH2 CR 9056: Add reflections from obstructions to the total incident
3012 0 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) += state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) +
3013 0 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) +
3014 0 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum);
3015 : }
3016 71216 : }
3017 71216 : for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
3018 0 : int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser; // TDD: Diffuser object number
3019 0 : int const SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
3020 0 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3021 0 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3022 :
3023 : // Reconstruct the beam, sky, and ground radiation transmittance of just the TDD:DOME and TDD pipe
3024 : // by dividing out diffuse solar transmittance of TDD:DIFFUSER
3025 0 : Real64 ConInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
3026 :
3027 0 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = ConInc;
3028 0 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3029 0 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier *
3030 0 : TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarBeam) / thisConstruct.TransDiff;
3031 :
3032 0 : state.dataSurface->SurfSkySolarInc(SurfNum) = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier *
3033 0 : state.dataSolarShading->SurfAnisoSkyMult(SurfNum2) *
3034 0 : TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarAniso) / thisConstruct.TransDiff;
3035 :
3036 0 : state.dataSurface->SurfGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum2) *
3037 0 : state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolIso / thisConstruct.TransDiff;
3038 : // Incident direct (unreflected) beam
3039 0 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = currBeamSolar(SurfNum) *
3040 0 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay,
3041 0 : state.dataGlobal->TimeStep,
3042 0 : SurfNum2) *
3043 : ConInc; // NOTE: sunlit and coninc array set to SurfNum2
3044 :
3045 : // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
3046 0 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = state.dataSurface->SurfSkySolarInc(SurfNum);
3047 0 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
3048 0 : (state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
3049 0 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum));
3050 : }
3051 :
3052 71216 : for (int ShelfNum = 1; ShelfNum <= (int)state.dataDaylightingDevicesData->Shelf.size(); ++ShelfNum) {
3053 0 : int SurfNum = state.dataDaylightingDevicesData->Shelf(ShelfNum).Window; // Daylighting shelf object number
3054 0 : int OutShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf; // Outside daylighting shelf present if > 0
3055 0 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
3056 0 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
3057 0 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3058 0 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3059 : // Shelf diffuse solar radiation
3060 : Real64 ShelfSolarRad =
3061 0 : (currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) *
3062 0 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) +
3063 0 : state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(OutShelfSurf)) *
3064 0 : state.dataDaylightingDevicesData->Shelf(ShelfNum).OutReflectSol;
3065 :
3066 0 : GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
3067 0 : if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
3068 0 : GndReflSolarRad = state.dataSurface->Surface(SurfNum).GndReflSolarRad;
3069 : }
3070 : // Add all reflected solar from the outside shelf to the ground solar
3071 : // NOTE: If the shelf blocks part of the view to the ground, the user must reduce the ground view factor!!
3072 0 : state.dataSurface->SurfGndSolarInc(SurfNum) =
3073 0 : GndReflSolarRad * Surface(SurfNum).ViewFactorGround + ShelfSolarRad * state.dataDaylightingDevicesData->Shelf(ShelfNum).ViewFactor;
3074 : }
3075 :
3076 : // Calculate Exterior and Interior Absorbed Short Wave Radiation
3077 170521 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3078 211316 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3079 112011 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
3080 112011 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
3081 112011 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
3082 692571 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
3083 580560 : int const ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
3084 580560 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3085 580560 : currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3086 580560 : if (Surface(SurfNum).ExtSolar) {
3087 : Real64 AbsExt =
3088 348112 : state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); // Absorptivity of outer most layer (or movable insulation if present)
3089 348112 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
3090 348112 : state.dataSurface->SurfOpaqAO(SurfNum) * currBeamSolar(SurfNum) +
3091 348112 : AbsExt * (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum));
3092 : }
3093 580560 : if (ConstrNum > 0) {
3094 580560 : int SurfSolIncPtr = SolarShading::SurfaceScheduledSolarInc(state, SurfNum, ConstrNum);
3095 580560 : if (SurfSolIncPtr == 0) {
3096 580560 : if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Opaque surface
3097 580560 : int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum); // Daylighting shelf object number
3098 580560 : int InShelfSurf = 0; // Inside daylighting shelf surface number
3099 580560 : if (ShelfNum > 0) {
3100 0 : InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf; // Inside daylighting shelf present if > 0
3101 : }
3102 580560 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +=
3103 580560 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum);
3104 580560 : if (InShelfSurf > 0) { // Inside daylighting shelf
3105 : // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init)
3106 0 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
3107 0 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * (0.5 * Surface(SurfNum).Area);
3108 : } else { // Regular surface
3109 580560 : state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
3110 580560 : state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * Surface(SurfNum).Area;
3111 : }
3112 : }
3113 : } else {
3114 0 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum);
3115 : }
3116 : }
3117 : }
3118 112011 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
3119 112011 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
3120 143115 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
3121 31104 : auto &surf = state.dataSurface->Surface(SurfNum);
3122 31104 : auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
3123 31104 : if (surf.ExtSolar || surf.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
3124 : // Exclude special shading surfaces which required SurfOpaqQRadSWOut calculations above
3125 31104 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3126 31104 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3127 31104 : Real64 CosInc = state.dataHeatBal->SurfCosIncidenceAngle(SurfNum); // Cosine of incidence angle of beam solar on glass
3128 31104 : Real64 BeamSolar = currBeamSolar(SurfNum); // Local variable for BeamSolarRad
3129 31104 : Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum); // Sky diffuse solar incident on a surface
3130 31104 : Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum); // Ground diffuse solar incident on a surface
3131 :
3132 31104 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
3133 :
3134 60836 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed &&
3135 29732 : !state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
3136 29732 : int TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
3137 66665 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3138 36933 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
3139 : }
3140 :
3141 29732 : if (IS_SHADED(ShadeFlag)) { // Shaded window
3142 :
3143 0 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); // Shaded window construction
3144 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3145 :
3146 0 : if (ANY_SHADE_SCREEN(ShadeFlag)) { // Shade/screen on
3147 0 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3148 0 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = constructionSh.AbsDiff(Lay);
3149 : }
3150 0 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = constructionSh.AbsDiffShade * (SkySolarInc + GndSolarInc);
3151 :
3152 0 : } else if (ANY_BLIND(ShadeFlag)) { // Blind on
3153 0 : auto &surfShade = state.dataSurface->surfShades(SurfNum);
3154 0 : int slatIdxLo = surfShade.blind.slatAngIdxLo;
3155 0 : int slatIdxHi = surfShade.blind.slatAngIdxHi;
3156 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3157 : Real64 AbsDiffBlind;
3158 :
3159 : // For constructions, have to do interpolation whether we have movable slats or not
3160 0 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3161 0 : auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
3162 0 : auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
3163 :
3164 0 : AbsDiffWin(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.Abs, dfAbsSlatHi.Sol.Ft.Df.Abs, interpFac);
3165 0 : AbsDiffWinGnd(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3166 0 : AbsDiffWinSky(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3167 : }
3168 :
3169 0 : auto const &tarSlatLo = constructionSh.blindTARs[slatIdxLo];
3170 0 : auto const &tarSlatHi = constructionSh.blindTARs[slatIdxHi];
3171 0 : AbsDiffBlind = Interp(tarSlatLo.Sol.Ft.Df.Abs, tarSlatHi.Sol.Ft.Df.Abs, interpFac);
3172 :
3173 0 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = AbsDiffBlind * (SkySolarInc + GndSolarInc);
3174 :
3175 0 : auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
3176 0 : if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
3177 0 : Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt);
3178 :
3179 : // Need to do these interpolations unless we want to cache this in surfShade.blind.
3180 0 : Real64 AbsDiffBlindGnd = Interp(tarSlatLo.Sol.Ft.Df.AbsGnd, tarSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3181 0 : Real64 AbsDiffBlindSky = Interp(tarSlatLo.Sol.Ft.Df.AbsSky, tarSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3182 :
3183 0 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) =
3184 0 : SkySolarInc * (0.5 * ACosTlt * AbsDiffBlindGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffBlindSky) +
3185 0 : GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffBlindGnd + 0.5 * ACosTlt * AbsDiffBlindSky);
3186 : }
3187 : }
3188 :
3189 : // Correct for shadowing of divider onto interior shading device (note that dividers are
3190 : // not allowed in windows with between-glass shade/blind)
3191 :
3192 0 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
3193 0 : state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) *= surfWin.glazedFrac;
3194 : }
3195 :
3196 0 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3197 0 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for switchable glazing
3198 0 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3199 0 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) =
3200 0 : Window::InterpSw(SwitchFac, state.dataHeatBalSurfMgr->AbsDiffWin(Lay), constructionSh.AbsDiff(Lay));
3201 : }
3202 : }
3203 :
3204 : } // End of check if window has shading device on
3205 :
3206 29732 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3207 66665 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3208 36933 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3209 36933 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc) +
3210 36933 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3211 : // SurfWinA is from InteriorSolarDistribution
3212 36933 : if (ANY_BLIND(ShadeFlag)) {
3213 0 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3214 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3215 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3216 0 : auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
3217 0 : if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
3218 :
3219 0 : Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); // Absolute value of cosine of surface tilt angle
3220 :
3221 0 : int slatIdxLo = surfShade.blind.slatAngIdxLo;
3222 0 : int slatIdxHi = surfShade.blind.slatAngIdxLo;
3223 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3224 0 : auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
3225 0 : auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
3226 :
3227 0 : Real64 AbsDiffGlassLayGnd = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
3228 0 : Real64 AbsDiffGlassLaySky = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
3229 :
3230 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3231 0 : SkySolarInc * (0.5 * ACosTlt * AbsDiffGlassLayGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffGlassLaySky) +
3232 0 : GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffGlassLayGnd + 0.5 * ACosTlt * AbsDiffGlassLaySky) +
3233 0 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3234 : }
3235 : }
3236 : // Total solar absorbed in solid layer (W), for reporting
3237 36933 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3238 36933 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3239 :
3240 : // Total solar absorbed in all glass layers (W), for reporting
3241 36933 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3242 : }
3243 29732 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3244 29732 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3245 : // Need to do it this way for now because of scheduled surface gains. They do work only with
3246 : // BSDF windows and overwriting absorbtances will work only for ordinary windows
3247 : // } else if ( SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: BSDF &&
3248 : // SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: EQL &&
3249 : // inExtWindowModel->isExternalLibraryModel() ) {
3250 : // TotSolidLay = Construct( ConstrNum ).TotSolidLayers;
3251 : // for ( Lay = 1; Lay <= TotSolidLay; ++Lay ) {
3252 : // SurfWinQRadSWwinAbs( Lay, SurfNum ) = SurfWinA( Lay, SurfNum ) *
3253 : // ( SurfQRadSWOutIncident( SurfNum ) + QS( Surface( SurfNum ).Zone ) );
3254 : // }
3255 1372 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
3256 0 : int TotSolidLay = state.dataConstruction->Construct(ConstrNum).TotSolidLayers;
3257 : // Number of solid layers in fenestration system (glass + shading)
3258 0 : int CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState;
3259 : // Current state for Complex Fenestration
3260 : // Examine for schedule surface gain
3261 0 : Real64 SurfSolAbs = SolarShading::WindowScheduledSolarAbs(
3262 : state,
3263 : SurfNum,
3264 0 : ConstrNum); // Pointer to scheduled surface gains object for fenestration systems
3265 :
3266 0 : for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
3267 0 : if (SurfSolAbs != 0) {
3268 0 : state.dataSurface->SurfWinA(SurfNum, Lay) =
3269 0 : state.dataSurface->FenLayAbsSSG(SurfSolAbs).scheds(Lay)->getCurrentVal();
3270 : // ABWin(Lay) = SurfWinA(SurfNum,Lay)
3271 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = state.dataSurface->SurfWinA(SurfNum, Lay);
3272 : } else {
3273 : // Several notes about this equation. First part is accounting for diffuse solar radiation for the ground
3274 : // and from the sky. Second item (SurfWinA(SurfNum,Lay) * BeamSolar) is accounting for absorbed solar
3275 : // radiation originating from beam on exterior side. Third item (SurfWinACFOverlap(SurfNum,Lay)) is
3276 : // accounting for absorptances from beam hitting back of the window which passes through rest of exterior
3277 : // windows
3278 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3279 0 : state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyFtAbs(Lay) * SkySolarInc +
3280 0 : state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyGndAbs(Lay) * GndSolarInc +
3281 0 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
3282 0 : state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * BeamSolar;
3283 : }
3284 : // Total solar absorbed in solid layer (W), for reporting
3285 0 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3286 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3287 :
3288 : // Total solar absorbed in all glass layers (W), for reporting
3289 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3290 : }
3291 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3292 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3293 :
3294 1372 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
3295 1372 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3296 : // EQLNum = Construct(Surface(SurfNum)%Construction)%EQLConsPtr
3297 : int TotSolidLay =
3298 1372 : state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(Surface(SurfNum).Construction).EQLConsPtr).NL;
3299 4970 : for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
3300 : // Absorbed window components include:
3301 : // (1) beam solar radiation absorbed by all layers in the fenestration
3302 : // (2) sky and ground reflected diffuse solar radiation absorbed by all layers
3303 : // (3) diffuse short wave incident on the inside face of the fenestration. The short wave internal sources
3304 : // include light, ...
3305 3598 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay);
3306 3598 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3307 3598 : state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
3308 3598 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc);
3309 :
3310 : // Total solar absorbed in solid layer (W), for reporting
3311 3598 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3312 3598 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3313 :
3314 : // Total solar absorbed in all glass layers (W), for reporting
3315 3598 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3316 : }
3317 :
3318 1372 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3319 1372 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3320 0 : } else if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
3321 0 : int SurfNum2 = SurfNum;
3322 0 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
3323 0 : SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
3324 : }
3325 :
3326 : std::pair<Real64, Real64> incomingAngle =
3327 0 : Window::getSunWCEAngles(state, SurfNum2, SingleLayerOptics::BSDFDirection::Incoming);
3328 0 : Real64 Theta = incomingAngle.first;
3329 0 : Real64 Phi = incomingAngle.second;
3330 :
3331 : std::shared_ptr<MultiLayerOptics::CMultiLayerScattered> aLayer =
3332 0 : Window::CWindowConstructionsSimplified::instance(state).getEquivalentLayer(
3333 0 : state, FenestrationCommon::WavelengthRange::Solar, ConstrNum);
3334 :
3335 0 : size_t totLayers = aLayer->getNumOfLayers();
3336 0 : for (size_t Lay = 1; Lay <= totLayers; ++Lay) {
3337 0 : Real64 AbWinDiff = aLayer->getAbsorptanceLayer(
3338 : Lay, FenestrationCommon::Side::Front, FenestrationCommon::ScatteringSimple::Diffuse, Theta, Phi);
3339 :
3340 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3341 0 : AbWinDiff * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
3342 :
3343 : // Total solar absorbed in solid layer (W), for reporting
3344 0 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3345 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3346 :
3347 : // Total solar absorbed in all glass layers (W), for reporting
3348 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3349 : }
3350 0 : }
3351 :
3352 : // Solar absorbed by window frame and dividers
3353 31104 : int FrDivNum = Surface(SurfNum).FrameDivider; // Frame/divider number
3354 31104 : if (FrDivNum > 0) {
3355 0 : Real64 FrArea = state.dataSurface->SurfWinFrameArea(SurfNum); // Frame, divider area (m2)
3356 0 : Real64 FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut; // Frame, divider outside projection (m)
3357 0 : Real64 FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn;
3358 0 : Real64 DivArea = state.dataSurface->SurfWinDividerArea(SurfNum);
3359 0 : Real64 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
3360 0 : Real64 DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut;
3361 0 : Real64 DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn;
3362 0 : Real64 CosIncAngHorProj = 0.0; // Cosine of incidence angle of sun on horizontal faces of a frame or divider projection
3363 0 : Real64 CosIncAngVertProj = 0.0; // Cosine of incidence angle of sun on vertical faces of a frame or divider projection
3364 0 : Real64 FracSunLit = 0.0; // Fraction of window sunlit this time step
3365 : Real64 BeamFaceInc; // Beam solar incident window plane this time step (W/m2)
3366 : Real64 DifSolarFaceInc; // Diffuse solar incident on window plane this time step (W/m2)
3367 0 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
3368 0 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
3369 0 : if (FrArea > 0.0 || DivArea > 0.0) {
3370 0 : FracSunLit = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
3371 0 : BeamFaceInc = currBeamSolarRad *
3372 0 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
3373 : CosInc;
3374 0 : DifSolarFaceInc = SkySolarInc + GndSolarInc;
3375 : }
3376 0 : if (FracSunLit > 0.0) {
3377 0 : if ((FrArea > 0.0 && (FrProjOut > 0.0 || FrProjIn > 0.0)) ||
3378 0 : (DivArea > 0.0 && (DivProjOut > 0.0 || DivProjIn > 0.0))) {
3379 : // Dot products used to calculate beam solar incident on faces of
3380 : // frame and divider perpendicular to the glass surface.
3381 : // Note that SOLCOS is the current timestep's solar direction cosines.
3382 : // PhiWin = ASIN(WALCOS(3,SurfNum))
3383 : Real64 PhiWin =
3384 0 : std::asin(Surface(SurfNum).OutNormVec(3)); // Altitude and azimuth angle of outward window normal (radians)
3385 0 : Real64 ThWin = std::atan2(Surface(SurfNum).OutNormVec(2), Surface(SurfNum).OutNormVec(1));
3386 0 : Real64 PhiSun = std::asin(state.dataEnvrn->SOLCOS(3)); // Altitude and azimuth angle of sun (radians)
3387 0 : Real64 ThSun = std::atan2(state.dataEnvrn->SOLCOS(2), state.dataEnvrn->SOLCOS(1));
3388 0 : Real64 const cos_PhiWin(std::cos(PhiWin));
3389 0 : Real64 const cos_PhiSun(std::cos(PhiSun));
3390 : CosIncAngHorProj =
3391 0 : std::abs(std::sin(PhiWin) * cos_PhiSun * std::cos(ThWin - ThSun) - cos_PhiWin * std::sin(PhiSun));
3392 0 : CosIncAngVertProj = std::abs(cos_PhiWin * cos_PhiSun * std::sin(ThWin - ThSun));
3393 : }
3394 : }
3395 : // Frame solar
3396 : // (A window shade or blind, if present, is assumed to not shade the frame, so no special
3397 : // treatment of frame solar needed if window has an exterior shade or blind.)
3398 0 : if (FrArea > 0.0) {
3399 0 : Real64 FrIncSolarOut = BeamFaceInc; // Total solar incident on outside of frame including solar
3400 0 : Real64 FrIncSolarIn = 0.0; // Total solar incident on inside of frame including solar on frame projection (W/m2)
3401 0 : Real64 TransDiffGl = 0.0; // Diffuse solar transmittance
3402 0 : if (FrProjOut > 0.0 || FrProjIn > 0.0) {
3403 : Real64 BeamFrHorFaceInc =
3404 0 : currBeamSolarRad * CosIncAngHorProj *
3405 0 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit /
3406 0 : FrArea;
3407 : Real64 BeamFrVertFaceInc =
3408 0 : currBeamSolarRad * CosIncAngVertProj *
3409 0 : (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
3410 0 : FrArea;
3411 : // Beam solar on outside of frame
3412 0 : FrIncSolarOut += (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjOut;
3413 0 : if (FrProjIn > 0.0) {
3414 0 : Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
3415 0 : TransDiffGl = thisConstruct.TransDiff;
3416 0 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3417 0 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3418 0 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3419 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3420 0 : Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
3421 0 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3422 0 : Real64 TransDiffGlSh = constructionSh.TransDiff;
3423 0 : TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
3424 : }
3425 : // Beam solar on inside of frame
3426 0 : FrIncSolarIn = (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjIn * TransGl;
3427 : }
3428 : }
3429 : // Beam plus diffuse solar on outside of frame
3430 0 : FrIncSolarOut += DifSolarFaceInc * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum));
3431 0 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) =
3432 0 : FrIncSolarOut * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3433 : // Add diffuse from beam reflected from window outside reveal surfaces
3434 0 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) += currBeamSolarRad *
3435 0 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) *
3436 0 : state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3437 :
3438 : // Beam plus diffuse solar on inside of frame
3439 0 : FrIncSolarIn += DifSolarFaceInc * TransDiffGl * 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum);
3440 0 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = FrIncSolarIn * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3441 : // Add diffuse from beam reflected from window inside reveal surfaces
3442 0 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += currBeamSolarRad *
3443 0 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) *
3444 0 : state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
3445 : }
3446 :
3447 : // Divider solar
3448 : // (An exterior shade or blind, when in place, is assumed to completely cover the divider.
3449 : // Dividers are not allowed on windows with between-glass shade/blind so DivProjOut and
3450 : // DivProjIn will be zero in this case.)
3451 0 : if (DivArea > 0.0) { // Solar absorbed by window divider
3452 0 : Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
3453 0 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
3454 : // Suspended (between-glass) divider; account for effect glass on outside of divider
3455 : // (note that outside and inside projection for this type of divider are both zero)
3456 0 : int MatNumGl = thisConstruct.LayerPoint(1); // Outer glass layer material number
3457 0 : auto const *thisMaterial = dynamic_cast<Material::MaterialFen *>(s_mat->materials(MatNumGl));
3458 0 : assert(thisMaterial != nullptr);
3459 0 : Real64 TransGl = thisMaterial->Trans; // Outer glass layer material number, switched construction
3460 0 : Real64 ReflGl = thisMaterial->ReflectSolBeamFront;
3461 0 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
3462 0 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3463 0 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3464 0 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3465 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3466 0 : Real64 MatNumGlSh = constructionSh.LayerPoint(1);
3467 0 : auto const *thisMaterialSh = dynamic_cast<Material::MaterialGlass *>(s_mat->materials(MatNumGlSh));
3468 0 : assert(thisMaterialSh != nullptr);
3469 0 : Real64 TransGlSh = thisMaterialSh->Trans;
3470 0 : Real64 ReflGlSh = thisMaterialSh->ReflectSolBeamFront;
3471 0 : Real64 AbsGlSh = 1.0 - TransGlSh - ReflGlSh;
3472 0 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3473 0 : ReflGl = Window::InterpSw(SwitchFac, ReflGl, ReflGlSh);
3474 0 : AbsGl = Window::InterpSw(SwitchFac, AbsGl, AbsGlSh);
3475 : }
3476 0 : Real64 DividerRefl = 1.0 - DividerAbs; // Window divider solar reflectance
3477 0 : DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
3478 : }
3479 :
3480 0 : Real64 BeamDivHorFaceInc = 0.0; // Beam solar on divider's horizontal outside projection faces (W/m2)
3481 0 : Real64 BeamDivVertFaceInc = 0.0; // Beam solar on divider's vertical outside projection faces (W/m2)
3482 : // Beam incident on horizontal and vertical projection faces of divider if no exterior shading
3483 0 : if (DivProjOut > 0.0 && !DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3484 0 : BeamDivHorFaceInc = currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers *
3485 0 : DivProjOut *
3486 0 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
3487 : FracSunLit / DivArea;
3488 0 : BeamDivVertFaceInc =
3489 0 : currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivProjOut *
3490 0 : (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
3491 : DivArea;
3492 : }
3493 0 : Real64 DivIncSolarOutBm =
3494 : 0.0; // Diffuse solar incident on outside of divider including beam on divider projection (W/m2)
3495 0 : Real64 DivIncSolarOutDif =
3496 : 0.0; // Diffuse solar incident on outside of divider including diffuse on divider projection (W/m2)
3497 0 : Real64 DivIncSolarInBm =
3498 : 0.0; // Diffuse solar incident on inside of divider including beam on divider projection (W/m2)
3499 0 : Real64 DivIncSolarInDif =
3500 : 0.0; // Diffuse solar incident on inside of divider including diffuse on divider projection (W/m2)
3501 0 : if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) &&
3502 0 : !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { // No exterior or between-glass shading
3503 0 : DivIncSolarOutBm = BeamFaceInc + BeamDivHorFaceInc + BeamDivVertFaceInc;
3504 0 : DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3505 0 : if (DivProjIn > 0.0) {
3506 0 : Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
3507 0 : Real64 TransDiffGl = thisConstruct.TransDiff; // Diffuse solar transmittance
3508 0 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3509 0 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
3510 0 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3511 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3512 :
3513 0 : Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
3514 : // Outer glass solar trans, refl, absorptance if switched
3515 0 : TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
3516 0 : Real64 TransDiffGlSh = constructionSh.TransDiff;
3517 : // Diffuse solar transmittance, switched construction
3518 0 : TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
3519 : }
3520 : // Beam plus diffuse solar on inside of divider
3521 : // BeamDivHorFaceIncIn - Beam solar on divider's horizontal inside projection faces (W/m2)
3522 : // BeamDivVertFaceIncIn - Beam solar on divider's vertical inside projection faces (W/m2)
3523 : Real64 BeamDivHorFaceIncIn =
3524 0 : currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivProjIn *
3525 0 : (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
3526 0 : FracSunLit / DivArea;
3527 : Real64 BeamDivVertFaceIncIn =
3528 0 : currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers *
3529 0 : DivProjIn * (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) *
3530 0 : FracSunLit / DivArea;
3531 0 : DivIncSolarInBm = TransGl * (BeamDivHorFaceIncIn + BeamDivVertFaceIncIn);
3532 0 : DivIncSolarInDif = TransDiffGl * DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum);
3533 : }
3534 : } else { // Exterior shade, screen or blind present
3535 :
3536 0 : DivIncSolarOutBm = BeamFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3537 0 : DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
3538 0 : DivIncSolarInBm = BeamFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
3539 0 : DivIncSolarInDif = DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
3540 : }
3541 :
3542 0 : if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
3543 : // No exterior or between-glass shade, screen or blind
3544 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = DividerAbs * (DivIncSolarOutBm + DivIncSolarOutDif);
3545 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = DividerAbs * (DivIncSolarInBm + DivIncSolarInDif);
3546 : // Exterior shade, screen or blind
3547 :
3548 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) { // Exterior blind
3549 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3550 :
3551 0 : int profIdxLo = surfShade.blind.profAngIdxLo;
3552 0 : int profIdxHi = surfShade.blind.profAngIdxHi;
3553 0 : Real64 profInterpFac = surfShade.blind.profAngInterpFac;
3554 :
3555 0 : auto const &btarLo = surfShade.blind.TAR.Sol.Ft.Bm[profIdxLo];
3556 0 : auto const &btarHi = surfShade.blind.TAR.Sol.Ft.Bm[profIdxHi];
3557 :
3558 0 : Real64 FrontDiffTrans = surfShade.blind.TAR.Sol.Ft.Df.Tra;
3559 0 : Real64 TBlBmDif = Interp(btarLo.DfTra, btarHi.DfTra, profInterpFac);
3560 :
3561 : // TBlBmBm - Blind beam-beam solar transmittance
3562 0 : Real64 TBlBmBm = surfShade.blind.bmBmTrans;
3563 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3564 0 : DividerAbs * (DivIncSolarOutBm * (TBlBmBm + TBlBmDif) + DivIncSolarOutDif * FrontDiffTrans);
3565 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3566 0 : DividerAbs * (DivIncSolarInBm * (TBlBmBm + TBlBmDif) + DivIncSolarInDif * FrontDiffTrans);
3567 :
3568 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtShade) { // Exterior shade
3569 0 : int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
3570 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
3571 0 : auto const *matFen = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(constructionSh.LayerPoint(1)));
3572 0 : assert(matFen != nullptr);
3573 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3574 0 : DividerAbs * matFen->Trans * (DivIncSolarOutBm + DivIncSolarOutDif);
3575 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3576 0 : DividerAbs * matFen->Trans * (DivIncSolarInBm + DivIncSolarInDif);
3577 :
3578 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtScreen) { // Exterior screen
3579 0 : int screenNum = surfWin.screenNum;
3580 0 : auto const *screen = dynamic_cast<Material::MaterialScreen const *>(s_mat->materials(screenNum));
3581 0 : assert(screen != nullptr);
3582 :
3583 0 : auto &surf = state.dataSurface->Surface(SurfNum);
3584 : Real64 phi, theta;
3585 0 : Material::GetRelativePhiTheta(
3586 0 : surf.Tilt * Constant::DegToRad, surf.Azimuth * Constant::DegToRad, state.dataEnvrn->SOLCOS, phi, theta);
3587 : #ifdef PRECALC_INTERP_SCREEN
3588 : int ip1, ip2, it1, it2; // hi/lo phi and theta map indices
3589 : BilinearInterpCoeffs coeffs;
3590 0 : Material::GetPhiThetaIndices(phi, theta, screen->dPhi, screen->dTheta, ip1, ip2, it1, it2);
3591 0 : GetBilinearInterpCoeffs(
3592 0 : phi, theta, ip1 * screen->dPhi, ip2 * screen->dPhi, it1 * screen->dTheta, it2 * screen->dTheta, coeffs);
3593 0 : auto const &b11 = screen->btars[ip1][it1];
3594 0 : auto const &b12 = screen->btars[ip1][it2];
3595 0 : auto const &b21 = screen->btars[ip2][it1];
3596 0 : auto const &b22 = screen->btars[ip2][it2];
3597 0 : Real64 BmDfTrans = BilinearInterp(b11.DfTrans, b12.DfTrans, b21.DfTrans, b22.DfTrans, coeffs);
3598 0 : Real64 BmBmTrans = BilinearInterp(b11.BmTrans, b12.BmTrans, b21.BmTrans, b22.BmTrans, coeffs);
3599 :
3600 0 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3601 0 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
3602 0 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3603 0 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
3604 : #else // !PRECALC_INTERP_SCREEN
3605 : Material::ScreenBmTransAbsRef btar;
3606 :
3607 : Material::CalcScreenTransmittance(state, screen, phi, theta, btar);
3608 : Real64 BmDfTrans = btar.DfTrans;
3609 : Real64 BmBmTrans = btar.BmTrans;
3610 :
3611 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
3612 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
3613 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
3614 : DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
3615 : #endif // PRECALC_INTERP_SCREEN
3616 : }
3617 : }
3618 : }
3619 : } // Surface(SurfNum)%ExtSolar
3620 : } // end of surface window loop
3621 99305 : } // end of space loop
3622 : } // end of zone loop
3623 71216 : for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
3624 0 : int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
3625 0 : int const ConstrNum = Surface(SurfNum).Construction;
3626 0 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3627 0 : int const TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
3628 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
3629 0 : for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
3630 0 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
3631 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
3632 0 : state.dataHeatBalSurfMgr->AbsDiffWin(Lay) *
3633 0 : (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum)) +
3634 0 : state.dataSurface->SurfWinA(SurfNum, Lay) * currBeamSolar(SurfNum);
3635 0 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
3636 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
3637 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
3638 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
3639 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3640 : }
3641 : }
3642 :
3643 : // Average absorbed solar for representative surfaces
3644 71216 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
3645 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3646 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3647 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
3648 0 : int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
3649 0 : int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
3650 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
3651 0 : auto &surface = state.dataSurface->Surface(surfNum);
3652 0 : if (surface.ConstituentSurfaceNums.size() > 1) {
3653 0 : Real64 QoutAtot = 0.0;
3654 0 : Real64 QinAtot = 0.0;
3655 0 : Real64 Atot = 0.0;
3656 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3657 0 : QoutAtot += state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
3658 0 : QinAtot += state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
3659 0 : Atot += state.dataSurface->Surface(constSurfNum).Area;
3660 0 : }
3661 :
3662 0 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = QoutAtot / Atot;
3663 0 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = QinAtot / Atot;
3664 : }
3665 : }
3666 0 : firstSurf = thisSpace.WindowSurfaceFirst;
3667 0 : lastSurf = thisSpace.WindowSurfaceLast;
3668 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
3669 0 : auto const &surface = state.dataSurface->Surface(surfNum);
3670 0 : if (surface.ExtSolar && surface.ConstituentSurfaceNums.size() > 1) {
3671 : // Absorbed in glazing
3672 : int totalGlassLayers =
3673 0 : state.dataConstruction->Construct(state.dataSurface->SurfActiveConstruction(surfNum)).TotGlassLayers;
3674 0 : for (int layer = 1; layer <= totalGlassLayers; ++layer) {
3675 0 : Real64 QAtot = 0.0;
3676 0 : Real64 Atot = 0.0;
3677 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3678 0 : QAtot +=
3679 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(constSurfNum, layer) * state.dataSurface->Surface(constSurfNum).Area;
3680 0 : Atot += state.dataSurface->Surface(constSurfNum).Area;
3681 0 : }
3682 :
3683 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, layer) = QAtot / Atot;
3684 : }
3685 :
3686 : // Absorbed by frame and dividers
3687 0 : if (surface.FrameDivider > 0) {
3688 0 : if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
3689 0 : Real64 QoutAtot = 0.0;
3690 0 : Real64 QinAtot = 0.0;
3691 0 : Real64 Atot = 0.0;
3692 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3693 0 : QoutAtot += state.dataSurface->SurfWinFrameQRadOutAbs(constSurfNum) *
3694 0 : state.dataSurface->SurfWinFrameArea(constSurfNum);
3695 0 : QinAtot += state.dataSurface->SurfWinFrameQRadInAbs(constSurfNum) *
3696 0 : state.dataSurface->SurfWinFrameArea(constSurfNum);
3697 0 : Atot += state.dataSurface->SurfWinFrameArea(constSurfNum);
3698 0 : }
3699 :
3700 0 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = QoutAtot / Atot;
3701 0 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = QinAtot / Atot;
3702 : }
3703 0 : if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
3704 0 : Real64 QoutAtot = 0.0;
3705 0 : Real64 QinAtot = 0.0;
3706 0 : Real64 Atot = 0.0;
3707 0 : for (int constSurfNum : surface.ConstituentSurfaceNums) {
3708 0 : QoutAtot += state.dataSurface->SurfWinDividerQRadOutAbs(constSurfNum) *
3709 0 : state.dataSurface->SurfWinDividerArea(constSurfNum);
3710 0 : QinAtot += state.dataSurface->SurfWinDividerQRadInAbs(constSurfNum) *
3711 0 : state.dataSurface->SurfWinDividerArea(constSurfNum);
3712 0 : Atot += state.dataSurface->SurfWinDividerArea(constSurfNum);
3713 0 : }
3714 :
3715 0 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = QoutAtot / Atot;
3716 0 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = QinAtot / Atot;
3717 : }
3718 : }
3719 : }
3720 : }
3721 0 : }
3722 : }
3723 : }
3724 71216 : } // End of sun-up check
3725 249960 : }
3726 :
3727 249958 : void InitIntSolarDistribution(EnergyPlusData &state)
3728 : {
3729 :
3730 : // SUBROUTINE INFORMATION:
3731 : // AUTHOR Anonymous
3732 : // DATE WRITTEN July 1977
3733 : // MODIFIED Oct 1999 (FW) to handle movable shades
3734 : // May 2000 (FW) to handle window frame and dividers
3735 : // May 2001 (FW) to handle window blinds
3736 : // Jan 2002 (FW) mods for between-glass shade/blind
3737 : // May 2006 (RR) to handle exterior window screens
3738 : // RE-ENGINEERED Mar98 (RKS)
3739 :
3740 : // PURPOSE OF THIS SUBROUTINE:
3741 : // This subroutine initializes the arrays associated with solar heat
3742 : // gains for both individual surfaces and for zones.
3743 :
3744 : // METHODOLOGY EMPLOYED:
3745 : // If the sun is down, all of the pertinent arrays are zeroed. If the
3746 : // sun is up, various calculations are made.
3747 :
3748 : // REFERENCES:
3749 : // (I)BLAST legacy routine QSUN
3750 :
3751 : using Dayltg::DistributeTDDAbsorbedSolar;
3752 : using namespace DataWindowEquivalentLayer;
3753 :
3754 249958 : auto &s_mat = state.dataMaterial;
3755 : // COMPUTE TOTAL SHORT-WAVE RADIATION ORIGINATING IN ZONE.
3756 : // Note: If sun is not up, QS is only internal gains
3757 602834 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3758 352876 : Real64 sumSpaceQLTSW = 0.0;
3759 723131 : for (int spaceNum : state.dataViewFactor->EnclSolInfo(enclosureNum).spaceNums) {
3760 370255 : sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
3761 352876 : }
3762 352876 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) = state.dataHeatBal->EnclSolQD(enclosureNum) + sumSpaceQLTSW;
3763 352876 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) = sumSpaceQLTSW;
3764 : }
3765 :
3766 249958 : if (state.dataHeatBalSurf->InterZoneWindow) { // DO INTERZONE DISTRIBUTION.
3767 :
3768 2 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3769 :
3770 1 : if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclosureNum)) {
3771 :
3772 0 : for (int OtherenclosureNum = 1; OtherenclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++OtherenclosureNum) {
3773 :
3774 0 : if ((OtherenclosureNum != enclosureNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(OtherenclosureNum))) {
3775 0 : Real64 sumSpaceQLTSW = 0.0;
3776 0 : for (int spaceNum : state.dataViewFactor->EnclSolInfo(OtherenclosureNum).spaceNums) {
3777 0 : sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
3778 0 : }
3779 0 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) +=
3780 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
3781 0 : (state.dataHeatBal->EnclSolQD(OtherenclosureNum) + sumSpaceQLTSW);
3782 0 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) +=
3783 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) * sumSpaceQLTSW;
3784 0 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) +=
3785 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
3786 0 : state.dataHeatBal->EnclSolQD(OtherenclosureNum);
3787 0 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclosureNum) =
3788 0 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec;
3789 : }
3790 : }
3791 : }
3792 : }
3793 : }
3794 :
3795 : // Beam and diffuse solar on inside surfaces from interior windows (for reporting)
3796 :
3797 249958 : if (state.dataEnvrn->SunIsUp) {
3798 1133860 : for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
3799 1012414 : auto const &surface = state.dataSurface->Surface(SurfNum);
3800 : //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
3801 1012414 : if (surface.Class == DataSurfaces::SurfaceClass::Shading) {
3802 0 : continue;
3803 : }
3804 1012414 : int const enclosureNum = surface.SolarEnclIndex;
3805 1012414 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) =
3806 1012414 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) / state.dataViewFactor->EnclSolInfo(enclosureNum).TotalSurfArea;
3807 1012414 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) =
3808 1012414 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) * (surface.Area + state.dataSurface->SurfWinDividerArea(SurfNum));
3809 1012414 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) =
3810 1012414 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3811 121446 : }
3812 : }
3813 :
3814 : // COMPUTE CONVECTIVE GAINS AND ZONE FLUX DENSITY.
3815 602834 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3816 352876 : auto const &thisSolEnclosure = state.dataViewFactor->EnclSolInfo(enclosureNum);
3817 352876 : if (state.dataHeatBalSurf->InterZoneWindow) {
3818 1 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) *=
3819 1 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
3820 : // CR 8695, VMULT not based on visible
3821 1 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *=
3822 1 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
3823 : } else {
3824 352875 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) *= thisSolEnclosure.solVMULT;
3825 352875 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *= thisSolEnclosure.solVMULT;
3826 : }
3827 : }
3828 :
3829 : // COMPUTE RADIANT GAINS ON SURFACES
3830 586610 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3831 706907 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3832 370255 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
3833 370255 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
3834 370255 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
3835 2350619 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
3836 1980364 : auto const &surface = state.dataSurface->Surface(SurfNum);
3837 1980364 : int const solEnclosureNum = surface.SolarEnclIndex;
3838 1980364 : int const ConstrNum = surface.Construction;
3839 1980364 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3840 :
3841 1980364 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum);
3842 : // TODO - AbsIntSurfVis = InsideAbsorpSolar instead of InsideAbsorpVis?
3843 1980364 : Real64 AbsIntSurfVis = thisConstruct.InsideAbsorpSolar; // Inside opaque surface visible absorptance to fix CR 8695 change to
3844 :
3845 1980364 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsIntSurf;
3846 1980364 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) += state.dataHeatBal->EnclSolQSWRadLights(solEnclosureNum) * AbsIntSurfVis;
3847 :
3848 : // Calculate absorbed solar on outside if movable exterior insulation in place
3849 1980364 : if (state.dataSurface->AnyMovableInsulation) {
3850 0 : auto &movInsul = state.dataSurface->extMovInsuls(SurfNum);
3851 0 : if (movInsul.present) {
3852 0 : Real64 AbsExt = state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum);
3853 0 : auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
3854 0 : state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) =
3855 0 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) * AbsExt / thisMaterial->AbsorpSolar;
3856 : // For transparent insulation, allow some sunlight to get through the movable insulation.
3857 : // The equation below is derived by taking what is transmitted through the layer and applying
3858 : // the fraction that is absorbed plus the back reflected portion (first order reflection only)
3859 : // to the plane between the transparent insulation and the exterior surface face.
3860 0 : auto const *matMovInsul = s_mat->materials(movInsul.matNum);
3861 0 : auto const *matFenMovInsul = dynamic_cast<Material::MaterialFen const *>(matMovInsul);
3862 0 : Real64 transMovInsul = (matFenMovInsul != nullptr) ? matFenMovInsul->Trans : 0.0;
3863 :
3864 0 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
3865 0 : transMovInsul * state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) *
3866 0 : ((thisMaterial->AbsorpSolar / AbsExt) + (1 - thisMaterial->AbsorpSolar));
3867 : }
3868 : }
3869 : // RJH 08/30/07 - Add SurfWinInitialDifSolInAbs, SurfWinInitialDifSolwinAbs, and SurfWinInitialDifSolAbsByShade
3870 : // calced in CalcWinTransDifSolInitialDistribution to SurfOpaqQRadSWInAbs, SurfWinQRadSWwinAbs, and SurfWinIntSWAbsByShade here
3871 1980364 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum);
3872 : } // end of opaque
3873 :
3874 370255 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
3875 370255 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
3876 458819 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { // Window
3877 88564 : auto const &surface = state.dataSurface->Surface(SurfNum);
3878 88564 : auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
3879 88564 : int const radEnclosureNum = surface.RadEnclIndex;
3880 88564 : int const solEnclosureNum = surface.SolarEnclIndex;
3881 88564 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3882 88564 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
3883 :
3884 88564 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) {
3885 86195 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
3886 :
3887 86195 : int TotGlassLayers = thisConstruct.TotGlassLayers;
3888 86195 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
3889 :
3890 : // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
3891 86195 : Real64 pulseMultipler = 0.01; // use to create a pulse for the load component report computations, the W/sqft pulse for the zone
3892 86195 : if (!state.dataGlobal->doLoadComponentPulseNow) {
3893 86189 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
3894 86189 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3895 86189 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
3896 : } else {
3897 : // radiant value prior to adjustment for pulse for load component report
3898 6 : Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
3899 : // for the loads component report during the special sizing run increase the radiant portion
3900 : // a small amount to create a "pulse" of heat that is used for the
3901 : // radiant value including adjustment for pulse for load component report
3902 6 : Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
3903 : // ITABSF is the Inside Thermal Absorptance
3904 : // EnclRadThermAbsMult is a multiplier for each zone/enclosure
3905 : // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
3906 6 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
3907 6 : adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
3908 6 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
3909 : }
3910 :
3911 86195 : if (NOT_SHADED(ShadeFlag)) { // No window shading
3912 196685 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
3913 110490 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3914 110490 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
3915 : }
3916 0 : } else if (ConstrNumSh != 0 && ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
3917 : // Interior, exterior or between-glass shade, screen or blind in place
3918 0 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
3919 0 : for (int IGlass = 1; IGlass <= constrSh.TotGlassLayers; ++IGlass) {
3920 0 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
3921 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3922 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBack(IGlass);
3923 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind || ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) {
3924 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3925 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3926 0 : auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxLo];
3927 0 : auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxHi];
3928 : // Glass layer back diffuse solar absorptance when blind in place
3929 0 : Real64 BlAbsDiffBk = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
3930 :
3931 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3932 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * BlAbsDiffBk;
3933 : }
3934 : }
3935 0 : if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
3936 0 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3937 0 : constrSh.ShadeAbsorpThermal *
3938 0 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
3939 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
3940 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3941 0 : Real64 EffBlEmiss = surfShade.effShadeEmi; // Blind emissivity (thermal absorptance) as part of glazing system
3942 0 : state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3943 0 : EffBlEmiss *
3944 0 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
3945 : }
3946 :
3947 0 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
3948 0 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) =
3949 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBackShade;
3950 0 : } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
3951 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
3952 0 : auto const &btarLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
3953 0 : auto const &btarHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
3954 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
3955 0 : Real64 AbsDiffBkBl = Interp(btarLo.Sol.Bk.Df.Abs, btarHi.Sol.Bk.Df.Abs, interpFac);
3956 :
3957 0 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsDiffBkBl;
3958 : }
3959 : // Correct for divider shadowing
3960 0 : if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3961 0 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) *= surfWin.glazedFrac;
3962 : }
3963 :
3964 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
3965 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh); // What was here before?
3966 0 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
3967 :
3968 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
3969 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
3970 0 : Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
3971 0 : thisConstruct.AbsDiffBack(IGlass),
3972 0 : constructionSh.AbsDiffBack(IGlass));
3973 : }
3974 :
3975 : } // End of shading flag check
3976 :
3977 : // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
3978 86195 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
3979 3 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) +=
3980 3 : (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) +
3981 3 : (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
3982 3 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
3983 3 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
3984 3 : state.dataSurface->SurfWinFrameEmis(SurfNum)) *
3985 3 : (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)); // Window has a frame
3986 : }
3987 86195 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) { // Window has dividers
3988 3 : Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
3989 3 : Real64 DividerSolAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
3990 3 : if (state.dataSurface->SurfWinDividerType(SurfNum) ==
3991 : DataSurfaces::FrameDividerType::Suspended) { // Suspended divider; account for inside glass
3992 0 : Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass layer material number
3993 0 : auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
3994 0 : assert(thisMaterial != nullptr);
3995 0 : Real64 TransGl = thisMaterial->Trans; // Glass layer solar transmittance, reflectance, absorptance
3996 0 : Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
3997 0 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
3998 0 : Real64 DividerSolRefl = 1.0 - DividerSolAbs; // Window divider solar reflectance
3999 0 : DividerSolAbs = AbsGl + TransGl * (DividerSolAbs + DividerSolRefl * AbsGl) / (1.0 - DividerSolRefl * ReflGl);
4000 0 : DividerThermAbs = thisMaterial->AbsorpThermalBack;
4001 : }
4002 : // Correct for interior shade transmittance
4003 3 : if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
4004 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4005 0 : int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers); // Shade layer material number
4006 0 : auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
4007 0 : assert(matSh != nullptr);
4008 0 : DividerSolAbs *= matSh->Trans;
4009 0 : DividerThermAbs *= matSh->TransThermal;
4010 :
4011 3 : } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
4012 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4013 0 : Real64 SolBackDiffDiffTrans = surfShade.blind.TAR.Sol.Bk.Df.Tra;
4014 0 : Real64 IRBackTrans = surfShade.blind.TAR.IR.Bk.Tra;
4015 :
4016 0 : DividerSolAbs *= SolBackDiffDiffTrans;
4017 0 : DividerThermAbs *= IRBackTrans;
4018 : }
4019 : // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
4020 3 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) +=
4021 3 : (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * DividerSolAbs +
4022 3 : (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
4023 3 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
4024 3 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
4025 3 : DividerThermAbs) *
4026 3 : (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
4027 : }
4028 : } else {
4029 : // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
4030 2369 : Real64 pulseMultipler = 0.01; // the W/sqft pulse for the zone
4031 2369 : if (!state.dataGlobal->doLoadComponentPulseNow) {
4032 2369 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
4033 2369 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
4034 2369 : state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
4035 : } else {
4036 : // radiant value prior to adjustment for pulse for load component report
4037 0 : Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
4038 : // for the loads component report during the special sizing run increase the radiant portion
4039 : // a small amount to create a "pulse" of heat that is used for the
4040 : // radiant value including adjustment for pulse for load component report
4041 0 : Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
4042 : // ITABSF is the Inside Thermal Absorptance
4043 : // EnclRadThermAbsMult is a multiplier for each zone/radiant enclosure
4044 : // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
4045 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
4046 0 : adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
4047 0 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
4048 : }
4049 : // Radiations absorbed by the window layers coming from zone side
4050 2369 : int EQLNum = thisConstruct.EQLConsPtr;
4051 8580 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4052 6211 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) +=
4053 6211 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffBackEQL(Lay);
4054 : }
4055 : // Window frame has not been included for equivalent layer model yet
4056 :
4057 : } // end if for IF ( SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: EQL) THEN
4058 :
4059 88564 : if (surface.ExtBoundCond > 0) { // Interzone surface
4060 : // Short-wave radiation absorbed in panes of corresponding window in adjacent zone
4061 0 : int SurfNumAdjZone = surface.ExtBoundCond; // Surface number in adjacent zone for interzone surfaces
4062 0 : if (state.dataSurface->SurfWinWindowModelType(SurfNumAdjZone) != DataSurfaces::WindowModel::EQL) {
4063 0 : int TotGlassLayers = thisConstruct.TotGlassLayers;
4064 0 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4065 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, IGlass) +=
4066 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
4067 0 : state.dataConstruction->Construct(state.dataSurface->Surface(SurfNumAdjZone).Construction).AbsDiff(IGlass);
4068 : // Note that AbsDiff rather than AbsDiffBack is used in the above since the
4069 : // radiation from the current zone is incident on the outside of the adjacent
4070 : // zone's window.
4071 : }
4072 : } else { // IF (SurfaceWindow(SurfNumAdjZone)%WindowModelType == WindowModel:: EQL) THEN
4073 0 : int const AdjConstrNum = state.dataSurface->Surface(SurfNumAdjZone).Construction;
4074 0 : int const EQLNum = state.dataConstruction->Construct(AdjConstrNum).EQLConsPtr;
4075 0 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4076 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, Lay) +=
4077 0 : state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffFrontEQL(Lay);
4078 : // Note that AbsDiffFrontEQL rather than AbsDiffBackEQL is used in the above
4079 : // since the radiation from the current zone is incident on the outside of the
4080 : // adjacent zone's window.
4081 : }
4082 : }
4083 : }
4084 :
4085 88564 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) {
4086 86195 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
4087 86195 : int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
4088 86195 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4089 86195 : if (DataSurfaces::NOT_SHADED(ShadeFlag)) { // No window shading
4090 196685 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4091 110490 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4092 : }
4093 0 : } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
4094 0 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4095 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4096 : }
4097 : } else {
4098 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4099 : // Interior, exterior or between-glass shade, screen or blind in place
4100 0 : for (int IGlass = 1; IGlass <= constructionSh.TotGlassLayers; ++IGlass) {
4101 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4102 : }
4103 0 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag) || DataSurfaces::ANY_BLIND(ShadeFlag)) {
4104 0 : state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum);
4105 : }
4106 : } // End of shading flag check
4107 2369 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
4108 0 : int TotGlassLayers = thisConstruct.TotGlassLayers;
4109 0 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
4110 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
4111 : }
4112 2369 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
4113 :
4114 : // ConstrNum = Surface(SurfNum)%Construction
4115 2369 : int EQLNum = thisConstruct.EQLConsPtr;
4116 :
4117 8580 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
4118 6211 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay);
4119 : }
4120 : }
4121 :
4122 : } // End of window
4123 336652 : }
4124 : }
4125 249958 : Dayltg::DistributeTDDAbsorbedSolar(state);
4126 249958 : }
4127 :
4128 249957 : void ComputeIntThermalAbsorpFactors(EnergyPlusData &state)
4129 : {
4130 :
4131 : // SUBROUTINE INFORMATION:
4132 : // AUTHOR Legacy Code (George Walton)
4133 : // DATE WRITTEN Legacy: Dec 1976
4134 : // MODIFIED Nov. 99, FCW: to take into account movable interior shades and switchable glazing
4135 : // June 01, FCW: to take into account interior blinds.
4136 :
4137 : // PURPOSE OF THIS SUBROUTINE:
4138 : // This routine computes the fractions of long-wave radiation from lights, equipment and people
4139 : // that is absorbed by each zone surface.
4140 :
4141 : // METHODOLOGY EMPLOYED:
4142 : // The fraction is assumed to be proportional to the product of the surface area times its thermal absorptivity.
4143 :
4144 : // REFERENCES:
4145 : // BLAST Routine: CITAF - Compute Interior Thermal Absorption Factors
4146 249957 : auto &s_mat = state.dataMaterial;
4147 :
4148 602832 : for (auto const &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
4149 352875 : if (!thisEnclosure.radReCalc) {
4150 342688 : continue;
4151 : }
4152 20424 : for (int spaceNum : thisEnclosure.spaceNums) {
4153 10237 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4154 10237 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
4155 10237 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
4156 14173 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
4157 3936 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4158 3936 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4159 1 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4160 1 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
4161 : } else {
4162 3935 : int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
4163 3935 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal;
4164 : }
4165 : }
4166 10187 : }
4167 249957 : }
4168 249957 : if (state.dataSurface->AnyMovableSlat) {
4169 0 : for (int SurfNum : state.dataHeatBalSurf->SurfMovSlatsIndexList) {
4170 : // For window with an interior shade or blind, emissivity is a combination of glass and shade/blind emissivity
4171 0 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4172 : // Not sure we need to do this anymore
4173 0 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4174 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4175 0 : state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
4176 : }
4177 0 : }
4178 : }
4179 :
4180 602832 : for (auto &thisRadEnclosure : state.dataViewFactor->EnclRadInfo) {
4181 352875 : if (!thisRadEnclosure.radReCalc) {
4182 342688 : continue;
4183 : }
4184 10187 : Real64 SUM1 = 0.0;
4185 69403 : for (int const SurfNum : thisRadEnclosure.SurfacePtr) {
4186 59216 : auto &surf = state.dataSurface->Surface(SurfNum);
4187 59216 : int const ConstrNum = surf.Construction;
4188 59216 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
4189 59216 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4190 59216 : if (ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
4191 59216 : SUM1 += surf.Area * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
4192 : } else { // Switchable glazing
4193 0 : SUM1 += surf.Area * Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
4194 0 : thisConstruct.InsideAbsorpThermal,
4195 0 : state.dataConstruction->Construct(surf.activeShadedConstruction).InsideAbsorpThermal);
4196 : }
4197 :
4198 : // Window frame and divider effects
4199 59216 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
4200 1 : SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) *
4201 1 : state.dataSurface->SurfWinFrameEmis(SurfNum);
4202 : }
4203 59216 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
4204 1 : Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
4205 : // Suspended (between-glass) divider; relevant emissivity is inner glass emissivity
4206 1 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
4207 0 : DividerThermAbs = thisConstruct.InsideAbsorpThermal;
4208 : }
4209 1 : if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4210 : // Interior shade or blind in place
4211 0 : int const ConstrNumSh = surf.activeShadedConstruction;
4212 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4213 :
4214 0 : if (state.dataSurface->SurfWinHasShadeOrBlindLayer(SurfNum)) {
4215 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4216 : // Shade layer material number
4217 0 : int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers);
4218 0 : auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
4219 0 : assert(matSh != nullptr);
4220 : // Shade or blind IR transmittance
4221 0 : Real64 TauShIR = matSh->TransThermal;
4222 : // Effective emissivity of shade or blind
4223 0 : Real64 EffShDevEmiss = surfShade.effShadeEmi;
4224 :
4225 0 : if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
4226 0 : TauShIR = surfShade.blind.TAR.IR.Bk.Tra;
4227 : }
4228 0 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (EffShDevEmiss + DividerThermAbs * TauShIR);
4229 : } else {
4230 : // this is for EMS activated shade/blind but the window construction has no shade/blind layer
4231 0 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
4232 : DividerThermAbs;
4233 : }
4234 : } else {
4235 1 : SUM1 +=
4236 1 : state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * DividerThermAbs;
4237 : }
4238 : }
4239 :
4240 : } // End of loop over surfaces in zone/enclosure
4241 10187 : thisRadEnclosure.radThermAbsMult = 1.0 / SUM1;
4242 :
4243 249957 : } // End of loop over enclosures
4244 249957 : }
4245 :
4246 249956 : void ComputeIntSWAbsorpFactors(EnergyPlusData &state)
4247 : {
4248 :
4249 : // SUBROUTINE INFORMATION:
4250 : // AUTHOR Legacy (George Walton)
4251 : // DATE WRITTEN Legacy (December 1980)
4252 : // MODIFIED Nov. 99, FW; now called every time step to account for movable
4253 : // window shades and insulation
4254 : // Mar. 00, FW; change name from ComputeVisLightingAbsorpFactors
4255 : // to ComputeIntSWAbsorpFactors
4256 : // May 00, FW; add window frame and divider effects
4257 : // June 01, FW: account for window blinds
4258 : // Nov 01, FW: account for absorptance of exterior shades and interior or exterior blinds
4259 : // Jan 03, FW: add between-glass shade/blind
4260 : // May 06, RR: account for exterior window screens
4261 :
4262 : // PURPOSE OF THIS SUBROUTINE:
4263 : // Computes VMULT, the inverse of the sum of area*(short-wave absorptance+transmittance) for
4264 : // the surfaces in a zone. VMULT is used to calculate the zone interior diffuse short-wave radiation
4265 : // absorbed by the inside of opaque zone surfaces or by the glass and shade/blind layers of zone windows.
4266 :
4267 : // Sets VCONV to zero (VCONV was formerly used to calculate convective gain due to short-wave
4268 : // radiation absorbed by interior window shades).
4269 :
4270 : // REFERENCES:
4271 : // BLAST Routine - CIVAF - Compute Surface Absorption Factors For Short Wave Radiation
4272 : // From Zone Lights And Diffuse Solar.
4273 :
4274 : // Avoid a division by zero of the user has entered a bunch of surfaces with zero absorptivity on the inside
4275 249956 : Real64 constexpr SmallestAreaAbsProductAllowed(0.01);
4276 :
4277 249956 : auto &s_mat = state.dataMaterial;
4278 :
4279 602830 : for (auto &thisSolEnclosure : state.dataViewFactor->EnclSolInfo) {
4280 352874 : if (!thisSolEnclosure.radReCalc) {
4281 342688 : continue;
4282 : }
4283 10186 : Real64 SUM1 = 0.0; // Intermediate calculation value for solar absorbed and transmitted
4284 :
4285 69401 : for (int const SurfNum : thisSolEnclosure.SurfacePtr) {
4286 59215 : auto &thisSurf = state.dataSurface->Surface(SurfNum);
4287 59215 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
4288 59215 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
4289 59215 : if (thisConstruct.TransDiff <= 0.0) {
4290 : // Opaque surface
4291 55342 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum); // Inside surface short-wave absorptance
4292 55342 : SUM1 += thisSurf.Area * AbsIntSurf;
4293 :
4294 : } else {
4295 : // Window
4296 3873 : if (!state.dataConstruction->Construct(thisSurf.Construction).WindowTypeEQL) {
4297 1566 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4298 :
4299 1566 : Real64 AbsDiffTotWin = 0.0; // Sum of window layer short-wave absorptances
4300 1566 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
4301 1566 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
4302 :
4303 : // Sum of absorptances of glass layers
4304 3201 : for (int Lay = 1; Lay <= thisConstruct.TotGlassLayers; ++Lay) {
4305 1635 : Real64 AbsDiffLayWin = thisConstruct.AbsDiffBack(Lay); // Window layer short-wave absorptance
4306 :
4307 : // Window with shade, screen or blind
4308 1635 : if (ConstrNumSh != 0) {
4309 64 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4310 64 : if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
4311 0 : AbsDiffLayWin = constrSh.AbsDiffBack(Lay);
4312 64 : } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
4313 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4314 0 : auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxLo];
4315 0 : auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxHi];
4316 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
4317 0 : AbsDiffLayWin = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
4318 : }
4319 : }
4320 :
4321 : // Switchable glazing
4322 1635 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
4323 0 : assert(ConstrNumSh > 0); // Should this be included in the if above
4324 0 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4325 0 : AbsDiffLayWin = Window::InterpSw(SwitchFac, AbsDiffLayWin, constrSh.AbsDiffBack(Lay));
4326 : }
4327 1635 : AbsDiffTotWin += AbsDiffLayWin;
4328 : }
4329 :
4330 1566 : Real64 TransDiffWin = thisConstruct.TransDiff; // Window diffuse short-wave transmittance
4331 1566 : Real64 DiffAbsShade = 0.0; // Diffuse short-wave shade or blind absorptance
4332 :
4333 : // Window with shade, screen or blind
4334 :
4335 1566 : if (ConstrNumSh != 0) {
4336 64 : auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
4337 64 : if (ANY_SHADE_SCREEN(ShadeFlag)) {
4338 0 : TransDiffWin = constrSh.TransDiff;
4339 0 : DiffAbsShade = constrSh.AbsDiffBackShade;
4340 64 : } else if (ANY_BLIND(ShadeFlag)) {
4341 0 : auto const &surfShade = state.dataSurface->surfShades(SurfNum);
4342 0 : auto const &btarSlatLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
4343 0 : auto const &btarSlatHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
4344 0 : Real64 interpFac = surfShade.blind.slatAngInterpFac;
4345 0 : TransDiffWin = Interp(btarSlatLo.Sol.Ft.Df.Tra, btarSlatHi.Sol.Ft.Df.Tra, interpFac);
4346 0 : DiffAbsShade = Interp(btarSlatLo.Sol.Bk.Df.Abs, btarSlatHi.Sol.Bk.Df.Abs, interpFac);
4347 : }
4348 : }
4349 :
4350 : // Switchable glazing
4351 :
4352 1566 : if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
4353 0 : assert(ConstrNumSh > 0);
4354 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
4355 0 : TransDiffWin = Window::InterpSw(SwitchFac, TransDiffWin, constructionSh.TransDiff);
4356 : }
4357 :
4358 1566 : SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin + DiffAbsShade);
4359 :
4360 : // Window frame and divider effects (shade area is glazed area plus divider area)
4361 :
4362 1566 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
4363 1 : SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) *
4364 1 : (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum));
4365 : }
4366 1566 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
4367 1 : Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
4368 1 : if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
4369 : // Suspended (between-glass) divider: account for glass on inside of divider
4370 0 : Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass material number
4371 0 : auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
4372 0 : assert(thisMaterial != nullptr);
4373 0 : Real64 TransGl = thisMaterial->Trans; // Glass layer short-wave transmittance, reflectance, absorptance
4374 0 : Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
4375 0 : Real64 AbsGl = 1.0 - TransGl - ReflGl;
4376 0 : Real64 DividerRefl = 1.0 - DividerAbs; // Window divider short-wave reflectance
4377 0 : DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
4378 : }
4379 1 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4380 0 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (DividerAbs + DiffAbsShade);
4381 : } else {
4382 1 : SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
4383 : DividerAbs;
4384 : }
4385 : }
4386 : } else { // equivalent layer window
4387 : // In equivalent layer window solid layers (Glazing and shades) are treated equally
4388 : // frames and dividers are not supported
4389 2307 : Real64 AbsDiffTotWin = 0.0;
4390 2307 : Real64 AbsDiffLayWin = 0.0;
4391 2307 : Real64 TransDiffWin = thisConstruct.TransDiff;
4392 8358 : for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL; ++Lay) {
4393 6051 : AbsDiffLayWin = thisConstruct.AbsDiffBackEQL(Lay);
4394 6051 : AbsDiffTotWin += AbsDiffLayWin;
4395 : }
4396 2307 : SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin);
4397 : }
4398 : } // End of check if opaque surface or window
4399 : } // End of loop over surfaces in zone
4400 :
4401 10186 : if (SUM1 > SmallestAreaAbsProductAllowed) { // Everything is okay, proceed with the regular calculation
4402 10186 : thisSolEnclosure.solVMULT = 1.0 / SUM1;
4403 :
4404 : } else { // the sum of area*solar absorptance for all surfaces in the zone is zero--either the user screwed up
4405 : // or they really want to disallow any solar from being absorbed on the inside surfaces. Fire off a
4406 : // nasty warning message and then assume that no solar is ever absorbed (basically everything goes
4407 : // back out whatever window is there. Note that this also assumes that the shade has no effect.
4408 : // That's probably not correct, but how correct is it to assume that no solar is absorbed anywhere
4409 : // in the zone?
4410 0 : if (thisSolEnclosure.solAbsFirstCalc) {
4411 0 : ShowWarningError(
4412 : state,
4413 0 : format("ComputeIntSWAbsorbFactors: Sum of area times inside solar absorption for all surfaces is zero in Enclosure: {}",
4414 0 : thisSolEnclosure.Name));
4415 0 : thisSolEnclosure.solAbsFirstCalc = false;
4416 : }
4417 0 : thisSolEnclosure.solVMULT = 0.0;
4418 : }
4419 249956 : } // End of enclosure loop
4420 249956 : }
4421 :
4422 4 : void ComputeDifSolExcZonesWIZWindows(EnergyPlusData &state)
4423 : {
4424 :
4425 : // SUBROUTINE INFORMATION:
4426 : // MODIFIED Jun 2007 - Lawrie - Speed enhancements.
4427 : // RE-ENGINEERED Winkelmann, Lawrie
4428 :
4429 : // PURPOSE OF THIS SUBROUTINE:
4430 : // This subroutine computes the diffuse solar exchange factors between enclosures with
4431 : // interzone windows.
4432 :
4433 4 : int const numEnclosures = state.dataViewFactor->NumOfSolarEnclosures;
4434 4 : if (!allocated(state.dataHeatBalSurf->ZoneFractDifShortZtoZ)) {
4435 2 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ.allocate(numEnclosures, numEnclosures);
4436 2 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ.allocate(numEnclosures);
4437 2 : state.dataHeatBalSurfMgr->DiffuseArray.allocate(numEnclosures, numEnclosures);
4438 : }
4439 :
4440 4 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ = false;
4441 4 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ.to_identity();
4442 4 : state.dataHeatBalSurfMgr->DiffuseArray.to_identity();
4443 :
4444 : // IF (.not. ANY(Zone%HasInterZoneWindow)) RETURN ! this caused massive diffs
4445 4 : if (state.dataGlobal->KickOffSimulation || state.dataGlobal->KickOffSizing) {
4446 2 : return;
4447 : }
4448 : // Compute fraction transmitted in one pass.
4449 :
4450 6 : for (int const SurfNum : state.dataSurface->AllHTWindowSurfaceList) {
4451 4 : auto &surface = state.dataSurface->Surface(SurfNum);
4452 4 : if (surface.ExtBoundCond <= 0) {
4453 0 : continue;
4454 : }
4455 4 : if (surface.ExtBoundCond == SurfNum) {
4456 0 : continue;
4457 : }
4458 4 : if (state.dataConstruction->Construct(surface.Construction).TransDiff <= 0.0) {
4459 0 : continue;
4460 : }
4461 :
4462 4 : int surfEnclNum = surface.SolarEnclIndex;
4463 4 : if (!state.dataViewFactor->EnclSolInfo(surfEnclNum).HasInterZoneWindow) {
4464 2 : continue;
4465 : }
4466 2 : int MZ = state.dataSurface->Surface(surface.ExtBoundCond).SolarEnclIndex;
4467 4 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(surfEnclNum, MZ) += state.dataConstruction->Construct(surface.Construction).TransDiff *
4468 2 : state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT * surface.Area;
4469 2 : if (state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT != 0.0) {
4470 2 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ(surfEnclNum) = true;
4471 : }
4472 2 : }
4473 : // Compute fractions for multiple passes.
4474 :
4475 2 : Array2D<Real64>::size_type l(0u), m(0u), d(0u);
4476 8 : for (int NZ = 1; NZ <= numEnclosures; ++NZ, d += numEnclosures + 1) {
4477 6 : m = NZ - 1;
4478 6 : Real64 D_d(0.0); // Local accumulator
4479 24 : for (int MZ = 1; MZ <= numEnclosures; ++MZ, ++l, m += numEnclosures) {
4480 18 : if (MZ == NZ) {
4481 6 : continue;
4482 : }
4483 12 : state.dataHeatBalSurfMgr->DiffuseArray[l] =
4484 12 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] /
4485 24 : (1.0 - state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] *
4486 12 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m]); // [ l ] == ( MZ, NZ ), [ m ] == ( NZ, MZ )
4487 12 : D_d += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m] * state.dataHeatBalSurfMgr->DiffuseArray[l];
4488 : }
4489 6 : state.dataHeatBalSurfMgr->DiffuseArray[d] += D_d; // [ d ] == ( NZ, NZ )
4490 : }
4491 :
4492 2 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ = state.dataHeatBalSurfMgr->DiffuseArray;
4493 : // added for CR 7999 & 7869
4494 2 : assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize1() == numEnclosures);
4495 2 : assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize2() == numEnclosures);
4496 8 : for (int NZ = 1; NZ <= numEnclosures; ++NZ) {
4497 19 : for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
4498 15 : if (MZ == NZ) {
4499 5 : continue;
4500 : }
4501 10 : if (state.dataHeatBalSurf->ZoneFractDifShortZtoZ(MZ, NZ) > 0.0) {
4502 2 : state.dataHeatBalSurf->EnclSolRecDifShortFromZ(NZ) = true;
4503 2 : break;
4504 : }
4505 : }
4506 : }
4507 :
4508 : // Compute fractions for multiple zones.
4509 :
4510 8 : for (int IZ = 1; IZ <= numEnclosures; ++IZ) {
4511 6 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(IZ)) {
4512 4 : continue;
4513 : }
4514 :
4515 8 : for (int JZ = 1; JZ <= numEnclosures; ++JZ) {
4516 6 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(JZ)) {
4517 2 : continue;
4518 : }
4519 4 : if (IZ == JZ) {
4520 2 : continue;
4521 : }
4522 2 : if (state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ) == 0.0) {
4523 0 : continue;
4524 : }
4525 :
4526 8 : for (int KZ = 1; KZ <= numEnclosures; ++KZ) {
4527 6 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(KZ)) {
4528 2 : continue;
4529 : }
4530 4 : if (IZ == KZ) {
4531 2 : continue;
4532 : }
4533 2 : if (JZ == KZ) {
4534 2 : continue;
4535 : }
4536 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) == 0.0) {
4537 0 : continue;
4538 : }
4539 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, KZ) +=
4540 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4541 :
4542 0 : for (int LZ = 1; LZ <= numEnclosures; ++LZ) {
4543 0 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(LZ)) {
4544 0 : continue;
4545 : }
4546 0 : if (IZ == LZ) {
4547 0 : continue;
4548 : }
4549 0 : if (JZ == LZ) {
4550 0 : continue;
4551 : }
4552 0 : if (KZ == LZ) {
4553 0 : continue;
4554 : }
4555 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) == 0.0) {
4556 0 : continue;
4557 : }
4558 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, LZ) += state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
4559 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) *
4560 0 : state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4561 :
4562 0 : for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
4563 0 : if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(MZ)) {
4564 0 : continue;
4565 : }
4566 0 : if (IZ == MZ) {
4567 0 : continue;
4568 : }
4569 0 : if (JZ == MZ) {
4570 0 : continue;
4571 : }
4572 0 : if (KZ == MZ) {
4573 0 : continue;
4574 : }
4575 0 : if (LZ == MZ) {
4576 0 : continue;
4577 : }
4578 0 : if (state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) == 0.0) {
4579 0 : continue;
4580 : }
4581 0 : state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, MZ) +=
4582 0 : state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) * state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
4583 0 : state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
4584 : } // MZ Loop
4585 :
4586 : } // LZ Loop
4587 :
4588 : } // KZ Loop
4589 :
4590 : } // JZ Loop
4591 :
4592 : } // IZ Loop
4593 : } // ComputeDifSolExcZoneWIZWindows()
4594 :
4595 116073 : void InitEMSControlledSurfaceProperties(EnergyPlusData &state)
4596 : {
4597 :
4598 : // SUBROUTINE INFORMATION:
4599 : // AUTHOR B. Griffith
4600 : // DATE WRITTEN April 2011
4601 :
4602 : // PURPOSE OF THIS SUBROUTINE:
4603 : // initialize material and construction surface properties if being overridden by EMS
4604 :
4605 : // METHODOLOGY EMPLOYED:
4606 : // update solar, thermal and visible absorptance values when actuated by EMS
4607 :
4608 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4609 : int TotLayers; // count of material layers in a construction
4610 : int InsideMaterNum; // integer pointer for inside face's material layer
4611 : int OutsideMaterNum; // integer pointer for outside face's material layer
4612 :
4613 116073 : auto &s_mat = state.dataMaterial;
4614 :
4615 116073 : state.dataGlobal->AnySurfPropOverridesInModel = false;
4616 : // first determine if anything needs to be done, once yes, then always init
4617 736781 : for (auto const *mat : s_mat->materials) {
4618 620708 : if (mat->group != Material::Group::Regular) {
4619 7431 : continue;
4620 : }
4621 :
4622 613277 : if ((mat->AbsorpSolarEMSOverrideOn) || (mat->AbsorpThermalEMSOverrideOn) || (mat->AbsorpVisibleEMSOverrideOn)) {
4623 0 : state.dataGlobal->AnySurfPropOverridesInModel = true;
4624 0 : break;
4625 : }
4626 : }
4627 :
4628 116073 : if (!state.dataGlobal->AnySurfPropOverridesInModel) {
4629 116073 : return; // quick return if nothing has ever needed to be done
4630 : }
4631 :
4632 : // first, loop over materials
4633 : // why is this a second loop?
4634 0 : for (auto *mat : s_mat->materials) {
4635 0 : if (mat->group != Material::Group::Regular) {
4636 0 : continue;
4637 : }
4638 :
4639 0 : mat->AbsorpSolar = mat->AbsorpSolarEMSOverrideOn ? max(min(mat->AbsorpSolarEMSOverride, 0.9999), 0.0001) : mat->AbsorpSolarInput;
4640 0 : mat->AbsorpThermal = mat->AbsorpThermalEMSOverrideOn ? max(min(mat->AbsorpThermalEMSOverride, 0.9999), 0.0001) : mat->AbsorpThermalInput;
4641 0 : mat->AbsorpVisible = mat->AbsorpVisibleEMSOverrideOn ? max(min(mat->AbsorpVisibleEMSOverride, 0.9999), 0.0001) : mat->AbsorpVisibleInput;
4642 : } // loop over materials
4643 :
4644 : // second, loop over constructions
4645 0 : for (auto &thisConstruct : state.dataConstruction->Construct) {
4646 0 : if (thisConstruct.TypeIsWindow) {
4647 0 : continue; // only override opaque constructions
4648 : }
4649 0 : TotLayers = thisConstruct.TotLayers;
4650 0 : if (TotLayers == 0) {
4651 0 : continue; // error condition
4652 : }
4653 0 : InsideMaterNum = thisConstruct.LayerPoint(TotLayers);
4654 0 : if (InsideMaterNum != 0) {
4655 0 : auto const *mat = s_mat->materials(InsideMaterNum);
4656 0 : thisConstruct.InsideAbsorpVis = mat->AbsorpVisible;
4657 0 : thisConstruct.InsideAbsorpSolar = mat->AbsorpSolar;
4658 0 : thisConstruct.InsideAbsorpThermal = mat->AbsorpThermal;
4659 : }
4660 :
4661 0 : OutsideMaterNum = thisConstruct.LayerPoint(1);
4662 0 : if (OutsideMaterNum != 0) {
4663 0 : auto const *mat = s_mat->materials(OutsideMaterNum);
4664 0 : thisConstruct.OutsideAbsorpVis = mat->AbsorpVisible;
4665 0 : thisConstruct.OutsideAbsorpSolar = mat->AbsorpSolar;
4666 0 : thisConstruct.OutsideAbsorpThermal = mat->AbsorpThermal;
4667 : }
4668 : } // for (ConstrNum)
4669 : } // InitEMSControlledSurfaceProperties()
4670 :
4671 116073 : void InitEMSControlledConstructions(EnergyPlusData &state)
4672 : {
4673 :
4674 : // SUBROUTINE INFORMATION:
4675 : // AUTHOR B. Griffith
4676 : // DATE WRITTEN Jan 2012
4677 :
4678 : // PURPOSE OF THIS SUBROUTINE:
4679 : // change construction on surface if overridden by EMS
4680 :
4681 116073 : state.dataGlobal->AnyConstrOverridesInModel = false;
4682 854204 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4683 745241 : if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum)) {
4684 7110 : state.dataGlobal->AnyConstrOverridesInModel = true;
4685 7110 : break;
4686 : }
4687 : }
4688 116073 : if (!state.dataGlobal->AnyConstrOverridesInModel) {
4689 108963 : return;
4690 : }
4691 :
4692 45714 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4693 38604 : auto &surface = state.dataSurface->Surface(SurfNum);
4694 :
4695 38604 : if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum) && (state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum) > 0)) {
4696 :
4697 7110 : if (state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
4698 7110 : .TypeIsWindow) { // okay, always allow windows
4699 1352 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
4700 1352 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
4701 : }
4702 :
4703 14216 : if ((state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) &&
4704 7106 : (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum))) {
4705 :
4706 7106 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4707 7106 : state.dataConstruction->Construct(surface.Construction).IsUsed = true;
4708 7106 : state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4709 :
4710 : } else { // have not checked yet or is not okay, so see if we need to warn about incompatible
4711 4 : if (!state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) {
4712 : // check if constructions appear compatible
4713 :
4714 4 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
4715 0 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
4716 : // compare old construction to new construction and see if terms match
4717 : // set as okay and turn false if find a big problem
4718 4 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4719 : true;
4720 4 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4721 : true;
4722 4 : if (state.dataConstruction->Construct(surface.Construction).NumHistories !=
4723 4 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories) {
4724 : // throw warning, but allow
4725 0 : ShowWarningError(state,
4726 : "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
4727 : "CTF timescales are being used.");
4728 0 : ShowContinueError(state,
4729 0 : format("Construction named = {} has CTF timesteps = {}",
4730 0 : state.dataConstruction->Construct(surface.Construction).Name,
4731 0 : state.dataConstruction->Construct(surface.Construction).NumHistories));
4732 0 : ShowContinueError(
4733 : state,
4734 0 : format("While construction named = {} has CTF timesteps = {}",
4735 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4736 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories));
4737 0 : ShowContinueError(
4738 : state,
4739 0 : format("Transient heat transfer modeling may not be valid for surface name = {}, and the simulation continues",
4740 0 : surface.Name));
4741 : }
4742 4 : if (state.dataConstruction->Construct(surface.Construction).NumCTFTerms !=
4743 4 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms) {
4744 : // throw warning, but allow
4745 4 : ShowWarningError(state,
4746 : "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
4747 : "CTF terms are being used.");
4748 4 : ShowContinueError(state,
4749 4 : format("Construction named = {} has number of CTF terms = {}",
4750 2 : state.dataConstruction->Construct(surface.Construction).Name,
4751 2 : state.dataConstruction->Construct(surface.Construction).NumCTFTerms));
4752 4 : ShowContinueError(
4753 : state,
4754 4 : format("While construction named = {} has number of CTF terms = {}",
4755 2 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4756 2 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms));
4757 4 : ShowContinueError(state,
4758 4 : format("The actuator is allowed but the transient heat transfer modeling may not be valid for surface "
4759 : "name = {}, and the simulation continues",
4760 2 : surface.Name));
4761 : }
4762 :
4763 4 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
4764 0 : if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
4765 : // throw warning, and do not allow
4766 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4767 0 : ShowContinueError(state,
4768 0 : format("Construction named = {} has internal source/sink",
4769 0 : state.dataConstruction->Construct(surface.Construction).Name));
4770 0 : ShowContinueError(
4771 : state,
4772 0 : format("While construction named = {} is not an internal source/sink construction",
4773 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
4774 0 : ShowContinueError(
4775 : state,
4776 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4777 0 : surface.Name));
4778 :
4779 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4780 0 : SurfNum) = false;
4781 : }
4782 : }
4783 :
4784 8 : if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4785 : SurfNum)) {
4786 4 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4787 : }
4788 :
4789 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
4790 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4791 : true;
4792 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4793 : true;
4794 0 : if (state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes !=
4795 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).TotNodes) {
4796 : // throw warning, and do not allow
4797 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4798 0 : ShowContinueError(state,
4799 0 : format("Construction named = {} has number of finite difference nodes ={}",
4800 0 : state.dataConstruction->Construct(surface.Construction).Name,
4801 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes));
4802 0 : ShowContinueError(
4803 : state,
4804 0 : format("While construction named = {}has number of finite difference nodes ={}",
4805 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
4806 0 : state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
4807 0 : .TotNodes));
4808 0 : ShowContinueError(
4809 : state,
4810 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4811 0 : surface.Name));
4812 :
4813 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4814 : false;
4815 : }
4816 :
4817 0 : if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
4818 0 : if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
4819 : // throw warning, and do not allow
4820 0 : ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
4821 0 : ShowContinueError(state,
4822 0 : format("Construction named = {} has internal source/sink",
4823 0 : state.dataConstruction->Construct(surface.Construction).Name));
4824 0 : ShowContinueError(
4825 : state,
4826 0 : format("While construction named = {} is not an internal source/sink construction",
4827 0 : state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
4828 0 : ShowContinueError(
4829 : state,
4830 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4831 0 : surface.Name));
4832 :
4833 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4834 0 : SurfNum) = false;
4835 : }
4836 : }
4837 :
4838 0 : if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
4839 : SurfNum)) {
4840 0 : surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
4841 : }
4842 :
4843 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { // don't allow
4844 0 : ShowSevereError(state,
4845 : "InitEMSControlledConstructions: EMS Construction State Actuator not available with Heat transfer "
4846 : "algorithm CombinedHeatAndMoistureFiniteElement.");
4847 0 : ShowContinueError(
4848 : state,
4849 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4850 0 : surface.Name));
4851 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4852 : true;
4853 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4854 : false;
4855 :
4856 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) { // don't allow
4857 0 : ShowSevereError(state,
4858 : "InitEMSControlledConstructions: EMS Construction State Actuator not available for Surfaces with "
4859 : "Foundation Outside Boundary Condition.");
4860 0 : ShowContinueError(
4861 : state,
4862 0 : format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
4863 0 : surface.Name));
4864 0 : state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4865 : true;
4866 0 : state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
4867 : false;
4868 : }
4869 :
4870 : } else {
4871 : // do nothing, has been checked and is not okay with single warning already issued.
4872 : }
4873 : }
4874 : } else {
4875 31494 : surface.Construction = surface.ConstructionStoredInputValue;
4876 31494 : state.dataSurface->SurfActiveConstruction(SurfNum) = surface.ConstructionStoredInputValue;
4877 : }
4878 : } // for (SurfNum)
4879 : } // InitEMSControlledConstructions()
4880 :
4881 : // End Initialization Section of the Module
4882 : //******************************************************************************
4883 :
4884 : // Begin Algorithm Section of the Module
4885 : //******************************************************************************
4886 :
4887 : // Beginning of Record Keeping subroutines for the HB Module
4888 : // *****************************************************************************
4889 :
4890 249967 : void UpdateIntermediateSurfaceHeatBalanceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
4891 : {
4892 249967 : int firstZone = 1;
4893 249967 : int lastZone = state.dataGlobal->NumOfZones;
4894 :
4895 249967 : if (present(ZoneToResimulate)) {
4896 8 : firstZone = ZoneToResimulate;
4897 8 : lastZone = ZoneToResimulate;
4898 : }
4899 :
4900 586629 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4901 706951 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4902 370289 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4903 370289 : int const firstSurf = thisSpace.WindowSurfaceFirst;
4904 370289 : int const lastSurf = thisSpace.WindowSurfaceLast;
4905 458851 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4906 88562 : if (state.dataSurface->Surface(surfNum).ExtSolar) { // WindowManager's definition of ZoneWinHeatGain/Loss
4907 88560 : state.dataHeatBal->ZoneWinHeatGain(zoneNum) += state.dataSurface->SurfWinHeatGain(surfNum);
4908 : }
4909 : }
4910 : // Update zone window heat gain reports (these intermediate values are also used for Sensible Heat Gain Summary in GatherHeatGainReport)
4911 370289 : if (state.dataHeatBal->ZoneWinHeatGain(zoneNum) >= 0.0) {
4912 338968 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = state.dataHeatBal->ZoneWinHeatGain(zoneNum);
4913 338968 : state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) =
4914 338968 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
4915 : } else {
4916 31321 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = -state.dataHeatBal->ZoneWinHeatGain(zoneNum);
4917 31321 : state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) =
4918 31321 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
4919 : }
4920 336662 : }
4921 : }
4922 :
4923 249967 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
4924 0 : UpdateNonRepresentativeSurfaceResults(state, ZoneToResimulate);
4925 : }
4926 :
4927 : // Opaque or window surfaces (Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.)
4928 586629 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4929 706951 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4930 370289 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4931 370289 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
4932 370289 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
4933 2439226 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4934 2068937 : state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) =
4935 2068937 : -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
4936 2068937 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
4937 : }
4938 336662 : }
4939 : }
4940 : // Opaque surfaces
4941 586629 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4942 706951 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4943 370289 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4944 370289 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
4945 370289 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
4946 2350668 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4947 1980379 : state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) =
4948 1980379 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum);
4949 : }
4950 336662 : }
4951 : }
4952 : // Inside face conduction calculation for Kiva surfaces
4953 249968 : for (int surfNum : state.dataSurface->AllHTKivaSurfaceList) {
4954 1 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) =
4955 1 : -(state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
4956 1 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
4957 1 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum));
4958 249967 : }
4959 249967 : }
4960 :
4961 0 : void UpdateNonRepresentativeSurfaceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
4962 : {
4963 0 : int firstZone = 1;
4964 0 : int lastZone = state.dataGlobal->NumOfZones;
4965 :
4966 0 : if (present(ZoneToResimulate)) {
4967 0 : firstZone = ZoneToResimulate;
4968 0 : lastZone = ZoneToResimulate;
4969 : }
4970 :
4971 0 : for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
4972 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4973 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
4974 : // Heat transfer surfaces
4975 0 : int firstSurf = thisSpace.HTSurfaceFirst;
4976 0 : int lastSurf = thisSpace.HTSurfaceLast;
4977 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4978 0 : auto const &surface = state.dataSurface->Surface(surfNum);
4979 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
4980 :
4981 0 : if (surfNum != repSurfNum) {
4982 : #if 0
4983 : // Check for divergence
4984 : Real64 surfConv = -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
4985 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
4986 : Real64 repSurfConv = -state.dataHeatBalSurf->SurfHConvInt(repSurfNum) *
4987 : (state.dataHeatBalSurf->SurfTempIn(repSurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum));
4988 : Real64 diff = surfConv - repSurfConv;
4989 : if (std::abs(diff) > 3.0 && state.dataSurface->Surface(repSurfNum).ConstituentSurfaceNums.size() == 2) {
4990 : ShowWarningError(state, format("Difference in representative surface convection {:.3R} W/m2", diff));
4991 : ShowContinueErrorTimeStamp(state, "");
4992 : ShowContinueError(state, format(" Original Surface: {}", surface.Name));
4993 : ShowContinueError(state, format(" Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(surfNum)));
4994 : ShowContinueError(state,
4995 : format(" Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(surfNum)));
4996 : ShowContinueError(state,
4997 : format(" Sunlit fraction: {:.3R}",
4998 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum)));
4999 : ShowContinueError(state, format(" Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum)));
5000 : ShowContinueError(state,
5001 : format(" Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(surfNum)));
5002 : ShowContinueError(state, format(" Representative Surface: {}", state.dataSurface->Surface(repSurfNum).Name));
5003 : ShowContinueError(state, format(" Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(repSurfNum)));
5004 : ShowContinueError(state,
5005 : format(" Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(repSurfNum)));
5006 : ShowContinueError(state,
5007 : format(" Sunlit fraction: {:.3R}",
5008 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, repSurfNum)));
5009 : ShowContinueError(state,
5010 : format(" Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum)));
5011 : ShowContinueError(
5012 : state, format(" Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(repSurfNum)));
5013 : }
5014 : #endif
5015 :
5016 : // Surface Heat Balance Arrays
5017 0 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempIn(repSurfNum);
5018 0 : state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(repSurfNum);
5019 0 : state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBal->SurfTempEffBulkAir(repSurfNum);
5020 0 : state.dataHeatBalSurf->SurfHConvInt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(repSurfNum);
5021 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(repSurfNum);
5022 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(repSurfNum);
5023 0 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(repSurfNum);
5024 :
5025 0 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(repSurfNum);
5026 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvExt(repSurfNum);
5027 0 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(repSurfNum);
5028 0 : state.dataHeatBalSurf->SurfHAirExt(surfNum) = state.dataHeatBalSurf->SurfHAirExt(repSurfNum);
5029 0 : state.dataHeatBalSurf->SurfHSkyExt(surfNum) = state.dataHeatBalSurf->SurfHSkyExt(repSurfNum);
5030 0 : state.dataHeatBalSurf->SurfHGrdExt(surfNum) = state.dataHeatBalSurf->SurfHGrdExt(repSurfNum);
5031 :
5032 0 : state.dataSurface->SurfTAirRef(surfNum) = state.dataSurface->SurfTAirRef(repSurfNum);
5033 0 : if (state.dataSurface->SurfTAirRef(surfNum) != DataSurfaces::RefAirTemp::Invalid) {
5034 0 : state.dataSurface->SurfTAirRefRpt(surfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(surfNum)];
5035 : }
5036 :
5037 0 : state.dataSurface->surfExtConv(surfNum).hfModelEq = state.dataSurface->surfExtConv(repSurfNum).hfModelEq;
5038 0 : state.dataSurface->surfExtConv(surfNum).hnModelEq = state.dataSurface->surfExtConv(repSurfNum).hnModelEq;
5039 :
5040 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
5041 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(repSurfNum);
5042 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) =
5043 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(repSurfNum);
5044 :
5045 : // Internal (non reporting variables)
5046 0 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(repSurfNum);
5047 0 : state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum);
5048 : }
5049 : }
5050 :
5051 : // Opaque surfaces
5052 0 : firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
5053 0 : lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
5054 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
5055 0 : auto const &surface = state.dataSurface->Surface(surfNum);
5056 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
5057 :
5058 0 : if (surfNum != repSurfNum) {
5059 : // Surface Heat Balance Arrays
5060 0 : state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(repSurfNum);
5061 0 : state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum);
5062 0 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(repSurfNum);
5063 : }
5064 : }
5065 :
5066 : // Window surfaces
5067 0 : firstSurf = thisSpace.WindowSurfaceFirst;
5068 0 : lastSurf = thisSpace.WindowSurfaceLast;
5069 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
5070 0 : auto const &surface = state.dataSurface->Surface(surfNum);
5071 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
5072 :
5073 0 : if (surfNum != repSurfNum) {
5074 0 : Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
5075 :
5076 : // Glazing
5077 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
5078 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
5079 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
5080 :
5081 : // Frame
5082 0 : Real64 frameHeatGain = 0.0;
5083 0 : if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
5084 0 : Real64 frameAreaRatio = state.dataSurface->SurfWinFrameArea(surfNum) / state.dataSurface->SurfWinFrameArea(repSurfNum);
5085 0 : state.dataSurface->SurfWinFrameHeatGain(surfNum) = state.dataSurface->SurfWinFrameHeatGain(repSurfNum) * frameAreaRatio;
5086 0 : state.dataSurface->SurfWinFrameHeatLoss(surfNum) = state.dataSurface->SurfWinFrameHeatLoss(repSurfNum) * frameAreaRatio;
5087 0 : state.dataSurface->SurfWinFrameTempIn(surfNum) = state.dataSurface->SurfWinFrameTempIn(repSurfNum);
5088 0 : state.dataSurface->SurfWinFrameTempSurfOut(surfNum) = state.dataSurface->SurfWinFrameTempSurfOut(repSurfNum);
5089 0 : frameHeatGain = state.dataSurface->SurfWinFrameHeatGain(surfNum) - state.dataSurface->SurfWinFrameHeatLoss(surfNum);
5090 : }
5091 :
5092 : // Divider
5093 0 : Real64 dividerHeatGain = 0.0;
5094 0 : if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
5095 0 : Real64 dividerAreaRatio = state.dataSurface->SurfWinDividerArea(surfNum) / state.dataSurface->SurfWinDividerArea(repSurfNum);
5096 0 : state.dataSurface->SurfWinDividerHeatGain(surfNum) = state.dataSurface->SurfWinDividerHeatGain(repSurfNum) * dividerAreaRatio;
5097 0 : state.dataSurface->SurfWinDividerHeatLoss(surfNum) = state.dataSurface->SurfWinDividerHeatLoss(repSurfNum) * dividerAreaRatio;
5098 0 : state.dataSurface->SurfWinDividerTempIn(surfNum) = state.dataSurface->SurfWinDividerTempIn(repSurfNum);
5099 0 : state.dataSurface->SurfWinDividerTempSurfOut(surfNum) = state.dataSurface->SurfWinDividerTempSurfOut(repSurfNum);
5100 0 : dividerHeatGain = state.dataSurface->SurfWinDividerHeatGain(surfNum) - state.dataSurface->SurfWinDividerHeatLoss(surfNum);
5101 : }
5102 :
5103 0 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = frameHeatGain + dividerHeatGain;
5104 :
5105 : // Whole window
5106 0 : state.dataSurface->SurfWinHeatGain(surfNum) = (state.dataSurface->SurfWinHeatGain(repSurfNum) -
5107 0 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(repSurfNum) * areaRatio) +
5108 0 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum);
5109 : }
5110 : }
5111 0 : }
5112 : }
5113 0 : }
5114 :
5115 249945 : void UpdateFinalSurfaceHeatBalance(EnergyPlusData &state)
5116 : {
5117 :
5118 : // SUBROUTINE INFORMATION:
5119 : // AUTHOR Rick Strand
5120 : // DATE WRITTEN December 2000
5121 :
5122 : // PURPOSE OF THIS SUBROUTINE:
5123 : // If a radiant system is present and was on for part of the time step,
5124 : // then we probably need to make yet another pass through the heat balance.
5125 : // This is necessary because the heat source/sink to the surface that is
5126 : // the radiant system may have varied during the system time steps.
5127 :
5128 : // METHODOLOGY EMPLOYED:
5129 : // First, determine whether or not the radiant system was running. If
5130 : // any of the Qsource terms are non-zero, then it was running. Then,
5131 : // update the current source terms with the "average" value calculated
5132 : // by the radiant system algorithm. This requires the "USE" of the
5133 : // radiant algorithm module. Finally, using this source value, redo
5134 : // the inside and outside heat balances.
5135 :
5136 : bool LowTempRadSysOn; // .TRUE. if a low temperature radiant system is running
5137 : bool HighTempRadSysOn; // .TRUE. if a high temperature radiant system is running
5138 : bool HWBaseboardSysOn; // .TRUE. if a water baseboard heater is running
5139 : bool SteamBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
5140 : bool ElecBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
5141 : bool CoolingPanelSysOn; // true if a simple cooling panel is running
5142 : bool SwimmingPoolOn; // true if a pool is present (running)
5143 :
5144 249945 : LowTempRadiantSystem::UpdateRadSysSourceValAvg(state, LowTempRadSysOn);
5145 249945 : HighTempRadiantSystem::UpdateHTRadSourceValAvg(state, HighTempRadSysOn);
5146 249945 : HWBaseboardRadiator::UpdateBBRadSourceValAvg(state, HWBaseboardSysOn);
5147 249945 : SteamBaseboardRadiator::UpdateBBSteamRadSourceValAvg(state, SteamBaseboardSysOn);
5148 249945 : ElectricBaseboardRadiator::UpdateBBElecRadSourceValAvg(state, ElecBaseboardSysOn);
5149 249945 : CoolingPanelSimple::UpdateCoolingPanelSourceValAvg(state, CoolingPanelSysOn);
5150 249945 : SwimmingPool::UpdatePoolSourceValAvg(state, SwimmingPoolOn);
5151 :
5152 249945 : if (LowTempRadSysOn || HighTempRadSysOn || HWBaseboardSysOn || SteamBaseboardSysOn || ElecBaseboardSysOn || CoolingPanelSysOn || SwimmingPoolOn) {
5153 : // Solve the zone heat balance 'Detailed' solution
5154 : // Call the outside and inside surface heat balances
5155 4 : CalcHeatBalanceOutsideSurf(state);
5156 4 : CalcHeatBalanceInsideSurf(state);
5157 : }
5158 249945 : }
5159 :
5160 200977 : void UpdateThermalHistories(EnergyPlusData &state)
5161 : {
5162 :
5163 : // SUBROUTINE INFORMATION:
5164 : // AUTHOR Russ Taylor
5165 : // DATE WRITTEN June 1990
5166 : // RE-ENGINEERED Mar98 (RKS)
5167 :
5168 : // PURPOSE OF THIS SUBROUTINE:
5169 : // This subroutine updates and shifts the thermal and flux histories.
5170 :
5171 : // METHODOLOGY EMPLOYED:
5172 : // If a surface runs on the user selected subhourly time step, then the
5173 : // history terms for the temperatures and fluxes must simply be updated
5174 : // and shifted. However, if the surface runs at a different (longer) time
5175 : // step, then the "master" history series is used for the interpolated
5176 : // update scheme.
5177 :
5178 : // REFERENCES:
5179 : // (I)BLAST legacy routine UTHRMH
5180 : // Taylor et.al., Impact of Simultaneous Simulation of Buildings and
5181 : // Mechanical Systems in Heat Balance Based Energy Analysis Programs
5182 : // on System Response and Control, Building Simulation '91, IBPSA, Nice, France.
5183 :
5184 200977 : if (state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag) {
5185 103 : state.dataHeatBalSurfMgr->QExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5186 103 : state.dataHeatBalSurfMgr->QInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5187 103 : state.dataHeatBalSurfMgr->TempInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5188 103 : state.dataHeatBalSurfMgr->TempExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
5189 103 : state.dataHeatBalSurfMgr->SumTime.dimension(state.dataSurface->TotSurfaces, 0.0);
5190 103 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5191 1 : state.dataHeatBalSurfMgr->Qsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
5192 1 : state.dataHeatBalSurfMgr->Tsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
5193 1 : state.dataHeatBalSurfMgr->Tuser1.dimension(state.dataSurface->TotSurfaces, 0.0);
5194 : }
5195 103 : state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag = false;
5196 : }
5197 :
5198 488650 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5199 608949 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5200 321276 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5201 321276 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5202 321276 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5203 2007735 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5204 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5205 1686459 : auto const &surface = state.dataSurface->Surface(SurfNum);
5206 :
5207 1686459 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5208 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5209 0 : continue;
5210 : }
5211 :
5212 1686459 : int const ConstrNum = surface.Construction;
5213 1686459 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5214 :
5215 1686459 : if (construct.NumCTFTerms == 0) {
5216 0 : continue; // Skip surfaces with no history terms
5217 : }
5218 :
5219 : // Sign convention for the various terms in the following two equations
5220 : // is based on the form of the Conduction Transfer Function equation
5221 : // given by:
5222 : // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + (Sum of)(V Qsrc)
5223 : // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + (Sum of)(W Qsrc)
5224 : // In both equations, flux is positive from outside to inside. The V and W terms are for radiant systems only.
5225 :
5226 : // Set current inside flux:
5227 1686459 : Real64 const SurfOutsideTempCurr = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
5228 1686459 : Real64 SurfInsideFluxHistCurr = SurfOutsideTempCurr * construct.CTFCross[0] -
5229 1686459 : state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFInside[0] +
5230 1686459 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum); // Heat source/sink term for radiant systems
5231 : // Only HT opaq surfaces are evaluated, previous if (surface.Class == SurfaceClass::Floor || surface.Class == SurfaceClass::Wall ||
5232 : // surface.Class == SurfaceClass::IntMass || surface.Class == SurfaceClass::Roof || surface.Class == SurfaceClass::Door) checks are
5233 : // redundant.
5234 1686459 : if (construct.SourceSinkPresent) {
5235 2 : SurfInsideFluxHistCurr += state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceIn[0];
5236 : }
5237 1686459 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr;
5238 1686459 : state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting
5239 1686459 : state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr;
5240 :
5241 : // Update the temperature at the source/sink location (if one is present)
5242 1686459 : if (construct.SourceSinkPresent) {
5243 2 : state.dataHeatBalSurf->SurfTempSource(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1) =
5244 2 : SurfOutsideTempCurr * construct.CTFTSourceOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTSourceIn[0] +
5245 2 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTSourceQ[0] +
5246 2 : state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
5247 2 : state.dataHeatBalSurf->SurfTempUserLoc(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1) =
5248 2 : SurfOutsideTempCurr * construct.CTFTUserOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTUserIn[0] +
5249 2 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTUserSource[0] +
5250 2 : state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum);
5251 : }
5252 :
5253 : // Set current outside flux:
5254 1686459 : if (construct.SourceSinkPresent) {
5255 2 : state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) =
5256 2 : SurfOutsideTempCurr * construct.CTFOutside[0] - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
5257 2 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceOut[0] +
5258 2 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); // Heat source/sink term for radiant systems
5259 : } else {
5260 3372914 : state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = SurfOutsideTempCurr * construct.CTFOutside[0] -
5261 1686457 : state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
5262 1686457 : state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum);
5263 : }
5264 : // switch sign for balance at outside face
5265 1686459 : state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = -state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
5266 1686459 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(SurfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum);
5267 : }
5268 287673 : }
5269 : } // ...end of loop over all (heat transfer) surfaces...
5270 :
5271 200977 : if (state.dataHeatBal->SimpleCTFOnly && !state.dataGlobal->AnyConstrOverridesInModel) {
5272 : // Temporarily save the rvalue references of the last term arrays
5273 193863 : Array1D<Real64> insideTemp(std::move(state.dataHeatBalSurf->SurfInsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
5274 193863 : Array1D<Real64> outsideTemp(std::move(state.dataHeatBalSurf->SurfOutsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
5275 193863 : Array1D<Real64> insideFlux(std::move(state.dataHeatBalSurf->SurfInsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
5276 193863 : Array1D<Real64> outsideFlux(std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
5277 : // Shifting its internal pointer to data to the new object; Using the (Array1D && a) overload of the "=" operator
5278 1325627 : for (int HistTermNum = state.dataHeatBal->MaxCTFTerms + 1; HistTermNum >= 3; --HistTermNum) {
5279 1131764 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum - 1));
5280 1131764 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum - 1));
5281 1131764 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum - 1));
5282 1131764 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum - 1));
5283 : }
5284 : // Reuse the pointers of the last term arrays for the second term arrays
5285 193863 : state.dataHeatBalSurf->SurfInsideTempHist(2) = std::move(insideTemp);
5286 193863 : state.dataHeatBalSurf->SurfOutsideTempHist(2) = std::move(outsideTemp);
5287 193863 : state.dataHeatBalSurf->SurfInsideFluxHist(2) = std::move(insideFlux);
5288 193863 : state.dataHeatBalSurf->SurfOutsideFluxHist(2) = std::move(outsideFlux);
5289 : // Hard copy the values of the the 1st term to the 2nd (copying data instead of pointers to protect the 1st term arrays used in run time)
5290 193863 : state.dataHeatBalSurf->SurfInsideTempHist(2) = state.dataHeatBalSurf->SurfInsideTempHist(1);
5291 193863 : state.dataHeatBalSurf->SurfOutsideTempHist(2) = state.dataHeatBalSurf->SurfOutsideTempHist(1);
5292 193863 : state.dataHeatBalSurf->SurfInsideFluxHist(2) = state.dataHeatBalSurf->SurfInsideFluxHist(1);
5293 193863 : state.dataHeatBalSurf->SurfOutsideFluxHist(2) = state.dataHeatBalSurf->SurfOutsideFluxHist(1);
5294 193863 : return;
5295 193863 : }
5296 :
5297 14230 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5298 14232 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5299 7116 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5300 7116 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5301 7116 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5302 44374 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5303 37258 : auto const &surface = state.dataSurface->Surface(SurfNum);
5304 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5305 37258 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5306 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5307 0 : continue;
5308 : }
5309 37258 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5310 37258 : state.dataHeatBalSurfMgr->TempExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
5311 37258 : state.dataHeatBalSurfMgr->TempInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
5312 37258 : state.dataHeatBalSurfMgr->QExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
5313 37258 : state.dataHeatBalSurfMgr->QInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum);
5314 : }
5315 : }
5316 7116 : }
5317 :
5318 : } // ...end of loop over all (heat transfer) surfaces...
5319 7114 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5320 4 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5321 4 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5322 2 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5323 2 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5324 2 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5325 4 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5326 2 : auto const &surface = state.dataSurface->Surface(SurfNum);
5327 : // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
5328 2 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5329 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5330 0 : continue;
5331 : }
5332 2 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5333 2 : state.dataHeatBalSurfMgr->Tsrc1(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1);
5334 2 : state.dataHeatBalSurfMgr->Tuser1(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1);
5335 2 : state.dataHeatBalSurfMgr->Qsrc1(SurfNum) = state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1);
5336 : }
5337 : }
5338 2 : }
5339 : } // ...end of loop over all (heat transfer) surfaces...
5340 : }
5341 :
5342 : // SHIFT TEMPERATURE AND FLUX HISTORIES:
5343 : // SHIFT AIR TEMP AND FLUX SHIFT VALUES WHEN AT BOTTOM OF ARRAY SPACE.
5344 14230 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5345 14232 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5346 7116 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5347 7116 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5348 7116 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5349 44374 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5350 37258 : auto const &surface = state.dataSurface->Surface(SurfNum);
5351 :
5352 37258 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5353 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5354 0 : continue;
5355 : }
5356 :
5357 37258 : int const ConstrNum = surface.Construction;
5358 37258 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5359 :
5360 37258 : ++state.dataHeatBalSurf->SurfCurrNumHist(SurfNum);
5361 37258 : state.dataHeatBalSurfMgr->SumTime(SurfNum) = double(state.dataHeatBalSurf->SurfCurrNumHist(SurfNum)) * state.dataGlobal->TimeStepZone;
5362 :
5363 37258 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == construct.NumHistories) {
5364 37258 : state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
5365 :
5366 37258 : if (construct.NumCTFTerms > 1) {
5367 7126 : int const numCTFTerms(construct.NumCTFTerms);
5368 35612 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
5369 28486 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum) =
5370 28486 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
5371 28486 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum) =
5372 28486 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
5373 28486 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum) =
5374 28486 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5375 28486 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum) =
5376 28486 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5377 28486 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) =
5378 28486 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
5379 28486 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) =
5380 28486 : state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
5381 28486 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) =
5382 28486 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5383 28486 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) =
5384 28486 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
5385 : }
5386 : }
5387 :
5388 37258 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempExt1(SurfNum);
5389 37258 : state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempInt1(SurfNum);
5390 37258 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QExt1(SurfNum);
5391 37258 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QInt1(SurfNum);
5392 :
5393 37258 : state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum);
5394 37258 : state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum);
5395 37258 : state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum);
5396 37258 : state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum);
5397 : } else {
5398 0 : Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
5399 0 : if (construct.NumCTFTerms > 1) {
5400 0 : int const numCTFTerms(construct.NumCTFTerms);
5401 0 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
5402 : // TH(SideNum, TermNum, SurfNum) = (THM(SideNum, TermNum, SurfNum) -
5403 : // (THM(SideNum, TermNum, SurfNum) - THM(SideNum, TermNum - 1, SurfNum)) * sum_steps;
5404 0 : Real64 const THM_Out_1(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum));
5405 0 : Real64 const THM_In_1(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum));
5406 0 : Real64 const THM_Out_2(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum));
5407 0 : Real64 const THM_In_2(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum));
5408 0 : state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = THM_Out_1 - (THM_Out_1 - THM_Out_2) * sum_steps;
5409 0 : state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = THM_In_1 - (THM_In_1 - THM_In_2) * sum_steps;
5410 :
5411 0 : Real64 const QHM_Out_1(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum));
5412 0 : Real64 const QHM_In_1(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum));
5413 0 : Real64 const QHM_Out_2(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum));
5414 0 : Real64 const QHM_In_2(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum));
5415 0 : state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = QHM_Out_1 - (QHM_Out_1 - QHM_Out_2) * sum_steps;
5416 0 : state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = QHM_In_1 - (QHM_In_1 - QHM_In_2) * sum_steps;
5417 : }
5418 : }
5419 : // TH( 1, 2, SurfNum ) = THM( 1, 2, SurfNum ) - ( THM( 1, 2, SurfNum ) - TempExt1( SurfNum ) ) * sum_steps;
5420 0 : state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) =
5421 0 : state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) -
5422 0 : (state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempExt1(SurfNum)) * sum_steps;
5423 0 : state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) =
5424 0 : state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) -
5425 0 : (state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempInt1(SurfNum)) * sum_steps;
5426 0 : state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) =
5427 0 : state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) -
5428 0 : (state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QExt1(SurfNum)) * sum_steps;
5429 0 : state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) =
5430 0 : state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) -
5431 0 : (state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QInt1(SurfNum)) * sum_steps;
5432 : }
5433 : }
5434 7116 : }
5435 : } // ...end of loop over all (heat transfer) surfaces
5436 :
5437 7114 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
5438 4 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5439 4 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5440 2 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5441 2 : int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
5442 2 : int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
5443 4 : for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
5444 2 : auto const &surface = state.dataSurface->Surface(SurfNum);
5445 2 : int const ConstrNum = surface.Construction;
5446 2 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
5447 2 : if (!construct.SourceSinkPresent) {
5448 0 : continue;
5449 : }
5450 2 : if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
5451 0 : (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
5452 0 : continue;
5453 : }
5454 :
5455 2 : if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
5456 2 : if (construct.NumCTFTerms > 1) {
5457 2 : int const numCTFTerms = construct.NumCTFTerms;
5458 2 : int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
5459 2 : int m1 = m + 1;
5460 4 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing
5461 : // SurfTsrcHist( SurfNum, HistTerm ) = SurfTsrcHistM( SurfNum, HHistTerm ) = SurfTsrcHistM( SurfNum, HistTermNum - 1
5462 : // ); SurfQsrcHist( SurfNum, HistTerm ) = SurfQsrcHistM( SurfNum, HHistTerm ) = SurfQsrcHistM( SurfNum, HistTermNum -
5463 : // 1 );
5464 2 : state.dataHeatBalSurf->SurfTsrcHist[m1] = state.dataHeatBalSurf->SurfTsrcHistM[m1] =
5465 2 : state.dataHeatBalSurf->SurfTsrcHistM[m];
5466 2 : state.dataHeatBalSurf->SurfQsrcHist[m1] = state.dataHeatBalSurf->SurfQsrcHistM[m1] =
5467 2 : state.dataHeatBalSurf->SurfQsrcHistM[m];
5468 2 : state.dataHeatBalSurf->SurfTuserHist[m1] = state.dataHeatBalSurf->SurfTuserHistM[m1] =
5469 2 : state.dataHeatBalSurf->SurfTuserHistM[m];
5470 : }
5471 : }
5472 2 : state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tsrc1(SurfNum);
5473 2 : state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tuser1(SurfNum);
5474 2 : state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Qsrc1(SurfNum);
5475 2 : state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2);
5476 2 : state.dataHeatBalSurf->SurfTuserHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2);
5477 2 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2);
5478 : } else {
5479 0 : Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
5480 :
5481 0 : if (construct.NumCTFTerms > 1) {
5482 0 : int const numCTFTerms = construct.NumCTFTerms;
5483 0 : int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
5484 0 : int m1 = m + 1;
5485 0 : for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing [ l ] == ()
5486 : // Real64 const SurfTsrcHistM_elem( SurfTsrcHistM( SurfNum, HistTermNum ) );
5487 : // SurfTsrcHist( SurfNum, HistTermNum ) = SurfTsrcHistM_elem - ( SurfTsrcHistM_elem - SurfTsrcHistM( SurfNum,
5488 : // HistTermNum
5489 : // - 1 ) ) * sum_steps; Real64 const QsrcHistM_elem( SurfQsrcHistM( SurfNum, HistTermNum ) ); SurfQsrcHist( SurfNum,
5490 : // HistTermNum ) = QsrcHistM_elem - ( QsrcHistM_elem - SurfQsrcHistM( SurfNum, HistTermNum - 1 ) ) * sum_steps;
5491 0 : Real64 const TsrcHistM_m1(state.dataHeatBalSurf->SurfTsrcHistM[m1]);
5492 0 : state.dataHeatBalSurf->SurfTsrcHist[m1] =
5493 0 : TsrcHistM_m1 - (TsrcHistM_m1 - state.dataHeatBalSurf->SurfTsrcHistM[m]) * sum_steps;
5494 0 : Real64 const QsrcHistM_m1(state.dataHeatBalSurf->SurfQsrcHistM[m1]);
5495 0 : state.dataHeatBalSurf->SurfQsrcHist[m1] =
5496 0 : QsrcHistM_m1 - (QsrcHistM_m1 - state.dataHeatBalSurf->SurfQsrcHistM[m]) * sum_steps;
5497 0 : Real64 const TuserHistM_m1(state.dataHeatBalSurf->SurfTuserHistM[m1]);
5498 0 : state.dataHeatBalSurf->SurfTuserHist[m1] =
5499 0 : TuserHistM_m1 - (TuserHistM_m1 - state.dataHeatBalSurf->SurfTuserHistM[m]) * sum_steps;
5500 : }
5501 : }
5502 : // Tuned Linear indexing
5503 : // SurfTsrcHist( SurfNum, 2 ) = SurfTsrcHistM( SurfNum, 2 ) - ( SurfTsrcHistM( SurfNum, 2 ) - Tsrc1( SurfNum ) ) * sum_steps;
5504 : // SurfQsrcHist( SurfNum, 2 ) = SurfQsrcHistM( SurfNum, 2 ) - ( SurfQsrcHistM( SurfNum, 2 ) - Qsrc1( SurfNum ) ) * sum_steps;
5505 0 : int const l2 = state.dataHeatBalSurf->SurfTsrcHist.index(SurfNum, 2);
5506 0 : state.dataHeatBalSurf->SurfTsrcHist[l2] =
5507 0 : state.dataHeatBalSurf->SurfTsrcHistM[l2] -
5508 0 : (state.dataHeatBalSurf->SurfTsrcHistM[l2] - state.dataHeatBalSurfMgr->Tsrc1(SurfNum)) * sum_steps;
5509 0 : state.dataHeatBalSurf->SurfQsrcHist[l2] =
5510 0 : state.dataHeatBalSurf->SurfQsrcHistM[l2] -
5511 0 : (state.dataHeatBalSurf->SurfQsrcHistM[l2] - state.dataHeatBalSurfMgr->Qsrc1(SurfNum)) * sum_steps;
5512 0 : state.dataHeatBalSurf->SurfTuserHist[l2] =
5513 0 : state.dataHeatBalSurf->SurfTuserHistM[l2] -
5514 0 : (state.dataHeatBalSurf->SurfTuserHistM[l2] - state.dataHeatBalSurfMgr->Tuser1(SurfNum)) * sum_steps;
5515 : }
5516 : }
5517 2 : }
5518 : } // ...end of loop over all (heat transfer) surfaces...
5519 : } // ...end of AnyInternalHeatSourceInInput
5520 : }
5521 :
5522 249966 : void CalculateZoneMRT(EnergyPlusData &state,
5523 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
5524 : {
5525 :
5526 : // SUBROUTINE INFORMATION:
5527 : // AUTHOR Rick Strand
5528 : // DATE WRITTEN November 2000
5529 :
5530 : // PURPOSE OF THIS SUBROUTINE:
5531 : // Calculates the current zone and enclosure MRT for thermal comfort and radiation
5532 : // calculation purposes.
5533 :
5534 249966 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5535 109 : state.dataHeatBalSurfMgr->SurfaceAE.allocate(state.dataSurface->TotSurfaces);
5536 109 : state.dataHeatBalSurfMgr->ZoneAESum.allocate(state.dataGlobal->NumOfZones);
5537 109 : state.dataHeatBalSurfMgr->SurfaceAE = 0.0;
5538 109 : state.dataHeatBalSurfMgr->ZoneAESum = 0.0;
5539 249 : for (auto &encl : state.dataViewFactor->EnclRadInfo) {
5540 140 : encl.sumAE = 0.0;
5541 109 : }
5542 902 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
5543 793 : auto const &surface = state.dataSurface->Surface(SurfNum);
5544 793 : if (surface.HeatTransSurf) {
5545 777 : auto &thisSurfAE = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum);
5546 777 : thisSurfAE = surface.Area * state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal;
5547 777 : int ZoneNum = surface.Zone;
5548 777 : if (ZoneNum > 0) {
5549 777 : state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) += thisSurfAE;
5550 : }
5551 777 : if (surface.RadEnclIndex > 0) {
5552 777 : state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).sumAE += thisSurfAE;
5553 : }
5554 : }
5555 : }
5556 : }
5557 :
5558 : // Zero sumAET for applicable enclosures
5559 249966 : if (present(ZoneToResimulate)) {
5560 32 : for (int spaceNum : state.dataHeatBal->Zone(ZoneToResimulate).spaceIndexes) {
5561 24 : int enclNum = state.dataHeatBal->space(spaceNum).radiantEnclosureNum;
5562 24 : state.dataViewFactor->EnclRadInfo(enclNum).sumAET = 0.0;
5563 24 : state.dataViewFactor->EnclRadInfo(enclNum).reCalcMRT = true;
5564 8 : }
5565 : } else {
5566 602842 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
5567 352884 : thisEnclosure.reCalcMRT = true;
5568 249958 : }
5569 : }
5570 586633 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5571 336667 : if (present(ZoneToResimulate) && (ZoneNum != ZoneToResimulate)) {
5572 0 : continue;
5573 : }
5574 336667 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
5575 336667 : if (state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) > 0.01) {
5576 336664 : Real64 zoneSumAET = 0.0;
5577 706955 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
5578 370291 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5579 2439240 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
5580 2068949 : Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) * state.dataHeatBalSurf->SurfTempIn(SurfNum);
5581 2068949 : zoneSumAET += surfAET;
5582 2068949 : state.dataViewFactor->EnclRadInfo(state.dataSurface->Surface(SurfNum).RadEnclIndex).sumAET += surfAET;
5583 : }
5584 336664 : }
5585 336664 : thisZoneHB.MRT = zoneSumAET / state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum);
5586 : } else {
5587 3 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5588 6 : ShowWarningError(
5589 : state,
5590 6 : format("Zone areas*inside surface emissivities are summing to zero, for Zone=\"{}\"", state.dataHeatBal->Zone(ZoneNum).Name));
5591 9 : ShowContinueError(state, "As a result, MRT will be set to MAT for that zone");
5592 : }
5593 3 : thisZoneHB.MRT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
5594 : }
5595 : }
5596 : // Calculate MRT for applicable enclosures
5597 602866 : for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
5598 352900 : if (!thisEnclosure.reCalcMRT) {
5599 0 : continue;
5600 : }
5601 352900 : if (thisEnclosure.sumAE > 0.01) {
5602 352898 : thisEnclosure.sumAET = 0.0;
5603 2421819 : for (int surfNum : thisEnclosure.SurfacePtr) {
5604 2068921 : Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum);
5605 2068921 : thisEnclosure.sumAET += surfAET;
5606 : }
5607 352898 : thisEnclosure.MRT = thisEnclosure.sumAET / thisEnclosure.sumAE;
5608 : } else {
5609 2 : if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
5610 4 : ShowWarningError(state,
5611 4 : format("Enclosure areas*inside surface emissivities are summing to zero, for Enclosure=\"{}\"", thisEnclosure.Name));
5612 6 : ShowContinueError(state, "As a result, MRT will be set to the volume weighted average MAT for that enclosure");
5613 : }
5614 2 : Real64 sumMATVol = 0.0;
5615 2 : Real64 sumVol = 0.0;
5616 2 : Real64 sumMAT = 0.0;
5617 5 : for (auto &spaceNum : thisEnclosure.spaceNums) {
5618 3 : Real64 spaceVolume = state.dataHeatBal->space(spaceNum).Volume;
5619 3 : Real64 spaceMAT = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT;
5620 3 : sumVol += spaceVolume;
5621 3 : sumMATVol += spaceMAT * spaceVolume;
5622 3 : sumMAT += spaceMAT;
5623 2 : }
5624 2 : if (sumVol > 0.01) {
5625 2 : thisEnclosure.MRT = sumMATVol / sumVol;
5626 : } else {
5627 0 : thisEnclosure.MRT = sumMAT / (int)thisEnclosure.spaceNums.size();
5628 : }
5629 : }
5630 : // Set space MRTs
5631 723194 : for (int spaceNum : thisEnclosure.spaceNums) {
5632 370294 : state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MRT = thisEnclosure.MRT;
5633 352900 : }
5634 249966 : }
5635 :
5636 249966 : state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime = false;
5637 249966 : }
5638 :
5639 : // End of Record Keeping subroutines for the HB Module
5640 : // *****************************************************************************
5641 :
5642 : // Beginning of Reporting subroutines for the HB Module
5643 : // *****************************************************************************
5644 :
5645 249953 : void CalcThermalResilience(EnergyPlusData &state)
5646 : {
5647 : // This function calculate timestep-wise heat index and humidex.
5648 :
5649 : // The computation of the heat index is a refinement of a result obtained by multiple regression analysis
5650 : // carried out by Lans P. Rothfusz and described in a 1990 National Weather Service (NWS)
5651 : // Technical Attachment (SR 90-23).
5652 : // Reference: https://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
5653 :
5654 : // The current formula for determining the humidex was developed by J. M. Masterton and F. A. Richardson of
5655 : // Canada's Atmospheric Environment Service in 1979.
5656 : // Reference: Masterson, J., and F. Richardson, 1979: Humidex, a method of quantifying human
5657 : // discomfort due to excessive heat and humidity CLI 1-79, Environment Canada, Atmospheric Environment Service
5658 : // using OutputProcessor::ReqRepVars;
5659 249953 : if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
5660 242 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5661 262 : SetupOutputVariable(state,
5662 : "Zone Heat Index",
5663 : Constant::Units::C,
5664 131 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex,
5665 : OutputProcessor::TimeStepType::Zone,
5666 : OutputProcessor::StoreType::Average,
5667 131 : state.dataHeatBal->Zone(ZoneNum).Name);
5668 262 : SetupOutputVariable(state,
5669 : "Zone Humidity Index",
5670 : Constant::Units::None,
5671 131 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex,
5672 : OutputProcessor::TimeStepType::Zone,
5673 : OutputProcessor::StoreType::Average,
5674 131 : state.dataHeatBal->Zone(ZoneNum).Name);
5675 : }
5676 580 : for (auto const *reqVar : state.dataOutputProcessor->reqVars) {
5677 469 : if (reqVar->name == "Zone Heat Index") {
5678 0 : state.dataHeatBalSurfMgr->reportVarHeatIndex = true;
5679 469 : } else if (reqVar->name == "Zone Humidity Index") {
5680 0 : state.dataHeatBalSurfMgr->reportVarHumidex = true;
5681 : }
5682 111 : }
5683 : }
5684 :
5685 : // Calculate Heat Index and Humidex.
5686 : // The heat index equation set is fit to Fahrenheit units, so the zone air temperature values are first convert to F,
5687 : // then heat index is calculated and converted back to C.
5688 249953 : if (state.dataHeatBalSurfMgr->reportVarHeatIndex || state.dataOutRptTab->displayThermalResilienceSummary) {
5689 145262 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5690 75319 : Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5691 75319 : Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
5692 75319 : Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress) * 100.0;
5693 75319 : Real64 const ZoneTF = ZoneT * (9.0 / 5.0) + 32.0;
5694 75319 : if (state.dataHeatBal->heatIndexMethod == DataHeatBalance::HeatIndexMethod::Simplified) {
5695 75319 : Real64 constexpr c1 = -42.379;
5696 75319 : Real64 constexpr c2 = 2.04901523;
5697 75319 : Real64 constexpr c3 = 10.14333127;
5698 75319 : Real64 constexpr c4 = -.22475541;
5699 75319 : Real64 constexpr c5 = -.00683783;
5700 75319 : Real64 constexpr c6 = -.05481717;
5701 75319 : Real64 constexpr c7 = .00122874;
5702 75319 : Real64 constexpr c8 = .00085282;
5703 75319 : Real64 constexpr c9 = -.00000199;
5704 : Real64 HI;
5705 :
5706 75319 : if (ZoneTF < 80) {
5707 40740 : HI = 0.5 * (ZoneTF + 61.0 + (ZoneTF - 68.0) * 1.2 + (ZoneRH * 0.094));
5708 : } else {
5709 34579 : HI = c1 + c2 * ZoneTF + c3 * ZoneRH + c4 * ZoneTF * ZoneRH + c5 * ZoneTF * ZoneTF + c6 * ZoneRH * ZoneRH +
5710 34579 : c7 * ZoneTF * ZoneTF * ZoneRH + c8 * ZoneTF * ZoneRH * ZoneRH + c9 * ZoneTF * ZoneTF * ZoneRH * ZoneRH;
5711 34579 : if (ZoneRH < 13 && ZoneTF < 112) {
5712 450 : HI -= (13 - ZoneRH) / 4 * std::sqrt((17 - abs(ZoneTF - 95)) / 17);
5713 34129 : } else if (ZoneRH > 85 && ZoneTF < 87) {
5714 86 : HI += (ZoneRH - 85) / 10 * (87 - ZoneTF) / 5;
5715 : }
5716 : }
5717 75319 : HI = (HI - 32.0) * (5.0 / 9.0);
5718 75319 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex = HI;
5719 : } else {
5720 : // calculate extended heat index
5721 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex =
5722 0 : ExtendedHI::heatindex(state, ZoneT + Constant::Kelvin, ZoneRH / 100.0) - Constant::Kelvin;
5723 : }
5724 : }
5725 : }
5726 249953 : if (state.dataHeatBalSurfMgr->reportVarHumidex || state.dataOutRptTab->displayThermalResilienceSummary) {
5727 145262 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5728 75319 : Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
5729 75319 : Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5730 75319 : Real64 const TDewPointK = Psychrometrics::PsyTdpFnWPb(state, ZoneW, state.dataEnvrn->OutBaroPress) + Constant::Kelvin;
5731 75319 : Real64 const e = 6.11 * std::exp(5417.7530 * ((1 / 273.16) - (1 / TDewPointK)));
5732 75319 : Real64 const h = 5.0 / 9.0 * (e - 10.0);
5733 75319 : Real64 const Humidex = ZoneT + h;
5734 75319 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex = Humidex;
5735 : }
5736 : }
5737 249953 : }
5738 :
5739 69975 : void ReportThermalResilience(EnergyPlusData &state)
5740 : {
5741 :
5742 69975 : Array1D_bool reportPeriodFlags;
5743 69975 : if (state.dataWeather->TotReportPers > 0) {
5744 20 : reportPeriodFlags.dimension(state.dataWeather->TotThermalReportPers, false);
5745 20 : General::findReportPeriodIdx(state, state.dataWeather->ThermalReportPeriodInput, state.dataWeather->TotThermalReportPers, reportPeriodFlags);
5746 : }
5747 :
5748 69975 : auto &ort = state.dataOutRptTab;
5749 70015 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5750 40 : if (reportPeriodFlags(i)) {
5751 18 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
5752 18 : state.dataWeather->ThermalReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
5753 : }
5754 : }
5755 :
5756 69975 : if (state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime) {
5757 40 : int constexpr HINoBins = 5; // Heat Index range - number of bins
5758 40 : int constexpr HumidexNoBins = 5; // Humidex range - number of bins
5759 40 : int constexpr SETNoBins = 5; // SET report column numbers
5760 40 : int constexpr ColdHourOfSafetyNoBins = 5; // Cold Stress Hour of Safety number of columns
5761 40 : int constexpr HeatHourOfSafetyNoBins = 5; // Heat Stress Hour of Safety number of columns
5762 40 : int constexpr UnmetDegreeHourNoBins = 6; // Unmet Degree Hour number of columns
5763 40 : int constexpr DiscomfortWtExceedHourNoBins = 4; // Unmet Degree Hour number of columns
5764 :
5765 40 : if (state.dataHeatBal->TotPeople == 0) {
5766 32 : state.dataHeatBalSurfMgr->hasPierceSET = false;
5767 : }
5768 54 : for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
5769 14 : if (!state.dataHeatBal->People(iPeople).Pierce) {
5770 12 : state.dataHeatBalSurfMgr->hasPierceSET = false;
5771 : }
5772 : }
5773 86 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5774 : // the whole period
5775 : // user specified reporting period
5776 48 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5777 2 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5778 2 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5779 2 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
5780 2 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5781 2 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5782 2 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
5783 2 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
5784 2 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
5785 2 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
5786 : }
5787 2 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(ColdHourOfSafetyNoBins, 0.0);
5788 2 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(HeatHourOfSafetyNoBins, 0.0);
5789 2 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, i).assign(UnmetDegreeHourNoBins, 0.0);
5790 2 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
5791 2 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
5792 : }
5793 46 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod = 0.0;
5794 46 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod = 0.0;
5795 46 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod = 0.0;
5796 46 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod = 0.0;
5797 : }
5798 40 : state.dataHeatBalSurfMgr->lowSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
5799 40 : state.dataHeatBalSurfMgr->highSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
5800 40 : state.dataHeatBalSurfMgr->lowSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
5801 40 : state.dataHeatBalSurfMgr->highSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
5802 40 : state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime = false;
5803 : }
5804 :
5805 : // Count hours only during weather simulation periods
5806 69975 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
5807 : // use default value if there are no user inputs
5808 40 : Real64 ColdTempThresh = 15.56;
5809 40 : Real64 HeatTempThresh = 30.0;
5810 : // Trace current time step Zone Pierce SET; NaN if no occupant or SET not calculated
5811 : // Record last time step SET to trace SET unmet duration;
5812 :
5813 40 : Real64 valueNotInit = -999.0;
5814 40 : Real64 nearThreshold = 1.0;
5815 80 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5816 40 : state.dataHeatBal->Resilience(ZoneNum).PierceSET = valueNotInit;
5817 40 : state.dataHeatBal->Resilience(ZoneNum).PMV = valueNotInit;
5818 : }
5819 80 : for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
5820 40 : int ZoneNum = state.dataHeatBal->People(iPeople).ZonePtr;
5821 40 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc =
5822 40 : state.dataHeatBal->People(iPeople).NumberOfPeople * state.dataHeatBal->People(iPeople).sched->getCurrentVal();
5823 40 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
5824 40 : if (state.dataHeatBal->People(iPeople).Pierce) {
5825 40 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = state.dataThermalComforts->ThermalComfortData(iPeople).PierceSET;
5826 : } else {
5827 0 : state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = -1;
5828 : }
5829 :
5830 40 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
5831 40 : Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
5832 40 : ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
5833 40 : bool &CrossedColdThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedColdThresh;
5834 40 : if (Temperature > ColdTempThresh) { // safe
5835 36 : if (!CrossedColdThresh) {
5836 : // compute the number of hours before threshold is reached
5837 36 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
5838 : }
5839 : } else { // danger
5840 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5841 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
5842 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
5843 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5844 : // first time crossing threshold
5845 4 : if (!CrossedColdThresh) {
5846 : // compute the time when the zone crosses the threshold temperature
5847 : int encodedMonDayHrMin;
5848 2 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5849 2 : state.dataEnvrn->Month,
5850 2 : state.dataEnvrn->DayOfMonth,
5851 2 : state.dataGlobal->HourOfDay,
5852 2 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5853 : // fixme: not sure how to aggregate by zone
5854 2 : state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[1] = encodedMonDayHrMin;
5855 2 : CrossedColdThresh = true;
5856 : }
5857 : }
5858 40 : HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
5859 40 : bool &CrossedHeatThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedHeatThresh;
5860 40 : if (Temperature < HeatTempThresh) { // safe
5861 16 : if (!CrossedHeatThresh) {
5862 : // compute the number of hours before threshold is reached
5863 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
5864 : }
5865 : } else { // danger
5866 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5867 24 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
5868 24 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
5869 24 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5870 : // first time crossing threshold
5871 24 : if (!CrossedHeatThresh) {
5872 : // compute the time when the zone crosses the threshold temperature
5873 : int encodedMonDayHrMin;
5874 2 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5875 2 : state.dataEnvrn->Month,
5876 2 : state.dataEnvrn->DayOfMonth,
5877 2 : state.dataGlobal->HourOfDay,
5878 2 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5879 2 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[1] = encodedMonDayHrMin;
5880 2 : CrossedHeatThresh = true;
5881 : }
5882 : }
5883 :
5884 40 : Real64 VeryHotPMVThresh = 3.0;
5885 40 : Real64 WarmPMVThresh = 0.7;
5886 40 : Real64 CoolPMVThresh = -0.7;
5887 40 : Real64 VeryColdPMVThresh = -3.0;
5888 40 : Real64 PMV = state.dataThermalComforts->ThermalComfortData(iPeople).FangerPMV;
5889 40 : if (PMV < VeryColdPMVThresh) {
5890 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[0] +=
5891 14 : (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5892 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[0] +=
5893 14 : (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5894 : }
5895 40 : if (PMV < CoolPMVThresh) {
5896 20 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[1] +=
5897 20 : (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5898 20 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[1] +=
5899 20 : (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5900 : }
5901 40 : if (PMV > WarmPMVThresh) {
5902 16 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[2] +=
5903 16 : (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
5904 16 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[2] +=
5905 16 : (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5906 : }
5907 40 : if (PMV > VeryHotPMVThresh) {
5908 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[3] +=
5909 0 : (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
5910 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[3] +=
5911 0 : (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5912 : }
5913 :
5914 : // check whether PierceSET changed for people in a zone
5915 40 : if (state.dataHeatBal->Resilience(ZoneNum).PierceSET < valueNotInit + nearThreshold) {
5916 40 : state.dataHeatBal->Resilience(ZoneNum).PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
5917 : } else {
5918 0 : if (state.dataHeatBal->Resilience(ZoneNum).PierceSET != state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET) {
5919 0 : ShowRecurringWarningErrorAtEnd(state,
5920 0 : fmt::format("Zone {} has multiple people objects with different PierceSet.", ZoneNum),
5921 0 : state.dataHeatBalFanSys->PierceSETerrorIndex);
5922 : }
5923 : }
5924 :
5925 : // check whether PierceSET, PMV, etc. changed for different people in a zone
5926 40 : if (state.dataHeatBal->Resilience(ZoneNum).PMV < valueNotInit + nearThreshold) {
5927 40 : state.dataHeatBal->Resilience(ZoneNum).PMV = PMV;
5928 : } else {
5929 0 : if (state.dataHeatBal->Resilience(ZoneNum).PMV != PMV) {
5930 0 : ShowRecurringWarningErrorAtEnd(state,
5931 0 : fmt::format("Zone {} has multiple people objects with different PMV.", ZoneNum),
5932 0 : state.dataHeatBalFanSys->PMVerrorIndex);
5933 : }
5934 : }
5935 :
5936 80 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
5937 40 : if (reportPeriodFlags(i)) {
5938 18 : int ReportPeriodIdx = i;
5939 18 : ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
5940 18 : bool &CrossedColdThreshRepPeriod = state.dataHeatBalFanSys->CrossedColdThreshRepPeriod(ZoneNum, ReportPeriodIdx);
5941 18 : if (Temperature > ColdTempThresh) { // safe
5942 16 : if (!CrossedColdThreshRepPeriod) {
5943 : // compute the number of hours before threshold is reached
5944 16 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
5945 : }
5946 : } else { // danger
5947 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5948 2 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
5949 2 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
5950 2 : NumOcc * state.dataGlobal->TimeStepZone;
5951 2 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
5952 2 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5953 : // first time crossing threshold
5954 2 : if (!CrossedColdThreshRepPeriod) {
5955 : // compute the time when the zone crosses the threshold temperature
5956 : int encodedMonDayHrMin;
5957 1 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5958 1 : state.dataEnvrn->Month,
5959 1 : state.dataEnvrn->DayOfMonth,
5960 1 : state.dataGlobal->HourOfDay,
5961 1 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5962 : // fixme: not sure how to aggregate by zone
5963 1 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
5964 1 : CrossedColdThreshRepPeriod = true;
5965 : }
5966 : }
5967 18 : HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
5968 18 : bool &CrossedHeatThreshRepPeriod = state.dataHeatBalFanSys->CrossedHeatThreshRepPeriod(ZoneNum, ReportPeriodIdx);
5969 18 : if (Temperature < HeatTempThresh) { // safe
5970 8 : if (!CrossedHeatThreshRepPeriod) {
5971 : // compute the number of hours before threshold is reached
5972 3 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
5973 : }
5974 : } else { // danger
5975 : // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
5976 10 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
5977 10 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
5978 10 : NumOcc * state.dataGlobal->TimeStepZone;
5979 10 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
5980 10 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
5981 : // first time crossing threshold
5982 10 : if (!CrossedHeatThreshRepPeriod) {
5983 : // compute the time when the zone crosses the threshold temperature
5984 : int encodedMonDayHrMin;
5985 2 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
5986 2 : state.dataEnvrn->Month,
5987 2 : state.dataEnvrn->DayOfMonth,
5988 2 : state.dataGlobal->HourOfDay,
5989 2 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
5990 2 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
5991 2 : CrossedHeatThreshRepPeriod = true;
5992 : }
5993 : }
5994 :
5995 18 : if (PMV < VeryColdPMVThresh) {
5996 7 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
5997 7 : (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
5998 7 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
5999 7 : (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6000 : }
6001 18 : if (PMV < CoolPMVThresh) {
6002 10 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6003 10 : (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
6004 10 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6005 10 : (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6006 : }
6007 18 : if (PMV > WarmPMVThresh) {
6008 8 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6009 8 : (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
6010 8 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6011 8 : (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6012 : }
6013 18 : if (PMV > VeryHotPMVThresh) {
6014 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6015 0 : (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
6016 0 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6017 0 : (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6018 : }
6019 : }
6020 : }
6021 : }
6022 80 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6023 40 : Real64 HI = state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex;
6024 40 : Real64 Humidex = state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex;
6025 :
6026 40 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6027 40 : if (HI <= 26.7) {
6028 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[0] += state.dataGlobal->TimeStepZone;
6029 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6030 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6031 36 : } else if (HI > 26.7 && HI <= 32.2) {
6032 2 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[1] += state.dataGlobal->TimeStepZone;
6033 2 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6034 2 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6035 34 : } else if (HI > 32.2 && HI <= 39.4) {
6036 34 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[2] += state.dataGlobal->TimeStepZone;
6037 34 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6038 34 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6039 0 : } else if (HI > 39.4 && HI <= 51.7) {
6040 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[3] += state.dataGlobal->TimeStepZone;
6041 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
6042 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6043 : } else {
6044 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[4] += state.dataGlobal->TimeStepZone;
6045 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
6046 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6047 : }
6048 :
6049 40 : if (Humidex <= 29) {
6050 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[0] += state.dataGlobal->TimeStepZone;
6051 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6052 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6053 36 : } else if (Humidex > 29 && Humidex <= 40) {
6054 36 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[1] += state.dataGlobal->TimeStepZone;
6055 36 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6056 36 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6057 0 : } else if (Humidex > 40 && Humidex <= 45) {
6058 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[2] += state.dataGlobal->TimeStepZone;
6059 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6060 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6061 0 : } else if (Humidex > 45 && Humidex <= 50) {
6062 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[3] += state.dataGlobal->TimeStepZone;
6063 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
6064 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6065 : } else {
6066 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[4] += state.dataGlobal->TimeStepZone;
6067 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
6068 0 : state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6069 : }
6070 :
6071 40 : Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
6072 40 : auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
6073 40 : Real64 CoolingSetpoint = zoneTstatSetpt.setptHi;
6074 40 : Real64 HeatingSetpoint = zoneTstatSetpt.setptLo;
6075 :
6076 40 : if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
6077 30 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[0] += (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6078 30 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[1] +=
6079 30 : NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6080 30 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[2] +=
6081 30 : (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6082 : }
6083 40 : if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
6084 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[3] += (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6085 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[4] +=
6086 4 : NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6087 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[5] +=
6088 4 : (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6089 : }
6090 :
6091 40 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
6092 : int encodedMonDayHrMin;
6093 40 : Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
6094 40 : Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
6095 :
6096 40 : if (PierceSET <= 12.2) {
6097 22 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[0] += (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
6098 22 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[1] += (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
6099 22 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[2] += (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6100 : // Reset duration when last step is out of range.
6101 22 : if (PierceSETLast == -1 || PierceSETLast > 12.2) {
6102 4 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6103 4 : state.dataEnvrn->Month,
6104 4 : state.dataEnvrn->DayOfMonth,
6105 4 : state.dataGlobal->HourOfDay,
6106 4 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6107 4 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
6108 4 : state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
6109 : }
6110 : // Keep the longest duration record.
6111 22 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
6112 36 : if (state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] &&
6113 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6114 12 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] = state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1];
6115 12 : state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[4] = state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1];
6116 : }
6117 18 : } else if (PierceSET > 30) {
6118 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[0] += (PierceSET - 30) * state.dataGlobal->TimeStepZone;
6119 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[1] += (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
6120 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[2] += (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6121 14 : if (PierceSETLast == -1 || PierceSETLast <= 30) {
6122 4 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6123 4 : state.dataEnvrn->Month,
6124 4 : state.dataEnvrn->DayOfMonth,
6125 4 : state.dataGlobal->HourOfDay,
6126 4 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6127 4 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
6128 4 : state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
6129 : }
6130 14 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
6131 28 : if (state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] &&
6132 14 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6133 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] = state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1];
6134 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[4] = state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1];
6135 : }
6136 : }
6137 :
6138 40 : if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
6139 12 : state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
6140 12 : state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
6141 : }
6142 : }
6143 :
6144 80 : for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
6145 40 : if (reportPeriodFlags(i)) {
6146 18 : int ReportPeriodIdx = i;
6147 :
6148 18 : if (HI <= 26.7) {
6149 2 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6150 2 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6151 2 : NumOcc * state.dataGlobal->TimeStepZone;
6152 2 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6153 2 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6154 16 : } else if (HI > 26.7 && HI <= 32.2) {
6155 1 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6156 1 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6157 1 : NumOcc * state.dataGlobal->TimeStepZone;
6158 1 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6159 1 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6160 15 : } else if (HI > 32.2 && HI <= 39.4) {
6161 15 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6162 15 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6163 15 : NumOcc * state.dataGlobal->TimeStepZone;
6164 15 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6165 15 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6166 0 : } else if (HI > 39.4 && HI <= 51.7) {
6167 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6168 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6169 0 : NumOcc * state.dataGlobal->TimeStepZone;
6170 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6171 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6172 : } else {
6173 0 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
6174 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6175 0 : NumOcc * state.dataGlobal->TimeStepZone;
6176 0 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6177 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6178 : }
6179 :
6180 18 : if (Humidex <= 29) {
6181 2 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6182 2 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6183 2 : NumOcc * state.dataGlobal->TimeStepZone;
6184 2 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6185 2 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6186 16 : } else if (Humidex > 29 && Humidex <= 40) {
6187 16 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6188 16 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6189 16 : NumOcc * state.dataGlobal->TimeStepZone;
6190 16 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6191 16 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6192 0 : } else if (Humidex > 40 && Humidex <= 45) {
6193 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6194 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6195 0 : NumOcc * state.dataGlobal->TimeStepZone;
6196 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6197 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6198 0 : } else if (Humidex > 45 && Humidex <= 50) {
6199 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6200 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6201 0 : NumOcc * state.dataGlobal->TimeStepZone;
6202 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6203 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6204 : } else {
6205 0 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
6206 0 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6207 0 : NumOcc * state.dataGlobal->TimeStepZone;
6208 0 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6209 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6210 : }
6211 :
6212 18 : if (state.dataHeatBalSurfMgr->hasPierceSET) {
6213 : int encodedMonDayHrMin;
6214 18 : Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
6215 18 : Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
6216 18 : if (PierceSET <= 12.2) {
6217 11 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6218 11 : (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
6219 11 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6220 11 : (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
6221 11 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6222 11 : (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6223 : // Reset duration when last step is out of range
6224 11 : if (PierceSETLast == -1 || PierceSETLast > 12.2) {
6225 2 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6226 2 : state.dataEnvrn->Month,
6227 2 : state.dataEnvrn->DayOfMonth,
6228 2 : state.dataGlobal->HourOfDay,
6229 2 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6230 2 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6231 2 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6232 9 : } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
6233 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6234 0 : state.dataEnvrn->Month,
6235 0 : state.dataEnvrn->DayOfMonth,
6236 0 : state.dataGlobal->HourOfDay,
6237 0 : state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
6238 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6239 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6240 : }
6241 : // Keep the longest duration record.
6242 11 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
6243 11 : if (state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
6244 21 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
6245 10 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6246 9 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
6247 9 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
6248 9 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
6249 9 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
6250 : }
6251 7 : } else if (PierceSET > 30) {
6252 7 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6253 7 : (PierceSET - 30) * state.dataGlobal->TimeStepZone;
6254 7 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6255 7 : (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
6256 7 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6257 7 : (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6258 : // Reset duration when last step is out of range.
6259 7 : if (PierceSETLast == -1 || PierceSETLast <= 30) {
6260 2 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6261 2 : state.dataEnvrn->Month,
6262 2 : state.dataEnvrn->DayOfMonth,
6263 2 : state.dataGlobal->HourOfDay,
6264 2 : state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
6265 2 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6266 2 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6267 5 : } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
6268 0 : General::EncodeMonDayHrMin(encodedMonDayHrMin,
6269 0 : state.dataEnvrn->Month,
6270 0 : state.dataEnvrn->DayOfMonth,
6271 0 : state.dataGlobal->HourOfDay,
6272 0 : state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
6273 0 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6274 0 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
6275 : }
6276 7 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
6277 7 : if (state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
6278 14 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
6279 7 : state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
6280 3 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
6281 3 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
6282 3 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
6283 3 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
6284 : }
6285 : }
6286 18 : if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
6287 6 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6288 6 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
6289 : }
6290 : }
6291 :
6292 18 : if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
6293 13 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6294 13 : (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6295 13 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6296 13 : NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6297 13 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6298 13 : (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
6299 : }
6300 18 : if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
6301 2 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6302 2 : (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6303 2 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
6304 2 : NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6305 2 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[5] +=
6306 2 : (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
6307 : }
6308 : }
6309 : }
6310 : } // loop over zones
6311 : }
6312 69975 : }
6313 :
6314 55 : void ReportCO2Resilience(EnergyPlusData &state)
6315 : {
6316 55 : if (state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime) {
6317 40 : int NoBins = 3;
6318 86 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6319 48 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6320 2 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6321 2 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6322 2 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6323 : }
6324 : }
6325 40 : state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime = false;
6326 40 : if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
6327 38 : if (state.dataOutRptTab->displayCO2ResilienceSummaryExplicitly) {
6328 0 : ShowWarningError(state,
6329 : "Writing Annual CO2 Resilience Summary - CO2 Level Hours reports: "
6330 : "Zone Air CO2 Concentration output is required, "
6331 : "but no ZoneAirContaminantBalance object is defined.");
6332 : }
6333 38 : state.dataOutRptTab->displayCO2ResilienceSummary = false;
6334 38 : return;
6335 : }
6336 : }
6337 :
6338 17 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
6339 34 : for (auto const &people : state.dataHeatBal->People) {
6340 17 : state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
6341 17 : }
6342 :
6343 17 : Array1D_bool reportPeriodFlags;
6344 17 : if (state.dataWeather->TotReportPers > 0) {
6345 16 : reportPeriodFlags.dimension(state.dataWeather->TotCO2ReportPers, false);
6346 16 : General::findReportPeriodIdx(state, state.dataWeather->CO2ReportPeriodInput, state.dataWeather->TotCO2ReportPers, reportPeriodFlags);
6347 : }
6348 :
6349 17 : auto &ort = state.dataOutRptTab;
6350 49 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6351 32 : if (reportPeriodFlags(i)) {
6352 16 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
6353 16 : state.dataWeather->CO2ReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
6354 : }
6355 : }
6356 :
6357 34 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6358 17 : Real64 ZoneAirCO2 = state.dataContaminantBalance->ZoneAirCO2Avg(ZoneNum);
6359 :
6360 17 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6361 17 : if (ZoneAirCO2 <= 1000) {
6362 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[0] += state.dataGlobal->TimeStepZone;
6363 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6364 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6365 13 : } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
6366 12 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[1] += state.dataGlobal->TimeStepZone;
6367 12 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6368 12 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6369 : } else {
6370 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[2] += state.dataGlobal->TimeStepZone;
6371 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6372 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6373 : }
6374 49 : for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
6375 32 : if (reportPeriodFlags(i)) {
6376 16 : int ReportPeriodIdx = i;
6377 16 : if (ZoneAirCO2 <= 1000) {
6378 4 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6379 4 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6380 4 : NumOcc * state.dataGlobal->TimeStepZone;
6381 4 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6382 4 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6383 12 : } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
6384 11 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6385 11 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6386 11 : NumOcc * state.dataGlobal->TimeStepZone;
6387 11 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6388 11 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6389 : } else {
6390 1 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6391 1 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6392 1 : NumOcc * state.dataGlobal->TimeStepZone;
6393 1 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6394 1 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6395 : }
6396 : }
6397 : }
6398 : }
6399 17 : } // loop over zones
6400 : }
6401 :
6402 55 : void ReportVisualResilience(EnergyPlusData &state)
6403 : {
6404 55 : if (state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime) {
6405 40 : int NoBins = 4;
6406 86 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6407 48 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6408 2 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6409 2 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6410 2 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
6411 : }
6412 : }
6413 40 : state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime = false;
6414 40 : if ((int)state.dataDayltg->daylightControl.size() == 0) {
6415 38 : if (state.dataOutRptTab->displayVisualResilienceSummaryExplicitly) {
6416 0 : ShowWarningError(state,
6417 : "Writing Annual Visual Resilience Summary - Lighting Level Hours reports: "
6418 : "Zone Average Daylighting Reference Point Illuminance output is required, "
6419 : "but no Daylighting Control Object is defined.");
6420 : }
6421 38 : state.dataOutRptTab->displayVisualResilienceSummary = false;
6422 38 : return;
6423 : }
6424 : }
6425 :
6426 17 : if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
6427 34 : for (auto const &people : state.dataHeatBal->People) {
6428 17 : state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
6429 17 : }
6430 : // Accumulate across daylighting controls first
6431 34 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6432 17 : state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum = 0.0;
6433 : }
6434 34 : for (int daylightCtrlNum = 1; daylightCtrlNum <= (int)state.dataDayltg->daylightControl.size(); ++daylightCtrlNum) {
6435 17 : auto &thisDaylightControl = state.dataDayltg->daylightControl(daylightCtrlNum);
6436 17 : if (thisDaylightControl.PowerReductionFactor > 0) {
6437 34 : for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
6438 17 : state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum += thisDaylightControl.refPts(refPt).illumSetPoint;
6439 : }
6440 : } else {
6441 0 : for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
6442 0 : state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum +=
6443 0 : thisDaylightControl.refPts(refPt).lums[(int)DataSurfaces::Lum::Illum];
6444 : }
6445 : }
6446 : }
6447 :
6448 17 : Array1D_bool reportPeriodFlags;
6449 17 : if (state.dataWeather->TotReportPers > 0) {
6450 16 : reportPeriodFlags.dimension(state.dataWeather->TotVisualReportPers, false);
6451 32 : General::findReportPeriodIdx(
6452 16 : state, state.dataWeather->VisualReportPeriodInput, state.dataWeather->TotVisualReportPers, reportPeriodFlags);
6453 : }
6454 :
6455 17 : auto &ort = state.dataOutRptTab;
6456 49 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6457 32 : if (reportPeriodFlags(i)) {
6458 16 : int curResMeterNumber = ort->meterNumTotalsBEPS(1);
6459 16 : state.dataWeather->VisualReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
6460 : }
6461 : }
6462 :
6463 34 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6464 17 : if (state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts == 0) {
6465 0 : continue;
6466 : }
6467 : // Now divide by total reference points to get average
6468 17 : Real64 avgZoneIllum = state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum / state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts;
6469 :
6470 17 : Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
6471 17 : if (avgZoneIllum <= 100) {
6472 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[0] += state.dataGlobal->TimeStepZone;
6473 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
6474 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6475 11 : } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
6476 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[1] += state.dataGlobal->TimeStepZone;
6477 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
6478 4 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6479 7 : } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
6480 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[2] += state.dataGlobal->TimeStepZone;
6481 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
6482 1 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6483 : } else {
6484 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[3] += state.dataGlobal->TimeStepZone;
6485 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
6486 6 : state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6487 : }
6488 49 : for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
6489 32 : if (reportPeriodFlags(i)) {
6490 16 : int ReportPeriodIdx = i;
6491 16 : if (avgZoneIllum <= 100) {
6492 6 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
6493 6 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6494 6 : NumOcc * state.dataGlobal->TimeStepZone;
6495 6 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
6496 6 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6497 10 : } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
6498 4 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
6499 4 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6500 4 : NumOcc * state.dataGlobal->TimeStepZone;
6501 4 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
6502 4 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6503 6 : } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
6504 0 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
6505 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6506 0 : NumOcc * state.dataGlobal->TimeStepZone;
6507 0 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
6508 0 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6509 : } else {
6510 6 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
6511 6 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6512 6 : NumOcc * state.dataGlobal->TimeStepZone;
6513 6 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
6514 6 : (NumOcc > 0) * state.dataGlobal->TimeStepZone;
6515 : }
6516 : }
6517 : }
6518 : }
6519 17 : } // loop over zones
6520 : }
6521 :
6522 249948 : void ReportSurfaceHeatBalance(EnergyPlusData &state)
6523 : {
6524 :
6525 : // SUBROUTINE INFORMATION:
6526 : // AUTHOR Linda Lawrie
6527 : // DATE WRITTEN Oct 2000
6528 :
6529 : // PURPOSE OF THIS SUBROUTINE:
6530 : // This subroutine puts the reporting part of the HBSurface Module in one area.
6531 :
6532 249948 : SolarShading::ReportSurfaceShading(state);
6533 :
6534 249948 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
6535 0 : ReportNonRepresentativeSurfaceResults(state);
6536 : }
6537 :
6538 : // Set derived surface output variables and other record keeping - after iterations are complete - all HT surfaces
6539 :
6540 : // Opaque or window surfaces
6541 586590 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6542 706887 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6543 370245 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6544 370245 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
6545 370245 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
6546 2439100 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6547 2068855 : auto const &surface = state.dataSurface->Surface(surfNum);
6548 : // Inside Face Convection - sign convention is positive means energy going into inside face from the air.
6549 2068855 : state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) = surface.Area * state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum);
6550 2068855 : state.dataHeatBalSurf->SurfQConvInRep(surfNum) =
6551 2068855 : state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6552 :
6553 2068855 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
6554 2068855 : state.dataHeatBalSurf->SurfQRadNetSurfInRep(surfNum) =
6555 2068855 : state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6556 :
6557 2068855 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) * surface.Area;
6558 2068855 : state.dataHeatBalSurf->SurfQRadIntGainsInRep(surfNum) =
6559 2068855 : state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6560 :
6561 2068855 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) * surface.Area;
6562 2068855 : state.dataHeatBalSurf->SurfQRadHVACInRep(surfNum) =
6563 2068855 : state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6564 :
6565 2068855 : state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) * surface.Area;
6566 :
6567 2068855 : state.dataHeatBalSurf->SurfQConvOutReport(surfNum) =
6568 2068855 : state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6569 :
6570 2068855 : state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) * surface.Area;
6571 2068855 : state.dataHeatBalSurf->SurfQRadOutReport(surfNum) =
6572 2068855 : state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6573 :
6574 : // Calculate surface heat emission to the air, positive values indicates heat transfer from surface to the outside
6575 2068855 : state.dataHeatBalSurf->SurfQAirExtReport(surfNum) =
6576 2068855 : surface.Area * state.dataHeatBalSurf->SurfHAirExt(surfNum) *
6577 2068855 : (state.dataHeatBalSurf->SurfTempOut(surfNum) - state.dataSurface->SurfOutDryBulbTemp(surfNum));
6578 :
6579 : // Subtract since SurfQdotConvOutRep's convention is opposite (positive values indicate heat transfer from the outside to the surface)
6580 2068855 : state.dataHeatBalSurf->SurfQHeatEmiReport(surfNum) =
6581 2068855 : state.dataHeatBalSurf->SurfQAirExtReport(surfNum) - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum);
6582 : }
6583 336642 : }
6584 : }
6585 :
6586 249948 : if (state.dataOutRptTab->displayHeatEmissionsSummary) {
6587 69935 : state.dataHeatBalSurf->SumSurfaceHeatEmission = 0.0;
6588 508457 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
6589 438522 : if (state.dataSurface->Surface(SurfNum).ExtBoundCond == DataSurfaces::ExternalEnvironment) {
6590 350203 : state.dataHeatBalSurf->SumSurfaceHeatEmission +=
6591 350203 : state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
6592 : }
6593 : }
6594 : }
6595 :
6596 : // Window surfaces
6597 586590 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6598 706887 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6599 370245 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6600 370245 : int const firstSurf = thisSpace.WindowSurfaceFirst;
6601 370245 : int const lastSurf = thisSpace.WindowSurfaceLast;
6602 458806 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6603 88561 : auto const &surface = state.dataSurface->Surface(surfNum);
6604 88561 : state.dataHeatBal->SurfWinInitialDifSolInTransReport(surfNum) =
6605 88561 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum) * surface.Area;
6606 :
6607 : // Absorbed short wave radiation
6608 : int TotGlassLayers;
6609 88561 : int const constrNum = state.dataSurface->SurfActiveConstruction(surfNum);
6610 88561 : auto const &thisConstruct = state.dataConstruction->Construct(constrNum);
6611 88561 : int const constrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(surfNum);
6612 88561 : DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(surfNum);
6613 88561 : if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::EQL) {
6614 2367 : TotGlassLayers = state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL;
6615 86194 : } else if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::BSDF) {
6616 0 : TotGlassLayers = thisConstruct.TotSolidLayers;
6617 86194 : } else if (DataSurfaces::NOT_SHADED(ShadeFlag) || ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
6618 86194 : TotGlassLayers = thisConstruct.TotGlassLayers;
6619 : } else {
6620 : // Interior, exterior or between-glass shade, screen or blind in place
6621 0 : TotGlassLayers = state.dataConstruction->Construct(constrNumSh).TotGlassLayers;
6622 : }
6623 88561 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) = 0.0;
6624 88561 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = 0.0;
6625 88561 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = 0.0;
6626 205255 : for (int lay = 1; lay <= TotGlassLayers; ++lay) {
6627 : // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
6628 116694 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) +=
6629 116694 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(surfNum, lay) * surface.Area;
6630 : // Total Shortwave Radiation Absorbed on Inside of Surface[W]
6631 116694 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
6632 : // Total Shortwave Absorbed:All solid Layers[W]
6633 116694 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
6634 : }
6635 :
6636 : // Window heat gain/loss
6637 88561 : if (state.dataSurface->SurfWinHeatGain(surfNum) >= 0.0) {
6638 32908 : state.dataSurface->SurfWinHeatGainRep(surfNum) = state.dataSurface->SurfWinHeatGain(surfNum);
6639 32908 : state.dataSurface->SurfWinHeatGainRepEnergy(surfNum) =
6640 32908 : state.dataSurface->SurfWinHeatGainRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6641 : } else {
6642 55653 : state.dataSurface->SurfWinHeatLossRep(surfNum) = -state.dataSurface->SurfWinHeatGain(surfNum);
6643 55653 : state.dataSurface->SurfWinHeatLossRepEnergy(surfNum) =
6644 55653 : state.dataSurface->SurfWinHeatLossRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6645 : }
6646 88561 : state.dataSurface->SurfWinHeatTransferRepEnergy(surfNum) =
6647 88561 : state.dataSurface->SurfWinHeatGain(surfNum) * state.dataGlobal->TimeStepZoneSec;
6648 88561 : if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
6649 0 : int pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
6650 0 : state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatGain = state.dataSurface->SurfWinHeatGainRep(surfNum);
6651 0 : state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatLoss = state.dataSurface->SurfWinHeatLossRep(surfNum);
6652 : }
6653 : }
6654 336642 : }
6655 : }
6656 :
6657 249948 : if (state.dataSurface->AnyMovableInsulation) {
6658 0 : ReportIntMovInsInsideSurfTemp(state);
6659 : }
6660 :
6661 : // Opaque heat transfer surfaces
6662 586590 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6663 706887 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6664 370245 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6665 370245 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6666 370245 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6667 2350539 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6668 1980294 : auto const &surface = state.dataSurface->Surface(surfNum);
6669 :
6670 1980294 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) * surface.Area;
6671 1980294 : state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(surfNum) =
6672 1980294 : state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) * state.dataGlobal->TimeStepZoneSec;
6673 :
6674 1980294 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) * surface.Area;
6675 1980294 : state.dataHeatBalSurf->SurfQRadSolarInRep(surfNum) =
6676 1980294 : state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6677 :
6678 1980294 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) * surface.Area;
6679 1980294 : state.dataHeatBalSurf->SurfQRadLightsInRep(surfNum) =
6680 1980294 : state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
6681 :
6682 : // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
6683 1980294 : state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(surfNum) * surface.Area;
6684 : // Total Shortwave Radiation Absorbed on Inside of Surface[W]
6685 1980294 : state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) * surface.Area;
6686 :
6687 : // inside face conduction updates
6688 1980294 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) * surface.Area;
6689 1980294 : state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(surfNum) =
6690 1980294 : state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6691 1980294 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = 0.0;
6692 1980294 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = 0.0;
6693 1980294 : if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) >= 0.0) {
6694 842732 : state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6695 : } else {
6696 1137562 : state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6697 : }
6698 :
6699 : // outside face conduction updates
6700 1980294 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum);
6701 1980294 : state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(surfNum) =
6702 1980294 : state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6703 1980294 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = 0.0;
6704 1980294 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = 0.0;
6705 1980294 : if (state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) >= 0.0) {
6706 1320256 : state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6707 : } else {
6708 660038 : state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6709 : }
6710 : }
6711 2350539 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6712 : // do average surface conduction updates
6713 :
6714 1980294 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) =
6715 1980294 : (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)) / 2.0;
6716 1980294 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(surfNum) =
6717 1980294 : (state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)) / 2.0;
6718 1980294 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(surfNum) =
6719 1980294 : state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6720 1980294 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = 0.0;
6721 1980294 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = 0.0;
6722 1980294 : if (state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) >= 0.0) {
6723 806811 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
6724 : } else {
6725 1173483 : state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
6726 : }
6727 :
6728 : // do surface storage rate updates
6729 1980294 : state.dataHeatBalSurf->SurfOpaqStorageCondFlux(surfNum) =
6730 1980294 : -(state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum));
6731 1980294 : state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) =
6732 1980294 : -(state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum));
6733 1980294 : state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(surfNum) =
6734 1980294 : state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
6735 1980294 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = 0.0;
6736 1980294 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = 0.0;
6737 1980294 : if (state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) >= 0.0) {
6738 1045196 : state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
6739 : } else {
6740 935098 : state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
6741 : }
6742 : }
6743 336642 : }
6744 : }
6745 :
6746 249948 : if (state.dataGlobal->ZoneSizingCalc && state.dataGlobal->CompLoadReportIsReq) {
6747 : // This is by surface, so it works for both space and zone component loads
6748 14868 : int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
6749 14868 : auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
6750 43206 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6751 56676 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6752 28338 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6753 28338 : int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6754 28338 : int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6755 171426 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6756 143088 : surfCLDayTS.surf[surfNum - 1].lightSWRadSeq = state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum);
6757 143088 : surfCLDayTS.surf[surfNum - 1].feneSolarRadSeq = state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum);
6758 : }
6759 28338 : firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
6760 28338 : lastSurf = thisSpace.OpaqOrWinSurfaceLast;
6761 178212 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6762 149874 : auto const &surface = state.dataSurface->Surface(surfNum);
6763 149874 : if (!state.dataGlobal->WarmupFlag) {
6764 20640 : if (state.dataGlobal->isPulseZoneSizing) {
6765 10320 : surfCLDayTS.surf[surfNum - 1].loadConvectedWithPulse = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
6766 : } else {
6767 10320 : surfCLDayTS.surf[surfNum - 1].loadConvectedNormal = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
6768 10320 : surfCLDayTS.surf[surfNum - 1].netSurfRadSeq = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
6769 : }
6770 : }
6771 : }
6772 28338 : }
6773 : }
6774 : }
6775 :
6776 249948 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
6777 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6778 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6779 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6780 0 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
6781 0 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
6782 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6783 0 : state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
6784 0 : state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
6785 : }
6786 0 : if (state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) >= 0.0) {
6787 0 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
6788 0 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) =
6789 0 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6790 : } else {
6791 0 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
6792 0 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) =
6793 0 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6794 : }
6795 :
6796 0 : if (state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) >= 0.0) {
6797 0 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
6798 0 : state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) =
6799 0 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6800 : } else {
6801 0 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
6802 0 : state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) =
6803 0 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
6804 : }
6805 0 : }
6806 : }
6807 : }
6808 249948 : }
6809 :
6810 0 : void ReportNonRepresentativeSurfaceResults(EnergyPlusData &state)
6811 : {
6812 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6813 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6814 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
6815 : // Heat transfer surfaces
6816 0 : int firstSurf = thisSpace.HTSurfaceFirst;
6817 0 : int lastSurf = thisSpace.HTSurfaceLast;
6818 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6819 0 : auto const &surface = state.dataSurface->Surface(surfNum);
6820 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
6821 0 : if (surfNum != repSurfNum) {
6822 0 : state.dataSurface->surfIntConv(surfNum).convClassRpt = state.dataSurface->surfIntConv(repSurfNum).convClassRpt;
6823 0 : state.dataSurface->surfExtConv(surfNum).convClassRpt = state.dataSurface->surfExtConv(repSurfNum).convClassRpt;
6824 : }
6825 : }
6826 :
6827 : // Windows
6828 0 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
6829 0 : firstSurf = thisSpace.WindowSurfaceFirst;
6830 0 : lastSurf = thisSpace.WindowSurfaceLast;
6831 0 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
6832 0 : auto const &surface = state.dataSurface->Surface(surfNum);
6833 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
6834 0 : if (surfNum != repSurfNum) {
6835 0 : Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
6836 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
6837 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
6838 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
6839 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
6840 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
6841 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(repSurfNum) * areaRatio;
6842 : }
6843 : }
6844 : }
6845 0 : }
6846 : }
6847 0 : }
6848 :
6849 1 : void ReportIntMovInsInsideSurfTemp(EnergyPlusData &state)
6850 : {
6851 1 : state.dataHeatBalSurf->SurfTempInMovInsRep = state.dataHeatBalSurf->SurfTempIn;
6852 3 : for (int SurfNum : state.dataSurface->intMovInsulSurfNums) {
6853 2 : if (state.dataSurface->intMovInsuls(SurfNum).present) {
6854 1 : state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
6855 : }
6856 1 : }
6857 1 : }
6858 : // End of Reporting subroutines for the HB Module
6859 : // *****************************************************************************
6860 :
6861 : // *****************************************************************************
6862 : // *****************************************************************************
6863 : // *****************************************************************************
6864 : // *****************************************************************************
6865 :
6866 : // Formerly EXTERNAL SUBROUTINES (heavily related to HeatBalanceSurfaceManager) now moved into namespace
6867 :
6868 249962 : void CalcHeatBalanceOutsideSurf(EnergyPlusData &state,
6869 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
6870 : {
6871 :
6872 : // SUBROUTINE INFORMATION:
6873 : // AUTHOR George Walton
6874 : // DATE WRITTEN December 1979
6875 : // MODIFIED Jun 1990 (RDT for new CTF arrays);
6876 : // Aug 2000 (RJL for MTF moisture calculations)
6877 : // Sep 2000 (RKS for new radiant exchange algorithm)
6878 : // Dec 2000 (RKS for radiant system model addition)
6879 : // Apr 2002 (COP removed denominator from OSC calculation
6880 : // Jul 2008 (P.Biddulph include calls to HAMT)
6881 : // Jul 2011, M.J. Witte and C.O. Pedersen, add new fields to OSC for last T, max and min
6882 : // Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
6883 : // RE-ENGINEERED Mar 1998 (RKS)
6884 :
6885 : // PURPOSE OF THIS SUBROUTINE:
6886 : // This subroutine performs a heat balance on the outside face of each
6887 : // surface in the building.
6888 :
6889 : // METHODOLOGY EMPLOYED:
6890 : // Various boundary conditions are set and additional parameters are set-
6891 : // up. Then, the proper heat balance equation is selected based on the
6892 : // presence of movable insulation, thermal mass of the surface construction,
6893 : // and convection model being used.
6894 :
6895 : // REFERENCES:
6896 : // (I)BLAST legacy routine HBOUT
6897 : // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
6898 :
6899 : // // Using/Aliasing
6900 : // using namespace DataEnvironment;
6901 : // using namespace DataHeatBalance;
6902 : // using namespace DataHeatBalSurface;
6903 : // using namespace DataSurfaces;
6904 : // using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
6905 : // using namespace Psychrometrics;
6906 : // using EcoRoofManager::CalcEcoRoof;
6907 : //
6908 : // // Locals
6909 : // // SUBROUTINE ARGUMENT DEFINITIONS:
6910 : //
6911 : //>>>>>>> origin/develop
6912 : // SUBROUTINE PARAMETER DEFINITIONS:
6913 249962 : constexpr std::string_view RoutineNameGroundTemp("CalcHeatBalanceOutsideSurf:GroundTemp");
6914 249962 : constexpr std::string_view RoutineNameGroundTempFC("CalcHeatBalanceOutsideSurf:GroundTempFC");
6915 249962 : constexpr std::string_view RoutineNameOtherSideCoefNoCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefNoCalcExt");
6916 249962 : constexpr std::string_view RoutineNameOtherSideCoefCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefCalcExt");
6917 249962 : constexpr std::string_view RoutineNameOSCM("CalcHeatBalanceOutsideSurf:OSCM");
6918 249962 : constexpr std::string_view RoutineNameExtEnvWetSurf("CalcHeatBalanceOutsideSurf:extEnvWetSurf");
6919 249962 : constexpr std::string_view RoutineNameExtEnvDrySurf("CalcHeatBalanceOutsideSurf:extEnvDrySurf");
6920 249962 : constexpr std::string_view RoutineNameNoWind("CalcHeatBalanceOutsideSurf:nowind");
6921 249962 : constexpr std::string_view RoutineNameOther("CalcHeatBalanceOutsideSurf:interior/other");
6922 249962 : constexpr std::string_view RoutineNameIZPart("CalcHeatBalanceOutsideSurf:IZPart");
6923 249962 : constexpr std::string_view HBSurfManGroundHAMT("HBSurfMan:Ground:HAMT");
6924 249962 : constexpr std::string_view HBSurfManRainHAMT("HBSurfMan:Rain:HAMT");
6925 249962 : constexpr std::string_view HBSurfManDrySurfCondFD("HBSurfMan:DrySurf:CondFD");
6926 249962 : constexpr std::string_view Outside("Outside");
6927 :
6928 249962 : auto &s_mat = state.dataMaterial;
6929 :
6930 249962 : bool MovInsulErrorFlag = false; // Movable Insulation error flag
6931 :
6932 : // set ground surfaces average temperature
6933 249962 : GetGroundSurfacesTemperatureAverage(state);
6934 :
6935 : // set surrounding surfaces average temperature
6936 249962 : GetSurroundingSurfacesTemperatureAverage(state);
6937 :
6938 249962 : auto &Surface = state.dataSurface->Surface;
6939 :
6940 249962 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
6941 0 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
6942 : // Need to transfer any source/sink for a surface to the local array. Note that
6943 : // the local array is flux (W/m2) while the QRadSysSource is heat transfer (W).
6944 : // This must be done at this location so that this is always updated correctly.
6945 0 : if (Surface(SurfNum).Area > 0.0) {
6946 0 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) =
6947 0 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
6948 : }
6949 :
6950 : // next we add source (actually a sink) from any integrated PV
6951 0 : if (Surface(SurfNum).Area > 0.0) {
6952 0 : state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +=
6953 0 : state.dataHeatBalFanSys->QPVSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
6954 : }
6955 : }
6956 : }
6957 :
6958 249962 : if (present(ZoneToResimulate)) {
6959 16 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
6960 8 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, ZoneToResimulate, Outside);
6961 : } else {
6962 499908 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(
6963 249954 : state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, Outside);
6964 : }
6965 :
6966 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
6967 249963 : for (int surfNum : state.dataSurface->allOutsideSourceSurfaceList) {
6968 1 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) = Surface(surfNum).outsideHeatSourceTermSched->getCurrentVal();
6969 249962 : }
6970 586618 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
6971 706939 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6972 370283 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
6973 2439206 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
6974 2068923 : if (Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) {
6975 88560 : continue;
6976 : }
6977 1980363 : if (present(ZoneToResimulate)) {
6978 32 : if ((zoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) {
6979 0 : continue; // skip surfaces that are not associated with this zone
6980 : }
6981 : }
6982 : // Interior windows in partitions use "normal" heat balance calculations
6983 : // For rest, Outside surface temp of windows not needed in Window5 calculation approach.
6984 : // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
6985 :
6986 : // Initializations for this surface
6987 1980363 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
6988 1980363 : auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
6989 1980363 : Real64 HMovInsul = 0.0; // "Convection" coefficient of movable insulation
6990 1980363 : Real64 HSky = 0.0; // "Convection" coefficient from sky to surface
6991 1980363 : Real64 HGround = 0.0; // "Convection" coefficient from ground to surface
6992 1980363 : Real64 HAir = 0.0; // "Convection" coefficient from air to surface (radiation)
6993 1980363 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
6994 1980363 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
6995 1980363 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
6996 1980363 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
6997 1980363 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = 0.0;
6998 :
6999 : // Calculate the current outside surface temperature TH(SurfNum,1,1) for the
7000 : // various different boundary conditions
7001 1980363 : switch (Surface(SurfNum).ExtBoundCond) {
7002 119149 : case DataSurfaces::Ground: { // Surface in contact with ground
7003 119149 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
7004 119149 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
7005 :
7006 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7007 119149 : if (thisConstruct.SourceSinkPresent) {
7008 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7009 : }
7010 :
7011 : // start HAMT
7012 119149 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7013 : // Set variables used in the HAMT moisture balance
7014 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7015 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
7016 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
7017 0 : state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0, HBSurfManGroundHAMT);
7018 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7019 :
7020 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7021 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7022 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7023 : state,
7024 0 : state.dataEnvrn->OutBaroPress,
7025 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7026 : Psychrometrics::PsyWFnTdbRhPb(state,
7027 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7028 : 1.0,
7029 0 : state.dataEnvrn->OutBaroPress,
7030 0 : RoutineNameGroundTemp)) +
7031 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7032 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7033 :
7034 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7035 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7036 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7037 : }
7038 : // end HAMT
7039 :
7040 119149 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7041 : // Set variables used in the FD moisture balance
7042 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7043 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
7044 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
7045 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0);
7046 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7047 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7048 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7049 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7050 : state,
7051 0 : state.dataEnvrn->OutBaroPress,
7052 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7053 : Psychrometrics::PsyWFnTdbRhPb(state,
7054 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
7055 : 1.0,
7056 0 : state.dataEnvrn->OutBaroPress,
7057 0 : RoutineNameGroundTemp)) +
7058 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7059 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7060 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7061 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7062 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7063 : }
7064 : // Added for FCfactor grounds
7065 119149 : } break;
7066 0 : case DataSurfaces::GroundFCfactorMethod: { // Surface in contact with ground
7067 0 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
7068 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
7069 :
7070 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7071 0 : if (thisConstruct.SourceSinkPresent) {
7072 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7073 : }
7074 :
7075 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7076 : // Set variables used in the HAMT moisture balance
7077 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7078 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
7079 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
7080 0 : state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0, HBSurfManGroundHAMT);
7081 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7082 :
7083 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7084 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7085 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7086 : state,
7087 0 : state.dataEnvrn->OutBaroPress,
7088 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7089 : Psychrometrics::PsyWFnTdbRhPb(state,
7090 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7091 : 1.0,
7092 0 : state.dataEnvrn->OutBaroPress,
7093 0 : RoutineNameGroundTempFC)) +
7094 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7095 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7096 :
7097 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7098 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7099 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7100 : }
7101 :
7102 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7103 : // Set variables used in the FD moisture balance
7104 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
7105 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
7106 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
7107 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0);
7108 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7109 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7110 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7111 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7112 : state,
7113 0 : state.dataEnvrn->OutBaroPress,
7114 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7115 : Psychrometrics::PsyWFnTdbRhPb(state,
7116 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
7117 : 1.0,
7118 0 : state.dataEnvrn->OutBaroPress,
7119 0 : RoutineNameGroundTempFC)) +
7120 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7121 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7122 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7123 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7124 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7125 : }
7126 0 : } break;
7127 0 : case DataSurfaces::OtherSideCoefNoCalcExt: {
7128 : // Use Other Side Coefficients to determine the surface film coefficient and
7129 : // the exterior boundary condition temperature
7130 :
7131 0 : int OPtr = Surface(SurfNum).OSCPtr;
7132 : // Set surface temp from previous timestep
7133 0 : if (state.dataGlobal->BeginTimeStepFlag) {
7134 0 : state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7135 : }
7136 :
7137 0 : if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
7138 0 : state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
7139 : }
7140 :
7141 : // Allow for modification of TemperatureCoefficient with unitary sine wave.
7142 : Real64 ConstantTempCoef; // Temperature Coefficient as input or modified using sine wave COP mod
7143 0 : if (state.dataSurface->OSC(OPtr).SinusoidalConstTempCoef) { // Sine wave C4
7144 0 : ConstantTempCoef = std::sin(2 * Constant::Pi * state.dataGlobal->CurrentTime / state.dataSurface->OSC(OPtr).SinusoidPeriod);
7145 : } else {
7146 0 : ConstantTempCoef = state.dataSurface->OSC(OPtr).ConstTempCoef;
7147 : }
7148 :
7149 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7150 0 : (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
7151 0 : state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7152 0 : ConstantTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
7153 0 : state.dataSurface->OSC(OPtr).GroundTempCoef *
7154 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
7155 0 : state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
7156 0 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7157 0 : state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
7158 :
7159 : // Enforce max/min limits if applicable
7160 0 : if (state.dataSurface->OSC(OPtr).MinLimitPresent) {
7161 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7162 0 : max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7163 : }
7164 0 : if (state.dataSurface->OSC(OPtr).MaxLimitPresent) {
7165 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7166 0 : min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7167 : }
7168 :
7169 0 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataSurface->OSC(OPtr).OSCTempCalc;
7170 :
7171 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7172 0 : if (thisConstruct.SourceSinkPresent) {
7173 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7174 : }
7175 :
7176 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7177 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7178 : // Set variables used in the FD moisture balance and HAMT
7179 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7180 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7181 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7182 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
7183 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7184 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7185 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7186 0 : state.dataEnvrn->OutBaroPress,
7187 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7188 : Psychrometrics::PsyWFnTdbRhPb(state,
7189 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7190 : 1.0,
7191 0 : state.dataEnvrn->OutBaroPress,
7192 0 : RoutineNameOtherSideCoefNoCalcExt)) +
7193 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7194 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7195 0 : state.dataMstBal->HSkyFD(SurfNum) = HSky;
7196 0 : state.dataMstBal->HGrndFD(SurfNum) = HGround;
7197 0 : state.dataMstBal->HAirFD(SurfNum) = HAir;
7198 : }
7199 : // This ends the calculations for this surface and goes on to the next SurfNum
7200 0 : } break;
7201 0 : case DataSurfaces::OtherSideCoefCalcExt: { // A surface with other side coefficients that define the outside environment
7202 : // First, set up the outside convection coefficient and the exterior temperature
7203 : // boundary condition for the surface
7204 0 : int OPtr = Surface(SurfNum).OSCPtr;
7205 : // Set surface temp from previous timestep
7206 0 : if (state.dataGlobal->BeginTimeStepFlag) {
7207 0 : state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7208 : }
7209 :
7210 0 : if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
7211 0 : state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
7212 : }
7213 :
7214 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSC(OPtr).SurfFilmCoef;
7215 :
7216 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7217 0 : (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
7218 0 : state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7219 0 : state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
7220 0 : state.dataSurface->OSC(OPtr).GroundTempCoef *
7221 0 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
7222 0 : state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
7223 0 : state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
7224 0 : state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
7225 :
7226 : // Enforce max/min limits if applicable
7227 0 : if (state.dataSurface->OSC(OPtr).MinLimitPresent) {
7228 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7229 0 : max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7230 : }
7231 0 : if (state.dataSurface->OSC(OPtr).MaxLimitPresent) {
7232 0 : state.dataSurface->OSC(OPtr).OSCTempCalc =
7233 0 : min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
7234 : }
7235 :
7236 0 : Real64 TempExt = state.dataSurface->OSC(OPtr).OSCTempCalc;
7237 :
7238 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7239 0 : if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) {
7240 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7241 : }
7242 :
7243 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7244 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7245 : // Set variables used in the FD moisture balance and HAMT
7246 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7247 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7248 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7249 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7250 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7251 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7252 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7253 0 : state.dataEnvrn->OutBaroPress,
7254 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7255 : Psychrometrics::PsyWFnTdbRhPb(state,
7256 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7257 : 1.0,
7258 0 : state.dataEnvrn->OutBaroPress,
7259 0 : RoutineNameOtherSideCoefCalcExt)) +
7260 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7261 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7262 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7263 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7264 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7265 : }
7266 :
7267 : // Call the outside surface temp calculation and pass the necessary terms
7268 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7269 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7270 0 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7271 0 : if (MovInsulErrorFlag) {
7272 0 : ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7273 : }
7274 : }
7275 : // This ends the calculations for this surface and goes on to the next SurfNum
7276 0 : } break;
7277 0 : case DataSurfaces::OtherSideCondModeledExt: { // A surface with other side conditions determined from separate, dynamic component
7278 : // modeling that defines the "outside environment"
7279 : // First, set up the outside convection coefficient and the exterior temperature
7280 : // boundary condition for the surface
7281 0 : int OPtr = Surface(SurfNum).OSCMPtr;
7282 : // EMS overrides
7283 0 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTConv) {
7284 0 : state.dataSurface->OSCM(OPtr).TConv = state.dataSurface->OSCM(OPtr).EMSOverrideTConvValue;
7285 : }
7286 0 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHConv) {
7287 0 : state.dataSurface->OSCM(OPtr).HConv = state.dataSurface->OSCM(OPtr).EMSOverrideHConvValue;
7288 : }
7289 0 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTRad) {
7290 0 : state.dataSurface->OSCM(OPtr).TRad = state.dataSurface->OSCM(OPtr).EMSOverrideTRadValue;
7291 : }
7292 0 : if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHrad) {
7293 0 : state.dataSurface->OSCM(OPtr).HRad = state.dataSurface->OSCM(OPtr).EMSOverrideHradValue;
7294 : }
7295 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSCM(OPtr).HConv;
7296 :
7297 0 : Real64 TempExt = state.dataSurface->OSCM(OPtr).TConv;
7298 :
7299 : // Set the only radiant system heat balance coefficient that is non-zero for this case
7300 0 : if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) {
7301 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7302 : }
7303 :
7304 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7305 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7306 : // Set variables used in the FD moisture balance and HAMT
7307 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7308 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7309 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7310 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7311 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7312 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7313 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7314 : state,
7315 0 : state.dataEnvrn->OutBaroPress,
7316 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7317 : Psychrometrics::PsyWFnTdbRhPb(
7318 0 : state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOSCM)) +
7319 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7320 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7321 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataSurface->OSCM(OPtr).HRad; // CR 8046, use sky term for surface to baffle IR
7322 0 : state.dataMstBal->HGrndFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
7323 0 : state.dataMstBal->HAirFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
7324 : }
7325 :
7326 : // Call the outside surface temp calculation and pass the necessary terms
7327 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7328 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7329 :
7330 0 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
7331 0 : CalcExteriorVentedCavity(state, SurfNum);
7332 : }
7333 :
7334 0 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7335 0 : if (MovInsulErrorFlag) {
7336 0 : ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7337 : }
7338 :
7339 0 : } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7340 0 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7341 0 : if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
7342 0 : CalcExteriorVentedCavity(state, SurfNum);
7343 : }
7344 : }
7345 : // This ends the calculations for this surface and goes on to the next SurfNum
7346 0 : } break;
7347 1295912 : case DataSurfaces::ExternalEnvironment: {
7348 : // checking the EcoRoof presented in the external environment
7349 : // recompute each load by calling ecoroof
7350 :
7351 : Real64 TempExt;
7352 :
7353 1295912 : if (state.dataSurface->SurfExtEcoRoof(SurfNum)) {
7354 0 : EcoRoofManager::CalcEcoRoof(state, SurfNum, ConstrNum, TempExt);
7355 0 : continue;
7356 : }
7357 : // Roughness index of the exterior surface
7358 1295912 : Material::SurfaceRoughness RoughSurf = state.dataHeatBalSurf->SurfRoughnessExt(SurfNum);
7359 : // Thermal absorptance of the exterior surface
7360 1295912 : Real64 AbsThermSurf = state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum);
7361 1295912 : HMovInsul = 0;
7362 : // Check for outside movable insulation
7363 1295912 : if (state.dataSurface->AnyMovableInsulation && state.dataSurface->extMovInsuls(SurfNum).present) {
7364 0 : HMovInsul = state.dataSurface->extMovInsuls(SurfNum).H;
7365 : }
7366 :
7367 : // Check for exposure to wind (exterior environment)
7368 1295912 : if (Surface(SurfNum).ExtWind) {
7369 :
7370 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine)
7371 1212250 : Convect::InitExtConvCoeff(state,
7372 : SurfNum,
7373 : HMovInsul,
7374 : RoughSurf,
7375 : AbsThermSurf,
7376 1212250 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7377 1212250 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7378 1212250 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7379 1212250 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7380 1212250 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7381 1212250 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7382 :
7383 1212250 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside surface gets wet
7384 :
7385 0 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum == 0) { // Reset SurfHcExt because of wetness
7386 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0;
7387 : } else { // User set
7388 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
7389 : }
7390 :
7391 0 : TempExt = state.dataSurface->SurfOutWetBulbTemp(SurfNum);
7392 :
7393 : // start HAMT
7394 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7395 : // Set variables used in the HAMT moisture balance
7396 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7397 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) =
7398 0 : Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManRainHAMT);
7399 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7400 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7401 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7402 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7403 0 : state.dataEnvrn->OutBaroPress,
7404 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7405 : Psychrometrics::PsyWFnTdbRhPb(state,
7406 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7407 : 1.0,
7408 0 : state.dataEnvrn->OutBaroPress,
7409 0 : RoutineNameExtEnvWetSurf)) +
7410 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7411 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7412 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7413 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7414 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7415 : }
7416 : // end HAMT
7417 0 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
7418 : // Set variables used in the FD moisture balance
7419 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7420 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) =
7421 0 : Psychrometrics::PsyRhovFnTdbRhLBnd0C(state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0);
7422 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7423 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7424 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7425 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7426 0 : state.dataEnvrn->OutBaroPress,
7427 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7428 : Psychrometrics::PsyWFnTdbRhPb(state,
7429 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7430 : 1.0,
7431 0 : state.dataEnvrn->OutBaroPress,
7432 0 : RoutineNameExtEnvWetSurf)) +
7433 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7434 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7435 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7436 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7437 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7438 : }
7439 :
7440 : } else { // Surface is dry, use the normal correlation
7441 :
7442 1212250 : TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
7443 :
7444 2179640 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7445 967390 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7446 : // Set variables used in the FD moisture balance and HAMT
7447 244860 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7448 244860 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7449 244860 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7450 244860 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7451 244860 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7452 244860 : state.dataMstBal->HConvExtFD(SurfNum) /
7453 489720 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7454 244860 : state.dataEnvrn->OutBaroPress,
7455 244860 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7456 : Psychrometrics::PsyWFnTdbRhPb(state,
7457 244860 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7458 : 1.0,
7459 244860 : state.dataEnvrn->OutBaroPress,
7460 244860 : RoutineNameExtEnvDrySurf)) +
7461 489720 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7462 244860 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7463 : // check for saturation conditions of air
7464 : // Local temporary saturated vapor density for checking
7465 : Real64 RhoVaporSat =
7466 244860 : Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManDrySurfCondFD);
7467 244860 : if (state.dataMstBal->RhoVaporAirOut(SurfNum) > RhoVaporSat) {
7468 144030 : state.dataMstBal->RhoVaporAirOut(SurfNum) = RhoVaporSat;
7469 : }
7470 244860 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7471 244860 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7472 244860 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7473 : }
7474 : }
7475 :
7476 : } else { // No wind
7477 :
7478 : // Calculate exterior heat transfer coefficients for windspeed = 0
7479 83662 : Convect::InitExtConvCoeff(state,
7480 : SurfNum,
7481 : HMovInsul,
7482 : RoughSurf,
7483 : AbsThermSurf,
7484 83662 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7485 83662 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7486 83662 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7487 83662 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7488 83662 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7489 83662 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7490 :
7491 83662 : TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
7492 :
7493 167324 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7494 83662 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7495 : // Set variables used in the FD moisture balance and HAMT
7496 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
7497 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
7498 0 : state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
7499 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
7500 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7501 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7502 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7503 0 : state.dataEnvrn->OutBaroPress,
7504 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7505 : Psychrometrics::PsyWFnTdbRhPb(state,
7506 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7507 : 1.0,
7508 0 : state.dataEnvrn->OutBaroPress,
7509 0 : RoutineNameNoWind)) +
7510 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7511 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7512 0 : state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
7513 0 : state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
7514 0 : state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
7515 : }
7516 : }
7517 : // Calculate LWR from surrounding surfaces if defined for an exterior surface
7518 1295912 : if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
7519 6 : int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
7520 : // Absolute temperature of the outside surface of an exterior surface
7521 6 : Real64 TSurf = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) + Constant::Kelvin;
7522 14 : for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface;
7523 : SrdSurfNum++) {
7524 : // View factor of a surrounding surface
7525 8 : Real64 SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor;
7526 : // Absolute temperature of a surrounding surface
7527 : Real64 SrdSurfTempAbs =
7528 8 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() +
7529 8 : Constant::Kelvin;
7530 8 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) +=
7531 8 : Constant::StefanBoltzmann * AbsThermSurf * SrdSurfViewFac * (pow_4(SrdSurfTempAbs) - pow_4(TSurf));
7532 : }
7533 : }
7534 :
7535 1295912 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7536 1540772 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD ||
7537 244860 : Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
7538 1051052 : CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
7539 1051052 : if (MovInsulErrorFlag) {
7540 0 : ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
7541 : }
7542 : }
7543 1295912 : } break;
7544 :
7545 0 : case DataSurfaces::KivaFoundation: {
7546 0 : auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
7547 0 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness;
7548 0 : Real64 AbsThermSurf = thisMaterial->AbsorpThermal;
7549 :
7550 : // Set Kiva exterior convection algorithms
7551 0 : Convect::InitExtConvCoeff(state,
7552 : SurfNum,
7553 : HMovInsul,
7554 : RoughSurf,
7555 : AbsThermSurf,
7556 0 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
7557 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
7558 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
7559 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
7560 0 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
7561 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
7562 0 : } break;
7563 :
7564 565302 : default: { // for interior or other zone surfaces
7565 :
7566 565302 : if (Surface(SurfNum).ExtBoundCond == SurfNum) { // Regular partition/internal mass
7567 :
7568 402090 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
7569 :
7570 : // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
7571 :
7572 755208 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7573 353118 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7574 : // Set variables used in the FD moisture balance HAMT
7575 48972 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
7576 48972 : state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(SurfNum);
7577 48972 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
7578 48972 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7579 48972 : state.dataMstBal->HConvExtFD(SurfNum) /
7580 97944 : ((Psychrometrics::PsyRhoAirFnPbTdbW(
7581 : state,
7582 48972 : state.dataEnvrn->OutBaroPress,
7583 48972 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7584 : Psychrometrics::PsyWFnTdbRhPb(
7585 48972 : state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOther)) +
7586 97944 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7587 48972 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7588 48972 : state.dataMstBal->HSkyFD(SurfNum) = 0.0;
7589 48972 : state.dataMstBal->HGrndFD(SurfNum) = 0.0;
7590 48972 : state.dataMstBal->HAirFD(SurfNum) = 0.0;
7591 : }
7592 :
7593 : } else { // Interzone partition
7594 :
7595 163212 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
7596 163212 : state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
7597 :
7598 : // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
7599 :
7600 326424 : if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
7601 163212 : Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
7602 : // Set variables used in the FD moisture balance and HAMT
7603 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
7604 0 : state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(Surface(SurfNum).ExtBoundCond);
7605 0 : state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(Surface(SurfNum).ExtBoundCond);
7606 0 : state.dataMstBal->HMassConvExtFD(SurfNum) =
7607 0 : state.dataMstBal->HConvExtFD(SurfNum) /
7608 0 : ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
7609 0 : state.dataEnvrn->OutBaroPress,
7610 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7611 : Psychrometrics::PsyWFnTdbRhPb(state,
7612 0 : state.dataMstBal->TempOutsideAirFD(SurfNum),
7613 : 1.0,
7614 0 : state.dataEnvrn->OutBaroPress,
7615 0 : RoutineNameIZPart)) +
7616 0 : state.dataMstBal->RhoVaporAirOut(SurfNum)) *
7617 0 : Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
7618 0 : state.dataMstBal->HSkyFD(SurfNum) = 0.0;
7619 0 : state.dataMstBal->HGrndFD(SurfNum) = 0.0;
7620 0 : state.dataMstBal->HAirFD(SurfNum) = 0.0;
7621 : }
7622 : }
7623 : // This ends the calculations for this surface and goes on to the next SurfNum
7624 565302 : } break;
7625 : }
7626 :
7627 1980363 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = GetQdotConvOutPerArea(state, SurfNum);
7628 : }
7629 336656 : }
7630 : } // ...end of DO loop over all surface (actually heat transfer surfaces)
7631 249962 : }
7632 :
7633 1980365 : Real64 GetQdotConvOutPerArea(EnergyPlusData &state, int const SurfNum)
7634 : {
7635 1980365 : auto const &surface = state.dataSurface->Surface(SurfNum);
7636 1980365 : int OPtr = surface.OSCMPtr;
7637 1980365 : if (surface.OSCMPtr > 0) { // Optr is set above in this case, use OSCM boundary data
7638 0 : return -state.dataSurface->OSCM(OPtr).HConv * (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->OSCM(OPtr).TConv);
7639 : } else {
7640 1980365 : if (state.dataEnvrn->IsRain) {
7641 1 : return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
7642 1 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutWetBulbTemp(SurfNum));
7643 : } else {
7644 1980364 : return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
7645 1980364 : (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutDryBulbTemp(SurfNum));
7646 : }
7647 : }
7648 : }
7649 :
7650 249963 : void CalcHeatBalanceInsideSurf(EnergyPlusData &state,
7651 : ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
7652 : {
7653 249963 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime) {
7654 107 : if (state.dataHeatBal->AnyEMPD) {
7655 0 : state.dataHeatBalSurf->MinIterations = DataHeatBalSurface::MinEMPDIterations;
7656 : }
7657 107 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
7658 0 : SetupOutputVariable(state,
7659 : "Surface Inside Face Heat Balance Calculation Iteration Count",
7660 : Constant::Units::None,
7661 0 : state.dataHeatBal->InsideSurfIterations,
7662 : OutputProcessor::TimeStepType::Zone,
7663 : OutputProcessor::StoreType::Sum,
7664 : "Simulation");
7665 : }
7666 : // Precompute whether CTF temperature limits will be needed
7667 107 : state.dataHeatBalSurf->Zone_has_mixed_HT_models.resize(state.dataGlobal->NumOfZones + 1, false);
7668 235 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
7669 273 : for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
7670 145 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
7671 898 : for (int iSurf = thisSpace.HTSurfaceFirst, eSurf = thisSpace.HTSurfaceLast; iSurf <= eSurf; ++iSurf) {
7672 756 : DataSurfaces::HeatTransferModel const alg = state.dataSurface->Surface(iSurf).HeatTransferAlgorithm;
7673 756 : if ((alg == DataSurfaces::HeatTransferModel::CondFD) || (alg == DataSurfaces::HeatTransferModel::HAMT) ||
7674 : (alg == DataSurfaces::HeatTransferModel::Kiva)) {
7675 3 : state.dataHeatBalSurf->Zone_has_mixed_HT_models[iZone] = true;
7676 3 : break;
7677 : }
7678 : }
7679 128 : }
7680 : }
7681 107 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime = false;
7682 : }
7683 :
7684 249963 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag) {
7685 483 : state.dataHeatBalSurf->SurfTempInsOld = 23.0;
7686 483 : state.dataHeatBalSurfMgr->RefAirTemp = 23.0;
7687 483 : state.dataHeatBal->SurfTempEffBulkAir = 23.0;
7688 483 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount = 0;
7689 483 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = false;
7690 :
7691 : // Initialize Kiva instances ground temperatures
7692 483 : if (state.dataHeatBal->AnyKiva) {
7693 0 : state.dataSurfaceGeometry->kivaManager.initKivaInstances(state);
7694 : }
7695 : }
7696 249963 : if (!state.dataGlobal->BeginEnvrnFlag) {
7697 249480 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = true;
7698 : }
7699 :
7700 249963 : sumSurfQdotRadHVAC(state);
7701 :
7702 : // Pass correct list of surfaces to CalcHeatBalanceInsideSurf2
7703 249963 : bool const PartialResimulate(present(ZoneToResimulate));
7704 :
7705 249963 : if (!PartialResimulate) {
7706 249955 : if (state.dataHeatBal->AllCTF) {
7707 200983 : CalcHeatBalanceInsideSurf2CTFOnly(state, 1, state.dataGlobal->NumOfZones, state.dataSurface->AllIZSurfaceList);
7708 : } else {
7709 97944 : CalcHeatBalanceInsideSurf2(state,
7710 48972 : state.dataSurface->AllHTSurfaceList,
7711 48972 : state.dataSurface->AllIZSurfaceList,
7712 48972 : state.dataSurface->AllHTNonWindowSurfaceList,
7713 48972 : state.dataSurface->AllHTWindowSurfaceList);
7714 : }
7715 : } else {
7716 8 : auto const &zoneHTSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTSurfaceList;
7717 8 : auto const &zoneIZSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneIZSurfaceList;
7718 8 : auto const &zoneHTNonWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTNonWindowSurfaceList;
7719 8 : auto const &zoneHTWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTWindowSurfaceList;
7720 : // Cannot use CalcHeatBalanceInsideSurf2CTFOnly because resimulated zone includes adjacent interzone surfaces
7721 8 : CalcHeatBalanceInsideSurf2(state, zoneHTSurfList, zoneIZSurfList, zoneHTNonWindowSurfList, zoneHTWindowSurfList, ZoneToResimulate);
7722 : }
7723 249963 : CalculateZoneMRT(state, ZoneToResimulate); // Update here so that the proper value of MRT is available to radiant systems
7724 249963 : UpdateIntermediateSurfaceHeatBalanceResults(state, ZoneToResimulate);
7725 249963 : }
7726 :
7727 48980 : void CalcHeatBalanceInsideSurf2(EnergyPlusData &state,
7728 : const std::vector<int> &HTSurfs, // Heat transfer surfaces to simulate (opaque and windows)
7729 : const std::vector<int> &IZSurfs, // Interzone heat transfer surfaces to simulate
7730 : const std::vector<int> &HTNonWindowSurfs, // Non-window heat transfer surfaces to simulate
7731 : const std::vector<int> &HTWindowSurfs, // Window heat transfer surfaces to simulate
7732 : ObjexxFCL::Optional_int_const ZoneToResimulate)
7733 : {
7734 : // SUBROUTINE INFORMATION:
7735 : // AUTHOR George Walton
7736 : // DATE WRITTEN December 1979
7737 : // MODIFIED Jun 1990 (RDT for new CTF arrays)
7738 : // Dec 1999 (FCW for window calculation)
7739 : // May 2000 (FCW for window frame and dividers)
7740 : // Aug 2000 (RJL for MTF moisture calculations)
7741 : // Sep 2000 (RKS for new radiant exchange algorithm)
7742 : // Dec 2000 (RKS for radiant system model addition)
7743 : // Jul 2003 (CC) set the reference temperatures for inside surface heat balance
7744 : // depending on convection algorithms and/or air models used
7745 : // May 2006 (RR account for exterior window screen)
7746 : // Jul 2008 (P. Biddulph include calls to HAMT)
7747 : // Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
7748 : // RE-ENGINEERED Mar 1998 (RKS)
7749 :
7750 : // PURPOSE OF THIS SUBROUTINE:
7751 : // This subroutine performs a heat balance on the inside face of each
7752 : // surface in the building.
7753 :
7754 : // METHODOLOGY EMPLOYED:
7755 : // Various boundary conditions are set and additional parameters are set-
7756 : // up. Then, the proper heat balance equation is selected based on whether
7757 : // the surface is a partition or not and on whether or not movable
7758 : // insulation is present on the inside face.
7759 :
7760 : // REFERENCES:
7761 : // (I)BLAST legacy routine HBSRF
7762 :
7763 48980 : constexpr std::string_view rhoAirZone("RhoAirZone");
7764 48980 : constexpr std::string_view wsurf("Wsurf");
7765 48980 : constexpr std::string_view HBSurfManInsideSurf("HB,SurfMan:InsideSurf");
7766 48980 : constexpr std::string_view Inside("Inside");
7767 :
7768 : Real64 TempSurfOutTmp; // Local Temporary Surface temperature for the outside surface face
7769 : Real64 SurfTempInSat; // Local temporary surface dew point temperature
7770 :
7771 : Real64 Wsurf; // Moisture ratio for HAMT
7772 : Real64 RhoAirZone; // Zone moisture density for HAMT
7773 : int OtherSideZoneNum; // Zone Number index for other side of an interzone partition HAMT
7774 :
7775 48980 : auto &s_mat = state.dataMaterial;
7776 : // determine reference air temperatures
7777 342844 : for (int SurfNum : HTSurfs) {
7778 :
7779 : // These conditions are not used in every SurfNum loop here so we don't use them to skip surfaces
7780 293864 : if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
7781 0 : continue; // Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.
7782 : }
7783 293864 : Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum);
7784 293864 : state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) = RefAirTemp;
7785 293864 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataHeatBalSurfMgr->RefAirTemp(SurfNum);
7786 48980 : }
7787 :
7788 : // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
7789 : // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
7790 : // CalcWindowHeatBalance.
7791 : // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
7792 48980 : for (int surfNum : HTWindowSurfs) {
7793 0 : state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
7794 0 : state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
7795 0 : state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
7796 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
7797 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
7798 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
7799 0 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
7800 0 : state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
7801 0 : state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
7802 0 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
7803 0 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
7804 0 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
7805 0 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
7806 48980 : }
7807 :
7808 48980 : state.dataHeatBal->InsideSurfIterations = 0;
7809 :
7810 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
7811 48980 : for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
7812 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
7813 0 : state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
7814 48980 : }
7815 :
7816 : // Calculate Kiva instances
7817 48980 : if (state.dataHeatBal->AnyKiva) {
7818 0 : if (((state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::HOURLY &&
7819 0 : state.dataGlobal->TimeStep == 1) ||
7820 0 : state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::TIMESTEP) &&
7821 0 : !state.dataGlobal->WarmupFlag) {
7822 0 : state.dataSurfaceGeometry->kivaManager.calcKivaInstances(state);
7823 : }
7824 : }
7825 :
7826 48980 : bool Converged = false; // .TRUE. if inside heat balance has converged
7827 148861 : while (!Converged) { // Start of main inside heat balance DO loop...
7828 :
7829 99881 : state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
7830 :
7831 99881 : if (state.dataHeatBal->AnyKiva) {
7832 0 : for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
7833 0 : state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = kivaSurf.second.results.Trad - Constant::Kelvin;
7834 0 : }
7835 : }
7836 :
7837 199762 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
7838 99881 : state.dataHeatBalSurf->SurfTempIn,
7839 99881 : state.dataHeatBal->InsideSurfIterations,
7840 99881 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
7841 : ZoneToResimulate,
7842 : Inside); // Update the radiation balance
7843 :
7844 99881 : if (state.dataHeatBal->AnyKiva) {
7845 0 : for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
7846 0 : state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = state.dataHeatBalSurf->SurfTempInsOld(kivaSurf.first);
7847 0 : }
7848 : }
7849 :
7850 : // Every 30 iterations, recalculate the inside convection coefficients in case
7851 : // there has been a significant drift in the surface temperatures predicted.
7852 : // This is not fool-proof and it basically means that the outside surface
7853 : // heat balance is in error (potentially) once HConvIn is re-evaluated.
7854 : // The choice of 30 is not significant--just want to do this a couple of
7855 : // times before the iteration limit is hit.
7856 150782 : if ((state.dataHeatBal->InsideSurfIterations > 0) &&
7857 50901 : (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
7858 16 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
7859 : }
7860 :
7861 99881 : if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
7862 0 : for (int SurfNum : HTSurfs) {
7863 0 : auto const &surface = state.dataSurface->Surface(SurfNum);
7864 0 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
7865 0 : continue; // Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.
7866 : }
7867 :
7868 : // Calculate the inside surface moisture quantities
7869 : // calculate the inside surface moisture transfer conditions
7870 : // check for saturation conditions of air
7871 0 : if ((surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) ||
7872 0 : (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)) {
7873 0 : int ZoneNum = surface.Zone;
7874 0 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
7875 0 : Real64 const ZoneAirHumRat_zone(max(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRat, 1.0e-5));
7876 0 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
7877 :
7878 0 : state.dataMstBal->RhoVaporAirIn(SurfNum) =
7879 0 : min(Psychrometrics::PsyRhovFnTdbWPb_fast(MAT_zone, ZoneAirHumRat_zone, state.dataEnvrn->OutBaroPress),
7880 : Psychrometrics::PsyRhovFnTdbRh(state, MAT_zone, 1.0, HBSurfManInsideSurf));
7881 0 : state.dataMstBal->HMassConvInFD(SurfNum) =
7882 0 : HConvIn_surf / (Psychrometrics::PsyRhoAirFnPbTdbW_fast(state, state.dataEnvrn->OutBaroPress, MAT_zone, ZoneAirHumRat_zone) *
7883 0 : Psychrometrics::PsyCpAirFnW_fast(ZoneAirHumRat_zone));
7884 : }
7885 0 : }
7886 : }
7887 :
7888 699129 : for (int SurfNum : HTNonWindowSurfs) {
7889 : // Perform heat balance on the inside face of the surface ...
7890 : // The following are possibilities here:
7891 : // (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
7892 : // (b) the surface is a partition, in which case the temperature of both sides are the same
7893 : // (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
7894 : // (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
7895 : // (e) standard opaque surface with movable insulation, special two-part equation
7896 : // In the surface calculation there are the following Algorithm types for opaque surfaces that
7897 : // do not have movable insulation:
7898 : // (a) the regular CTF calc (SolutionAlgo = UseCTF)
7899 : // (b) the EMPD calc (Solutionalgo = UseEMPD)
7900 : // (c) the CondFD calc (SolutionAlgo = UseCondFD)
7901 : // (d) the HAMT calc (solutionalgo = UseHAMT).
7902 :
7903 599248 : auto const &surface = state.dataSurface->Surface(SurfNum);
7904 599248 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
7905 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
7906 0 : if (SurfNum != repSurfNum) {
7907 0 : continue;
7908 : }
7909 : }
7910 599248 : int const ZoneNum = surface.Zone;
7911 599248 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
7912 599248 : int const ConstrNum = surface.Construction;
7913 599248 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
7914 599248 : Real64 const MAT_zone = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
7915 599248 : Real64 const HConvIn_surf = state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
7916 :
7917 599248 : if (surface.ExtBoundCond == SurfNum) {
7918 : // CR6869 -- let Window HB take care of it IF (Surface(SurfNum)%ExtBoundCond == SurfNum) THEN
7919 : // Surface is adiabatic
7920 99862 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
7921 99862 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
7922 :
7923 0 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7924 0 : MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
7925 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
7926 : }
7927 : // Pre-calculate a few terms
7928 : Real64 const TempTerm(
7929 0 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
7930 0 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
7931 0 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
7932 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
7933 0 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
7934 0 : Real64 const TempDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
7935 : // Calculate the current inside surface temperature
7936 0 : if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
7937 0 : ((state.dataSurface->SurfIsPool(SurfNum)) &&
7938 0 : (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
7939 0 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
7940 0 : if (construct.SourceSinkPresent) {
7941 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7942 0 : (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
7943 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
7944 : TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
7945 : // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
7946 : // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
7947 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
7948 : // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
7949 : // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
7950 : // same temp) | Convection and damping term | Radiation from AFN ducts
7951 : } else {
7952 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7953 0 : (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
7954 : TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
7955 : // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
7956 : // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
7957 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
7958 : // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
7959 : // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
7960 : // same temp) | Convection and damping term | Radiation from AFN ducts
7961 : }
7962 : } else { // this is a pool and it has been simulated this time step
7963 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7964 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
7965 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) /
7966 0 : (construct.CTFInside[0] - construct.CTFCross[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
7967 : DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms (see
7968 : // non-pool equation for details) | Iterative damping term (for stability) |
7969 : // Conduction term (both partition sides same temp) | Pool and damping term
7970 : }
7971 0 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
7972 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
7973 0 : state.dataMstBalEMPD->HeatFluxLatent(SurfNum) * TempDiv; // Conduction term (both partition sides same temp) |
7974 : // Conduction term (both partition sides same temp) |
7975 : // Convection and damping term
7976 0 : if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
7977 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
7978 : }
7979 : }
7980 : // if any mixed heat transfer models in zone, apply limits to CTF result
7981 0 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
7982 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
7983 0 : max(DataHeatBalSurface::MinSurfaceTempLimit,
7984 0 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
7985 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
7986 : }
7987 :
7988 0 : if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
7989 :
7990 : // Radiant system does not need the damping coefficient terms (hopefully) // Partitions are assumed to be symmetric
7991 0 : Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf));
7992 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
7993 0 : TempTerm * RadSysDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW
7994 : // radiation from internal sources | Convection from surface to zone air | Radiant flux from
7995 : // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant
7996 : // flux from a steam baseboard heater | Radiant flux from an electric baseboard heater | Net
7997 : // radiant exchange with other zone surfaces | Cond term (both partition sides same temp) | Cond
7998 : // term (both partition sides same temp) | Convection and damping term
7999 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
8000 : 0.0; // The outside temp is assumed to be equal to the inside temp for a partition
8001 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
8002 0 : construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both partition sides same temp) | Cond
8003 : // term (both partition sides same temp) | Convection and damping term
8004 : }
8005 :
8006 99862 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
8007 0 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8008 :
8009 99862 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8010 0 : HeatBalanceHAMTManager::ManageHeatBalHAMT(state,
8011 : SurfNum,
8012 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
8013 : TempSurfOutTmp); // HAMT
8014 : }
8015 :
8016 99862 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
8017 199724 : HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
8018 99862 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
8019 : }
8020 :
8021 99862 : TH11 = TempSurfOutTmp;
8022 : }
8023 :
8024 99862 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8025 :
8026 : } else { // Standard surface or interzone surface
8027 499386 : bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataSurface->intMovInsuls(SurfNum).present;
8028 499386 : if (!movableInsulPresent) { // No movable insulation present, normal heat balance equation
8029 :
8030 499386 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
8031 499310 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
8032 :
8033 76 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
8034 0 : MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
8035 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
8036 : }
8037 : // Pre-calculate a few terms
8038 : Real64 const TempTerm(
8039 76 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
8040 76 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
8041 76 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
8042 76 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
8043 76 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
8044 76 : Real64 const TempDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
8045 : // Calculate the current inside surface temperature
8046 76 : if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
8047 0 : ((state.dataSurface->SurfIsPool(SurfNum)) &&
8048 0 : (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
8049 0 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
8050 76 : if (construct.SourceSinkPresent) {
8051 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8052 0 : (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
8053 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
8054 0 : construct.CTFCross[0] * TH11) *
8055 : TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
8056 : // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
8057 : // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
8058 : // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
8059 : // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
8060 : // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
8061 : // outside surface | Coefficient for conduction (current time) | Convection and damping term |
8062 : // Radiation from AFN ducts
8063 : } else {
8064 76 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8065 76 : (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
8066 76 : construct.CTFCross[0] * TH11) *
8067 : TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
8068 : // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
8069 : // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
8070 : // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
8071 : // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
8072 : // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
8073 : // outside surface | Coefficient for conduction (current time) | Convection and damping term |
8074 : // Radiation from AFN ducts
8075 : }
8076 : } else { // surface is a pool and the pool has been simulated this time step
8077 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8078 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
8079 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) /
8080 0 : (construct.CTFInside[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
8081 : DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms
8082 : // (see non-pool equation for details) | Iterative damping term (for
8083 : // stability) | Current conduction from | the outside surface |
8084 : // Coefficient for conduction (current time) | Pool and damping term
8085 : }
8086 76 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
8087 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
8088 0 : state.dataMstBalEMPD->HeatFluxLatent(SurfNum) *
8089 : TempDiv; // Coefficient for conduction (current time) | Convection and damping term
8090 0 : if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
8091 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
8092 : }
8093 : }
8094 : // if any mixed heat transfer models in zone, apply limits to CTF result
8095 76 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
8096 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = max(
8097 : DataHeatBalSurface::MinSurfaceTempLimit,
8098 0 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
8099 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
8100 : }
8101 :
8102 76 : if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
8103 :
8104 : // Radiant system does not need the damping coefficient terms (hopefully)
8105 0 : Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf));
8106 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
8107 0 : TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
8108 : // radiation from internal sources | Convection from surface to zone air | Radiant flux
8109 : // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
8110 : // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
8111 : // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
8112 : // sides same temp) | Convection and damping term
8113 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
8114 0 : construct.CTFCross[0] * RadSysDiv; // Outside temp=inside temp for a partition |
8115 : // Cond term (both partition sides same temp) |
8116 : // Convection and damping term
8117 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
8118 0 : construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both
8119 : // partition sides same temp) | Convection and
8120 : // damping term
8121 :
8122 0 : if (surface.ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
8123 : // The inside coefficients of one side are equal to the outside coefficients of the other side. But,
8124 : // the inside coefficients are set up once the heat balance equation for that side has been calculated.
8125 : // For both sides to actually have been set, we have to wait until we get to the second side in the surface
8126 : // derived type. At that point, both inside coefficient sets have been evaluated.
8127 0 : if (surface.ExtBoundCond < SurfNum) { // Both of the inside coefficients have now been set
8128 0 : int OtherSideSurfNum = surface.ExtBoundCond;
8129 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
8130 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
8131 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
8132 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
8133 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
8134 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
8135 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
8136 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
8137 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) =
8138 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
8139 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) =
8140 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
8141 : }
8142 : }
8143 : }
8144 :
8145 499386 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
8146 0 : surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8147 :
8148 499310 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8149 0 : if (surface.ExtBoundCond > 0) {
8150 : // HAMT get the correct other side zone zone air temperature --
8151 0 : int OtherSideSurfNum = surface.ExtBoundCond;
8152 : // ZoneNum = surface.Zone;
8153 0 : OtherSideZoneNum = state.dataSurface->Surface(OtherSideSurfNum).Zone;
8154 0 : state.dataMstBal->TempOutsideAirFD(SurfNum) =
8155 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(OtherSideZoneNum).MAT;
8156 : }
8157 0 : HeatBalanceHAMTManager::ManageHeatBalHAMT(state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
8158 : }
8159 :
8160 499310 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
8161 998620 : HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
8162 499310 : state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
8163 : }
8164 :
8165 499310 : TH11 = TempSurfOutTmp;
8166 :
8167 499310 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) {
8168 : // Read Kiva results for each surface
8169 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8170 0 : state.dataSurfaceGeometry->kivaManager.surfaceMap[SurfNum].results.Tconv - Constant::Kelvin;
8171 :
8172 0 : TH11 = 0.0;
8173 : }
8174 :
8175 499386 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8176 :
8177 : } else { // Movable insulation present
8178 0 : Real64 HMovInsul = state.dataSurface->intMovInsuls(SurfNum).H;
8179 0 : if (construct.SourceSinkPresent) {
8180 :
8181 0 : ShowSevereError(state, "Interior movable insulation is not valid with embedded sources/sinks");
8182 0 : ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
8183 0 : ShowContinueError(state,
8184 0 : format("interior movable insulation {} for a surface with that construction.",
8185 0 : s_mat->materials(state.dataSurface->intMovInsuls(SurfNum).matNum)->Name));
8186 0 : ShowContinueError(state,
8187 : "This is not currently allowed because the heat balance equations do not currently accommodate "
8188 : "this combination.");
8189 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
8190 : }
8191 :
8192 0 : Real64 F1 = HMovInsul / (HMovInsul + HConvIn_surf + DataHeatBalSurface::IterDampConst);
8193 :
8194 0 : state.dataHeatBalSurf->SurfTempIn(SurfNum) =
8195 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
8196 0 : construct.CTFCross[0] * TH11 +
8197 0 : F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
8198 0 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
8199 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
8200 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
8201 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum))) /
8202 0 : (construct.CTFInside[0] + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
8203 :
8204 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8205 0 : (construct.CTFInside[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
8206 0 : HMovInsul * state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) -
8207 0 : state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) - construct.CTFCross[0] * TH11) /
8208 : (HMovInsul);
8209 : // if any mixed heat transfer models in zone, apply limits to CTF result
8210 0 : if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
8211 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8212 0 : max(DataHeatBalSurface::MinSurfaceTempLimit,
8213 0 : min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
8214 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
8215 : }
8216 : }
8217 : }
8218 99881 : }
8219 99881 : for (int SurfNum : HTWindowSurfs) {
8220 0 : auto &surface = state.dataSurface->Surface(SurfNum);
8221 0 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8222 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8223 0 : if (SurfNum != repSurfNum) {
8224 0 : continue;
8225 : }
8226 : }
8227 0 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
8228 0 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // Not const, because storm window may change this
8229 0 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8230 0 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8231 : // Lookup up the TDD:DOME object
8232 0 : int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
8233 0 : int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
8234 : // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
8235 0 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
8236 :
8237 : // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
8238 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
8239 : // = SurfWinQRadSWwinAbs(SurfNum,1)/2.0
8240 0 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
8241 0 : state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
8242 0 : (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
8243 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) + HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
8244 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
8245 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
8246 0 : Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
8247 0 : (Ueff + HConvIn_surf +
8248 : DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
8249 : // solar | Convection from surface to zone air | Net radiant exchange with
8250 : // other zone surfaces | Iterative damping term (for stability) | Current
8251 : // conduction from the outside surface | Coefficient for conduction (current
8252 : // time) | Convection and damping term
8253 0 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8254 :
8255 0 : Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(SurfNum) + Constant::Kelvin));
8256 :
8257 : // fill out report vars for components of Window Heat Gain
8258 0 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) =
8259 0 : HConvIn_surf * surface.Area * (state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(SurfNum));
8260 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
8261 0 : state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
8262 0 : (Sigma_Temp_4 - (state.dataSurface->SurfWinIRfromParentZone(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)));
8263 0 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) =
8264 0 : state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
8265 0 : (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
8266 0 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum);
8267 :
8268 : // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
8269 0 : state.dataSurface->SurfWinHeatGain(SurfNum) =
8270 0 : state.dataSurface->SurfWinTransSolar(SurfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) +
8271 0 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) -
8272 0 : surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum);
8273 : // Net transmitted solar | Convection | IR exchange | IR
8274 : // Zone diffuse interior shortwave reflected back into the TDD
8275 :
8276 : } else { // Regular window
8277 0 : if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
8278 : // Get outside convection coeff for exterior window here to avoid calling
8279 : // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
8280 : // (HeatBalanceSurfaceManager USEing and WindowManager and
8281 : // WindowManager USEing HeatBalanceSurfaceManager)
8282 0 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
8283 0 : auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
8284 0 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
8285 0 : Real64 EmisOut = thisMaterial->AbsorpThermalFront; // Glass outside surface emissivity
8286 0 : DataSurfaces::WinShadingType const shading_flag(state.dataSurface->SurfWinShadingFlag(SurfNum));
8287 0 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
8288 : // Exterior shade in place
8289 0 : int const ConstrNumSh = surface.activeShadedConstruction;
8290 0 : if (ConstrNumSh != 0) {
8291 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
8292 0 : auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
8293 0 : assert(thisMaterial2 != nullptr);
8294 0 : RoughSurf = thisMaterial2->Roughness;
8295 0 : EmisOut = thisMaterial2->AbsorpThermal;
8296 : }
8297 : }
8298 :
8299 : // Get the outside effective emissivity for Equivalent layer model
8300 0 : if (construct.WindowTypeEQL) {
8301 0 : EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
8302 : }
8303 : // Set Exterior Convection Coefficient...
8304 0 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
8305 :
8306 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
8307 :
8308 0 : } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
8309 :
8310 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
8311 : // subroutine)
8312 0 : Convect::InitExtConvCoeff(state,
8313 : SurfNum,
8314 : 0.0,
8315 : RoughSurf,
8316 : EmisOut,
8317 : TH11,
8318 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
8319 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
8320 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
8321 0 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
8322 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
8323 :
8324 0 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
8325 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0; // Reset SurfHcExt because of wetness
8326 : }
8327 :
8328 : } else { // Not Wind exposed
8329 :
8330 : // Calculate exterior heat transfer coefficients for windspeed = 0
8331 0 : Convect::InitExtConvCoeff(state,
8332 : SurfNum,
8333 : 0.0,
8334 : RoughSurf,
8335 : EmisOut,
8336 : TH11,
8337 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum),
8338 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
8339 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
8340 0 : state.dataHeatBalSurf->SurfHAirExt(SurfNum),
8341 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
8342 : }
8343 : } else { // Interior Surface
8344 :
8345 0 : if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
8346 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
8347 : } else {
8348 : // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
8349 : // same
8350 0 : state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
8351 : }
8352 : }
8353 :
8354 : // Following call determines inside surface temperature of glazing, and of
8355 : // frame and/or divider, if present
8356 0 : Window::CalcWindowHeatBalance(
8357 0 : state, SurfNum, state.dataHeatBalSurf->SurfHConvExt(SurfNum), state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TH11);
8358 0 : state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
8359 : }
8360 : }
8361 99881 : } // ...end of inside surface heat balance equation selection
8362 :
8363 699129 : for (int SurfNum : HTSurfs) {
8364 599248 : int const ZoneNum = state.dataSurface->Surface(SurfNum).Zone;
8365 599248 : auto &zone = state.dataHeatBal->Zone(ZoneNum);
8366 599248 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
8367 599248 : Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
8368 599248 : TH12 = state.dataHeatBalSurf->SurfTempIn(SurfNum);
8369 599248 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = TH11; // For reporting
8370 599248 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Dome) {
8371 0 : continue;
8372 : }
8373 599248 : if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8374 : // Tubular daylighting devices are treated as one big object with an effective R value.
8375 : // The outside face temperature of the TDD:DOME and the inside face temperature of the
8376 : // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
8377 : // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
8378 : // and the outside face of the TDD:DIFFUSER for reporting.
8379 :
8380 : // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
8381 0 : int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
8382 0 : state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
8383 0 : state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
8384 :
8385 : // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
8386 : // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
8387 0 : TH11 = state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
8388 0 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
8389 : }
8390 :
8391 599248 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
8392 0 : TestSurfTempCalcHeatBalanceInsideSurf(state, TH12, SurfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
8393 : }
8394 :
8395 99881 : } // ...end of main loops over all surfaces for inside heat balances
8396 :
8397 : // Interzone surface updating: interzone surfaces have other side temperatures
8398 : // which can vary as the simulation iterates through the inside heat
8399 : // balance. This block is intended to "lock" the opposite side (outside)
8400 : // temperatures to the correct value, namely the value calculated by the
8401 : // inside surface heat balance for the other side.
8402 : // assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
8403 : // int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
8404 99881 : for (int SurfNum : IZSurfs) {
8405 0 : int const surfExtBoundCond = state.dataSurface->Surface(SurfNum).ExtBoundCond;
8406 : // Set the outside surface temperature to the inside surface temperature of the interzone pair.
8407 : // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
8408 : // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
8409 : // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
8410 0 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
8411 0 : state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
8412 99881 : }
8413 :
8414 99881 : ++state.dataHeatBal->InsideSurfIterations;
8415 :
8416 : // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
8417 99881 : Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
8418 699129 : for (int SurfNum : HTNonWindowSurfs) {
8419 599248 : MaxDelTemp = max(std::abs(state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfTempInsOld(SurfNum)), MaxDelTemp);
8420 599248 : if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
8421 : // also check all internal nodes as well as surface faces
8422 599172 : MaxDelTemp = max(MaxDelTemp, state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).MaxNodeDelTemp);
8423 : }
8424 99881 : } // ...end of loop to check for convergence
8425 :
8426 99881 : if (!state.dataHeatBal->AnyCondFD) {
8427 19 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) {
8428 8 : Converged = true;
8429 : }
8430 : } else {
8431 99862 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTempCondFD) {
8432 48972 : Converged = true;
8433 : }
8434 :
8435 : // resets relaxation factor to speed up iterations when under-relaxation is not needed.
8436 99862 : if (state.dataHeatBal->InsideSurfIterations <= 1) {
8437 48972 : state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
8438 : }
8439 99862 : if ((state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::IterationsForCondFDRelaxChange) && !Converged) {
8440 : // adjust relaxation factor down, assume large number of iterations is result of instability
8441 492 : state.dataHeatBal->CondFDRelaxFactor *= 0.9;
8442 492 : if (state.dataHeatBal->CondFDRelaxFactor < 0.1) {
8443 400 : state.dataHeatBal->CondFDRelaxFactor = 0.1;
8444 : }
8445 : }
8446 : }
8447 :
8448 : #ifdef EP_Count_Calls
8449 : state.dataTimingsData->NumMaxInsideSurfIterations =
8450 : max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
8451 : #endif
8452 :
8453 99881 : if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) {
8454 0 : Converged = false;
8455 : }
8456 :
8457 99881 : if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
8458 0 : if (!state.dataGlobal->WarmupFlag) {
8459 0 : ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
8460 0 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
8461 0 : if (!state.dataHeatBal->AnyCondFD) {
8462 0 : ShowWarningError(state,
8463 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
8464 : "Allowed Temp Diff [C] ={:.3R}",
8465 : MaxDelTemp,
8466 0 : state.dataHeatBal->MaxAllowedDelTemp));
8467 0 : ShowContinueErrorTimeStamp(state, "");
8468 : } else {
8469 0 : ShowWarningError(state,
8470 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
8471 : "Allowed Temp Diff [C] ={:.6R}",
8472 : MaxDelTemp,
8473 0 : state.dataHeatBal->MaxAllowedDelTempCondFD));
8474 0 : ShowContinueErrorTimeStamp(state, "");
8475 : }
8476 : } else {
8477 0 : ShowRecurringWarningErrorAtEnd(state,
8478 : "Inside surface heat balance convergence problem continues",
8479 0 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
8480 : MaxDelTemp,
8481 : MaxDelTemp,
8482 : _,
8483 : "[C]",
8484 : "[C]");
8485 : }
8486 : }
8487 0 : break; // iteration loop
8488 : }
8489 :
8490 : } // ...end of main inside heat balance DO loop (ends when Converged)
8491 :
8492 : // Update SumHmXXXX for non-window EMPD or HAMT surfaces
8493 48980 : if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
8494 :
8495 : // these SumHmA* variables are only used for EMPD and HAMT and should be reset each time step (and every iteration)
8496 0 : for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
8497 0 : thisZoneHB.SumHmAW = 0.0;
8498 0 : thisZoneHB.SumHmARa = 0.0;
8499 0 : thisZoneHB.SumHmARaW = 0.0;
8500 0 : }
8501 :
8502 0 : for (int SurfNum : HTNonWindowSurfs) {
8503 0 : auto const &surface = state.dataSurface->Surface(SurfNum);
8504 0 : int ZoneNum = surface.Zone;
8505 0 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
8506 :
8507 0 : if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
8508 0 : HeatBalanceHAMTManager::UpdateHeatBalHAMT(state, SurfNum);
8509 :
8510 0 : Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
8511 :
8512 0 : thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
8513 :
8514 0 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).MAT);
8515 0 : RhoAirZone = Psychrometrics::PsyRhoAirFnPbTdbW(
8516 : state,
8517 0 : state.dataEnvrn->OutBaroPress,
8518 : MAT_zone,
8519 0 : Psychrometrics::PsyWFnTdbRhPb(
8520 : state,
8521 : MAT_zone,
8522 0 : Psychrometrics::PsyRhFnTdbRhov(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum), rhoAirZone),
8523 0 : state.dataEnvrn->OutBaroPress));
8524 :
8525 0 : Real64 const surfInTemp(state.dataHeatBalSurf->SurfTempInTmp(SurfNum));
8526 : Wsurf =
8527 0 : Psychrometrics::PsyWFnTdbRhPb(state,
8528 : surfInTemp,
8529 0 : Psychrometrics::PsyRhFnTdbRhov(state, surfInTemp, state.dataMstBal->RhoVaporSurfIn(SurfNum), wsurf),
8530 0 : state.dataEnvrn->OutBaroPress);
8531 :
8532 0 : thisZoneHB.SumHmARa += FD_Area_fac * RhoAirZone;
8533 :
8534 0 : thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); // old eq'n: FD_Area_fac * RhoAirZone * Wsurf;
8535 :
8536 0 : } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
8537 : // need to calculate the amount of moisture that is entering or
8538 : // leaving the zone Qm [kg/sec] = hmi * Area * (Del Rhov)
8539 : // {Hmi [m/sec]; Area [m2]; Rhov [kg moist/m3] }
8540 : // Positive values are into the zone and negative values are
8541 : // leaving the zone. SumHmAw is the sum of the moisture entering or
8542 : // leaving the zone from all of the surfaces and is a rate. Multiply
8543 : // by time to get the actual amount affecting the zone volume of air.
8544 :
8545 0 : MoistureBalanceEMPDManager::UpdateMoistureBalanceEMPD(state, SurfNum);
8546 0 : state.dataMstBal->RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum);
8547 0 : Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
8548 0 : thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
8549 0 : Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
8550 0 : thisZoneHB.SumHmARa +=
8551 0 : FD_Area_fac *
8552 0 : Psychrometrics::PsyRhoAirFnPbTdbW(
8553 : state,
8554 0 : state.dataEnvrn->OutBaroPress,
8555 : MAT_zone,
8556 0 : Psychrometrics::PsyWFnTdbRhPb(state,
8557 : MAT_zone,
8558 0 : Psychrometrics::PsyRhFnTdbRhovLBnd0C(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum)),
8559 0 : state.dataEnvrn->OutBaroPress)); // surfInTemp, PsyWFnTdbRhPb( surfInTemp, PsyRhFnTdbRhovLBnd0C(
8560 : // surfInTemp, RhoVaporAirIn( SurfNum ) ), OutBaroPress ) );
8561 0 : thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum);
8562 : }
8563 0 : }
8564 : }
8565 48980 : }
8566 :
8567 200983 : void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state,
8568 : const int FirstZone, // First zone to simulate
8569 : const int LastZone, // Last zone to simulate
8570 : const std::vector<int> &IZSurfs, // Last zone to simulate
8571 : ObjexxFCL::Optional_int_const ZoneToResimulate)
8572 : {
8573 :
8574 : // This function performs a heat balance on the inside face of each
8575 : // surface in the building. It is a copy of CalcHeatBalanceInsideSurf,
8576 : // simplified for CTF surfaces only.
8577 :
8578 : // REFERENCES:
8579 : // (I)BLAST legacy routine HBSRF
8580 :
8581 200983 : auto &s_mat = state.dataMaterial;
8582 200983 : auto &Surface = state.dataSurface->Surface;
8583 :
8584 200983 : constexpr std::string_view Inside("Inside");
8585 :
8586 200983 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime) {
8587 : // Set up coefficient arrays that never change - loop over non-window HT surfaces
8588 231 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8589 269 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8590 143 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8591 143 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8592 143 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8593 851 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8594 708 : int const ConstrNum = Surface(surfNum).Construction;
8595 708 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8596 708 : if (Surface(surfNum).ExtBoundCond == surfNum) {
8597 143 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 1;
8598 : } else {
8599 565 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 0;
8600 : }
8601 708 : if (construct.SourceSinkPresent) {
8602 0 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 1;
8603 : } else {
8604 708 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 0;
8605 : }
8606 : }
8607 126 : }
8608 : }
8609 :
8610 105 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime = false;
8611 : }
8612 :
8613 488661 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8614 608967 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8615 321289 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8616 : // loop over all heat transfer surface except TDD Dome.
8617 321289 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
8618 321289 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
8619 : // determine reference air temperatures and other variable terms - loop over all surfaces
8620 2096362 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8621 1775073 : auto const &surface = Surface(surfNum);
8622 1775073 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8623 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8624 0 : if (surfNum != repSurfNum) {
8625 0 : continue;
8626 : }
8627 : }
8628 :
8629 1775073 : int const ConstrNum = Surface(surfNum).Construction;
8630 1775073 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8631 1775073 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) = construct.CTFCross[0];
8632 1775073 : state.dataHeatBalSurf->SurfCTFInside0(surfNum) = construct.CTFInside[0];
8633 1775073 : state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) = construct.CTFSourceIn[0];
8634 1775073 : state.dataHeatBalSurf->SurfTempOutHist(surfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
8635 1775073 : if (construct.SourceSinkPresent) {
8636 0 : state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) = state.dataHeatBalSurf->SurfQsrcHist(surfNum, 1);
8637 : }
8638 :
8639 : // The special heat balance terms for pools are used only when the pool is operating, so IsPool can change
8640 1775073 : if (state.dataSurface->SurfIsPool(surfNum)) {
8641 0 : if ((std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit) ||
8642 0 : (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit)) {
8643 0 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 1;
8644 : } else {
8645 0 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 0;
8646 : }
8647 : }
8648 1775073 : Real64 RefAirTemp = state.dataSurface->Surface(surfNum).getInsideAirTemperature(state, surfNum);
8649 1775073 : state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = RefAirTemp;
8650 1775073 : state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(surfNum);
8651 : }
8652 :
8653 : // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
8654 : // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
8655 : // CalcWindowHeatBalance.
8656 : // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
8657 321289 : int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
8658 321289 : int const lastWindowSurf = thisSpace.WindowSurfaceLast;
8659 409851 : for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
8660 88562 : state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
8661 88562 : state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
8662 88562 : state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
8663 88562 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
8664 88562 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
8665 88562 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
8666 88562 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
8667 88562 : state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
8668 88562 : state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
8669 88562 : state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
8670 88562 : state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
8671 88562 : state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
8672 88562 : state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
8673 : }
8674 :
8675 : // Calculate heat extract due to additional heat flux source term as the surface boundary condition
8676 321290 : for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
8677 1 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
8678 1 : state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
8679 321289 : }
8680 :
8681 : // Set up coefficient arrays prior to calculations and precalc terms that do no change during iteration - non-window surfaces
8682 321289 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8683 321289 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8684 321289 : Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
8685 321289 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8686 : // this loop auto-vectorizes
8687 2007800 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8688 1686511 : auto const &surface = Surface(surfNum);
8689 1686511 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8690 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8691 0 : if (surfNum != repSurfNum) {
8692 0 : continue;
8693 : }
8694 : }
8695 :
8696 : // Pre-calculate a few terms before the iteration loop
8697 1686511 : state.dataHeatBalSurf->SurfTempTerm(surfNum) =
8698 1686511 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8699 1686511 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8700 1686511 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8701 1686511 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8702 1686511 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
8703 1686511 : state.dataHeatBalSurf->SurfTempDiv(surfNum) =
8704 1686511 : 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
8705 1686511 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
8706 1686511 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
8707 1686511 : (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant);
8708 : }
8709 287678 : }
8710 : }
8711 :
8712 200983 : state.dataHeatBal->InsideSurfIterations = 0;
8713 200983 : bool Converged = false; // .TRUE. if inside heat balance has converged
8714 978391 : while (!Converged) { // Start of main inside heat balance iteration loop...
8715 :
8716 777408 : state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
8717 :
8718 1554816 : HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
8719 777408 : state.dataHeatBalSurf->SurfTempIn,
8720 777408 : state.dataHeatBal->InsideSurfIterations,
8721 777408 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
8722 : ZoneToResimulate,
8723 : Inside); // Update the radiation balance
8724 :
8725 : // Every 30 iterations, recalculate the inside convection coefficients in case
8726 : // there has been a significant drift in the surface temperatures predicted.
8727 : // This is not fool-proof and it basically means that the outside surface
8728 : // heat balance is in error (potentially) once HConvIn is re-evaluated.
8729 : // The choice of 30 is not significant--just want to do this a couple of
8730 : // times before the iteration limit is hit.
8731 1353833 : if ((state.dataHeatBal->InsideSurfIterations > 0) &&
8732 576425 : (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
8733 139 : Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
8734 : // Since HConvIn has changed re-calculate a few terms - non-window surfaces
8735 313 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8736 348 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8737 174 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8738 174 : int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8739 174 : int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8740 :
8741 174 : Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
8742 174 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8743 : // this loop auto-vectorizes
8744 1258 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8745 1084 : auto const &surface = Surface(surfNum);
8746 1084 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8747 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8748 0 : if (surfNum != repSurfNum) {
8749 0 : continue;
8750 : }
8751 : }
8752 :
8753 1084 : state.dataHeatBalSurf->SurfTempTerm(surfNum) =
8754 1084 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8755 1084 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8756 1084 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8757 1084 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8758 1084 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
8759 1084 : state.dataHeatBalSurf->SurfTempDiv(surfNum) =
8760 1084 : 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
8761 1084 : state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
8762 1084 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
8763 1084 : (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) +
8764 : iterDampConstant);
8765 : }
8766 174 : }
8767 : }
8768 : }
8769 :
8770 : // Loop over non-window surfaces
8771 1924501 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
8772 2388278 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8773 1241185 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
8774 1241185 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
8775 1241185 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
8776 1241185 : Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
8777 : // this loop auto-vectorizes
8778 8024415 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8779 : // Perform heat balance on the inside face of the surface ...
8780 : // The following are possibilities here (this function only does CTF, see CalcHeatBalanceInsideSurf2 for others):
8781 : // (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
8782 : // (b) the surface is adiabatic (a partition), in which case the temperature of both sides are the same
8783 : // (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
8784 : // (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
8785 : // (e) standard opaque surface with movable insulation, special two-part equation
8786 : // In the surface calculation there are the following Algorithm types for opaque surfaces that
8787 : // do not have movable insulation:
8788 : // (a) the regular CTF calc (SolutionAlgo = UseCTF)
8789 : // (b) the EMPD calc (Solutionalgo = UseEMPD)
8790 : // (c) the CondFD calc (SolutionAlgo = UseCondFD)
8791 : // (d) the HAMT calc (solutionalgo = UseHAMT).
8792 :
8793 : // For adiabatic surface:
8794 : // Adiabatic: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] + HConvIn_surf + IterDampConst));
8795 : // Adiabatic: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
8796 : // Ad+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst *
8797 : // SurfTempInsOld(SurfNum)) * TempDiv; Ad+Pool: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] +
8798 : // PoolHeatTransCoefs(SurfNum) + IterDampConst); Ad+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) +
8799 : // QPoolSurfNumerator(SurfNum) + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
8800 :
8801 : // For standard or interzone surface:
8802 : // Standard: TempDiv = (1.0 / (construct.CTFInside(0) + HConvIn_surf + IterDampConst));
8803 : // Standard: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) *
8804 : // TempDiv; Std+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst
8805 : // * SurfTempInsOld(SurfNum)) * TempDiv; Std+Pool: TempDiv = (1.0 / (construct.CTFInside(0) + PoolHeatTransCoefs(SurfNum) +
8806 : // IterDampConst); Std+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + QPoolSurfNumerator(SurfNum) +
8807 : // IterDampConst* SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) * TempDiv;
8808 :
8809 : // Composite with Adiabatic/Source/Pool flags:
8810 : // TempDiv = (1.0 / (construct.CTFInside(0) - SurfIsAdiabatic*construct.CTFCross[0]+
8811 : // SurfIsOperatingPool*PoolHeatTransCoefs(SurfNum) + IsNotPoolSurf*HConvIn_surf + IterDampConst));
8812 : // SurfTempInTmp(SurfNum) = (IsNotPoolSurf*TempTerm + IsSource*construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) +
8813 : // SurfIsOperatingPool*SurfCTFConstInPart(SurfNum) + SurfIsOperatingPool*QPoolSurfNumerator(SurfNum)
8814 : // + IterDampConst * SurfTempInsOld(SurfNum)+
8815 : // IsNotAdiabatic*IsNotSource*construct.CTFCross[0]
8816 : // * TH11) * TempDiv;
8817 :
8818 : // Calculate the current inside surface temperature
8819 6783230 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8820 6783230 : ((!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) *
8821 6783230 : (state.dataHeatBalSurf->SurfTempTerm(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum)) +
8822 6783230 : state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) * state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) *
8823 6783230 : state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) +
8824 6783230 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) +
8825 6783230 : state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum) +
8826 6783230 : iterDampConstant * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
8827 6783230 : (!state.dataHeatBalSurf->SurfIsAdiabatic(surfNum)) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) *
8828 6783230 : state.dataHeatBalSurf->SurfTempOutHist(surfNum)) *
8829 6783230 : state.dataHeatBalSurf->SurfTempDiv(surfNum);
8830 : // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
8831 : // radiation from internal sources | Convection from surface to zone air | Net radiant
8832 : // exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there
8833 : // is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot
8834 : // water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from
8835 : // an electric baseboard heater | Iterative damping term (for stability) | Current
8836 : // conduction from | the outside surface | Coefficient for conduction (current time) |
8837 : // Convection and damping term | Radiation from AFN ducts
8838 :
8839 6783230 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
8840 : }
8841 :
8842 : // Loop over non-window surfaces (includes TubularDaylightingDomes)
8843 8024415 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
8844 6783230 : auto &movInsul = state.dataSurface->intMovInsuls(surfNum);
8845 :
8846 6783230 : bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && movInsul.present;
8847 6783230 : if (movableInsulPresent) { // Movable insulation present, recalc surface temps
8848 0 : Real64 HMovInsul = movInsul.H;
8849 0 : Real64 F1 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvInt(surfNum) + DataHeatBalSurface::IterDampConst);
8850 0 : state.dataHeatBalSurf->SurfTempIn(surfNum) =
8851 0 : (state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
8852 0 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum) +
8853 0 : F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8854 0 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8855 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8856 0 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
8857 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8858 0 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum))) /
8859 0 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
8860 :
8861 0 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8862 0 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum) +
8863 0 : HMovInsul * state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) -
8864 0 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) -
8865 0 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum)) /
8866 : (HMovInsul);
8867 : }
8868 :
8869 6783230 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
8870 0 : if (state.dataConstruction->Construct(Surface(surfNum).Construction).SourceSinkPresent) {
8871 : // Set the appropriate parameters for the radiant system
8872 : // Radiant system does not need the damping coefficient terms (hopefully)
8873 : Real64 const RadSysDiv(1.0 /
8874 0 : (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + state.dataHeatBalSurf->SurfHConvInt(surfNum)));
8875 : Real64 const TempTerm(
8876 0 : state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
8877 0 : state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
8878 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8879 0 : state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8880 0 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8881 0 : (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / state.dataGlobal->TimeStepZoneSec));
8882 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum) =
8883 0 : TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
8884 : // radiation from internal sources | Convection from surface to zone air | Radiant flux
8885 : // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
8886 : // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
8887 : // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
8888 : // sides same temp) | Convection and damping term
8889 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum) =
8890 0 : state.dataHeatBalSurf->SurfCTFCross0(surfNum) * RadSysDiv; // Outside temp=inside temp for a partition |
8891 : // Cond term (both partition sides same temp) |
8892 : // Convection and damping term
8893 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum) =
8894 0 : state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * RadSysDiv; // QTF term for the source | Cond term (both
8895 : // partition sides same temp) | Convection and
8896 : // damping term
8897 :
8898 0 : if (Surface(surfNum).ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
8899 : // The inside coefficients of one side are equal to the outside coefficients of the other side. But,
8900 : // the inside coefficients are set up once the heat balance equation for that side has been calculated.
8901 : // For both sides to actually have been set, we have to wait until we get to the second side in the surface
8902 : // derived type. At that point, both inside coefficient sets have been evaluated.
8903 0 : if (Surface(surfNum).ExtBoundCond <= surfNum) { // Both of the inside coefficients have now been set
8904 0 : int OtherSideSurfNum = Surface(surfNum).ExtBoundCond;
8905 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
8906 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum);
8907 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
8908 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum);
8909 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
8910 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum);
8911 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(surfNum) =
8912 0 : state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
8913 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(surfNum) =
8914 0 : state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
8915 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(surfNum) =
8916 0 : state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
8917 : }
8918 : }
8919 : }
8920 : }
8921 : }
8922 :
8923 : // Loop over window surfaces
8924 1241185 : int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
8925 1241185 : int const lastWindowSurf = thisSpace.WindowSurfaceLast;
8926 1620943 : for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
8927 379758 : auto &surface = state.dataSurface->Surface(surfNum);
8928 379758 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8929 0 : int repSurfNum = surface.RepresentativeCalcSurfNum;
8930 0 : if (surfNum != repSurfNum) {
8931 0 : continue;
8932 : }
8933 : }
8934 379758 : Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum));
8935 379758 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(surfNum);
8936 379758 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
8937 379758 : if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
8938 : // Lookup up the TDD:DOME object
8939 2 : int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
8940 2 : int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
8941 : // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
8942 2 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
8943 :
8944 : // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
8945 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
8946 : // = SurfWinQRadSWwinAbs(surfNum,1)/2.0
8947 2 : Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surfNum));
8948 2 : state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
8949 2 : (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, 1) / 2.0 +
8950 2 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
8951 2 : HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
8952 2 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
8953 2 : DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
8954 2 : Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
8955 2 : (Ueff + HConvIn_surf +
8956 : DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
8957 : // solar | Convection from surface to zone air | Net radiant exchange with
8958 : // other zone surfaces | Iterative damping term (for stability) | Current
8959 : // conduction from the outside surface | Coefficient for conduction (current
8960 : // time) | Convection and damping term
8961 2 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
8962 2 : Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(surfNum) + Constant::Kelvin));
8963 :
8964 : // fill out report vars for components of Window Heat Gain
8965 2 : state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
8966 4 : HConvIn_surf * surface.Area *
8967 2 : (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
8968 2 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
8969 2 : state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
8970 2 : (Sigma_Temp_4 -
8971 2 : (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum)));
8972 2 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
8973 2 : state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
8974 2 : (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
8975 2 : state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(surfNum);
8976 :
8977 : // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
8978 2 : state.dataSurface->SurfWinHeatGain(surfNum) =
8979 2 : state.dataSurface->SurfWinTransSolar(surfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) +
8980 2 : state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) -
8981 2 : surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum);
8982 : // Net transmitted solar | Convection | IR exchange | IR
8983 : // Zone diffuse interior shortwave reflected back into the TDD
8984 : } else { // Regular window
8985 379756 : if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
8986 : // Get outside convection coeff for exterior window here to avoid calling
8987 : // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
8988 : // (HeatBalanceSurfaceManager USEing and WindowManager and
8989 : // WindowManager USEing HeatBalanceSurfaceManager)
8990 88560 : if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
8991 88560 : auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
8992 88560 : assert(thisMaterial != nullptr);
8993 88560 : Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
8994 88560 : Real64 EmisOut = thisMaterial->AbsorpThermalFront; // Glass outside surface emissivity
8995 88560 : DataSurfaces::WinShadingType const shading_flag = state.dataSurface->SurfWinShadingFlag(surfNum);
8996 88560 : if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
8997 : // Exterior shade in place
8998 0 : int const ConstrNumSh = Surface(surfNum).activeShadedConstruction;
8999 0 : if (ConstrNumSh != 0) {
9000 0 : auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
9001 0 : auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
9002 0 : RoughSurf = thisMaterial2->Roughness;
9003 0 : EmisOut = thisMaterial2->AbsorpThermal;
9004 : }
9005 : }
9006 :
9007 : // Get the outside effective emissivity for Equivalent layer model
9008 88560 : if (construct.WindowTypeEQL) {
9009 2367 : EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
9010 : }
9011 : // Set Exterior Convection Coefficient...
9012 88560 : if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
9013 :
9014 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
9015 :
9016 88560 : } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
9017 :
9018 : // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
9019 : // subroutine)
9020 88560 : Convect::InitExtConvCoeff(state,
9021 : surfNum,
9022 : 0.0,
9023 : RoughSurf,
9024 : EmisOut,
9025 : TH11,
9026 88560 : state.dataHeatBalSurf->SurfHConvExt(surfNum),
9027 88560 : state.dataHeatBalSurf->SurfHSkyExt(surfNum),
9028 88560 : state.dataHeatBalSurf->SurfHGrdExt(surfNum),
9029 88560 : state.dataHeatBalSurf->SurfHAirExt(surfNum),
9030 88560 : state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
9031 :
9032 88560 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
9033 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = 1000.0; // Reset SurfHcExt because of wetness
9034 : }
9035 :
9036 : } else { // Not Wind exposed
9037 :
9038 : // Calculate exterior heat transfer coefficients for windspeed = 0
9039 0 : Convect::InitExtConvCoeff(state,
9040 : surfNum,
9041 : 0.0,
9042 : RoughSurf,
9043 : EmisOut,
9044 : TH11,
9045 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum),
9046 0 : state.dataHeatBalSurf->SurfHSkyExt(surfNum),
9047 0 : state.dataHeatBalSurf->SurfHGrdExt(surfNum),
9048 0 : state.dataHeatBalSurf->SurfHAirExt(surfNum),
9049 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
9050 : }
9051 :
9052 : } else { // Interior Surface
9053 :
9054 0 : if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
9055 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
9056 : } else {
9057 : // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
9058 : // same
9059 0 : state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
9060 : }
9061 : }
9062 :
9063 : // Following call determines inside surface temperature of glazing, and of
9064 : // frame and/or divider, if present
9065 88560 : Window::CalcWindowHeatBalance(
9066 88560 : state, surfNum, state.dataHeatBalSurf->SurfHConvExt(surfNum), state.dataHeatBalSurf->SurfTempInTmp(surfNum), TH11);
9067 88560 : state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
9068 : }
9069 : }
9070 : }
9071 :
9072 1241185 : int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
9073 1241185 : int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
9074 8404173 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
9075 7162988 : auto &zone = state.dataHeatBal->Zone(zoneNum);
9076 :
9077 7162988 : Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
9078 7162988 : Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(surfNum);
9079 7162988 : TH12 = state.dataHeatBalSurf->SurfTempIn(surfNum);
9080 7162988 : state.dataHeatBalSurf->SurfTempOut(surfNum) = TH11; // For reporting
9081 7162988 : if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
9082 : // Tubular daylighting devices are treated as one big object with an effective R value.
9083 : // The outside face temperature of the TDD:DOME and the inside face temperature of the
9084 : // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
9085 : // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
9086 : // and the outside face of the TDD:DIFFUSER for reporting.
9087 :
9088 : // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
9089 2 : int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(surfNum)).Dome;
9090 2 : state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
9091 2 : state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(surfNum);
9092 :
9093 : // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
9094 : // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
9095 2 : TH11 = state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
9096 2 : state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
9097 : }
9098 :
9099 7162988 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
9100 0 : TestSurfTempCalcHeatBalanceInsideSurf(
9101 0 : state, TH12, surfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
9102 : }
9103 : }
9104 1147093 : }
9105 : } // ...end of main loops over all surfaces for inside heat balances
9106 :
9107 : // Interzone surface updating: interzone surfaces have other side temperatures
9108 : // which can vary as the simulation iterates through the inside heat
9109 : // balance. This block is intended to "lock" the opposite side (outside)
9110 : // temperatures to the correct value, namely the value calculated by the
9111 : // inside surface heat balance for the other side.
9112 : // assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
9113 : // int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
9114 1532122 : for (int SurfNum : IZSurfs) {
9115 754714 : int const surfExtBoundCond = Surface(SurfNum).ExtBoundCond;
9116 : // Set the outside surface temperature to the inside surface temperature of the interzone pair.
9117 : // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
9118 : // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
9119 : // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
9120 754714 : state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
9121 754714 : state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
9122 754714 : state.dataHeatBalSurf->SurfTempOutHist(SurfNum) = state.dataHeatBalSurf->SurfTempOut(SurfNum);
9123 777408 : }
9124 :
9125 777408 : ++state.dataHeatBal->InsideSurfIterations;
9126 :
9127 : // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
9128 777408 : Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
9129 1924501 : for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
9130 2388278 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
9131 1241185 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
9132 1241185 : int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
9133 1241185 : int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
9134 8024415 : for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
9135 6783230 : Real64 delta = state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfTempInsOld(surfNum);
9136 6783230 : Real64 absDif = std::abs(delta);
9137 6783230 : MaxDelTemp = std::max(absDif, MaxDelTemp);
9138 : }
9139 1147093 : }
9140 : } // ...end of loop to check for convergence
9141 :
9142 777408 : if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) {
9143 200983 : Converged = true;
9144 : }
9145 :
9146 : #ifdef EP_Count_Calls
9147 : state.dataTimingsData->NumMaxInsideSurfIterations =
9148 : max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
9149 : #endif
9150 :
9151 777408 : if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) {
9152 0 : Converged = false;
9153 : }
9154 :
9155 777408 : if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
9156 0 : if (!state.dataGlobal->WarmupFlag) {
9157 0 : ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
9158 0 : if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
9159 0 : ShowWarningError(state,
9160 0 : format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max Allowed "
9161 : "Temp Diff [C] ={:.6R}",
9162 : MaxDelTemp,
9163 0 : state.dataHeatBal->MaxAllowedDelTempCondFD));
9164 0 : ShowContinueErrorTimeStamp(state, "");
9165 : } else {
9166 0 : ShowRecurringWarningErrorAtEnd(state,
9167 : "Inside surface heat balance convergence problem continues",
9168 0 : state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
9169 : MaxDelTemp,
9170 : MaxDelTemp,
9171 : _,
9172 : "[C]",
9173 : "[C]");
9174 : }
9175 : }
9176 0 : break; // iteration loop
9177 : }
9178 :
9179 : } // ...end of main inside heat balance iteration loop (ends when Converged)
9180 200983 : }
9181 :
9182 249963 : void sumSurfQdotRadHVAC(EnergyPlusData &state)
9183 : {
9184 249999 : for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
9185 36 : auto const &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
9186 36 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = thisSurfQRadFromHVAC.HTRadSys + thisSurfQRadFromHVAC.HWBaseboard +
9187 36 : thisSurfQRadFromHVAC.SteamBaseboard + thisSurfQRadFromHVAC.ElecBaseboard +
9188 36 : thisSurfQRadFromHVAC.CoolingPanel;
9189 249963 : }
9190 249963 : }
9191 :
9192 5 : void TestSurfTempCalcHeatBalanceInsideSurf(EnergyPlusData &state, Real64 TH12, int const SurfNum, DataHeatBalance::ZoneData &zone, int WarmupSurfTemp)
9193 : {
9194 5 : std::string surfName = state.dataSurface->Surface(SurfNum).Name;
9195 :
9196 5 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
9197 4 : if (state.dataGlobal->WarmupFlag) {
9198 0 : ++WarmupSurfTemp;
9199 : }
9200 4 : if (!state.dataGlobal->WarmupFlag || WarmupSurfTemp > 10 || state.dataGlobal->DisplayExtraWarnings) {
9201 4 : if (TH12 < DataHeatBalSurface::MinSurfaceTempLimit) {
9202 2 : if (state.dataSurface->SurfLowTempErrCount(SurfNum) == 0) {
9203 4 : ShowSevereMessage(
9204 4 : state, format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9205 4 : ShowContinueErrorTimeStamp(state, "");
9206 2 : if (!zone.TempOutOfBoundsReported) {
9207 1 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9208 1 : if (zone.FloorArea > 0.0) {
9209 1 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9210 : } else {
9211 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
9212 : }
9213 1 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9214 1 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9215 1 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9216 : } else {
9217 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9218 : }
9219 1 : if (zone.IsControlled) {
9220 3 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9221 : } else {
9222 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9223 : }
9224 1 : zone.TempOutOfBoundsReported = true;
9225 : }
9226 18 : ShowRecurringSevereErrorAtEnd(state,
9227 4 : "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9228 2 : state.dataSurface->SurfLowTempErrCount(SurfNum),
9229 : TH12,
9230 : TH12,
9231 : _,
9232 : "C",
9233 : "C");
9234 : } else {
9235 0 : ShowRecurringSevereErrorAtEnd(state,
9236 0 : "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9237 0 : state.dataSurface->SurfLowTempErrCount(SurfNum),
9238 : TH12,
9239 : TH12,
9240 : _,
9241 : "C",
9242 : "C");
9243 : }
9244 : } else {
9245 2 : if (state.dataSurface->SurfHighTempErrCount(SurfNum) == 0) {
9246 4 : ShowSevereMessage(
9247 4 : state, format(R"(Temperature (high) out of bounds ({:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9248 4 : ShowContinueErrorTimeStamp(state, "");
9249 2 : if (!zone.TempOutOfBoundsReported) {
9250 1 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9251 1 : if (zone.FloorArea > 0.0) {
9252 1 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9253 : } else {
9254 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
9255 : }
9256 1 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9257 1 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9258 1 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9259 : } else {
9260 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9261 : }
9262 1 : if (zone.IsControlled) {
9263 3 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9264 : } else {
9265 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9266 : }
9267 1 : zone.TempOutOfBoundsReported = true;
9268 : }
9269 18 : ShowRecurringSevereErrorAtEnd(state,
9270 4 : "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9271 2 : state.dataSurface->SurfHighTempErrCount(SurfNum),
9272 : TH12,
9273 : TH12,
9274 : _,
9275 : "C",
9276 : "C");
9277 : } else {
9278 0 : ShowRecurringSevereErrorAtEnd(state,
9279 0 : "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
9280 0 : state.dataSurface->SurfHighTempErrCount(SurfNum),
9281 : TH12,
9282 : TH12,
9283 : _,
9284 : "C",
9285 : "C");
9286 : }
9287 : }
9288 4 : if (zone.EnforcedReciprocity) {
9289 0 : if (WarmupSurfTemp > 3) {
9290 0 : ShowSevereError(state, format("CalcHeatBalanceInsideSurf: Zone=\"{}\" has view factor enforced reciprocity", zone.Name));
9291 0 : ShowContinueError(state, " and is having temperature out of bounds errors. Please correct zone geometry and rerun.");
9292 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
9293 : }
9294 4 : } else if (WarmupSurfTemp > 10) {
9295 0 : ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
9296 : }
9297 : }
9298 : }
9299 5 : if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal)) {
9300 0 : if (!state.dataGlobal->WarmupFlag) {
9301 0 : if (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal) {
9302 0 : ShowSevereError(state,
9303 0 : format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9304 0 : ShowContinueErrorTimeStamp(state, "");
9305 0 : if (!zone.TempOutOfBoundsReported) {
9306 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9307 0 : if (zone.FloorArea > 0.0) {
9308 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9309 : } else {
9310 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
9311 : }
9312 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9313 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9314 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9315 : } else {
9316 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9317 : }
9318 0 : if (zone.IsControlled) {
9319 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9320 : } else {
9321 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9322 : }
9323 0 : zone.TempOutOfBoundsReported = true;
9324 : }
9325 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9326 : } else {
9327 0 : ShowSevereError(state,
9328 0 : format(R"(Temperature (high) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9329 0 : ShowContinueErrorTimeStamp(state, "");
9330 0 : if (!zone.TempOutOfBoundsReported) {
9331 0 : ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
9332 0 : if (zone.FloorArea > 0.0) {
9333 0 : ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
9334 : } else {
9335 0 : ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
9336 : }
9337 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
9338 0 : ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
9339 0 : ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
9340 : } else {
9341 0 : ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
9342 : }
9343 0 : if (zone.IsControlled) {
9344 0 : ShowContinueError(state, "...Zone is part of HVAC controlled system.");
9345 : } else {
9346 0 : ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
9347 : }
9348 0 : zone.TempOutOfBoundsReported = true;
9349 : }
9350 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9351 : }
9352 : } else {
9353 0 : if (TH12 < -10000. || TH12 > 10000.) {
9354 0 : ShowSevereError(
9355 : state,
9356 0 : format(R"(CalcHeatBalanceInsideSurf: The temperature of {:.2R} C for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
9357 0 : ShowContinueError(state, "..is very far out of bounds during warmup. This may be an indication of a malformed zone.");
9358 0 : ShowContinueErrorTimeStamp(state, "");
9359 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
9360 : }
9361 : }
9362 : }
9363 5 : }
9364 :
9365 1051053 : void CalcOutsideSurfTemp(EnergyPlusData &state,
9366 : int const SurfNum, // Surface number DO loop counter
9367 : int const spaceNum, // Space number the current surface is attached to
9368 : int const ConstrNum, // Construction index for the current surface
9369 : Real64 const HMovInsul, // "Convection" coefficient of movable insulation
9370 : Real64 const TempExt, // Exterior temperature boundary condition
9371 : bool &ErrorFlag // Error flag for movable insulation problem
9372 : )
9373 : {
9374 :
9375 : // SUBROUTINE INFORMATION:
9376 : // AUTHOR George Walton
9377 : // DATE WRITTEN December 1979
9378 : // MODIFIED Jun 1990 (RDT for new CTF arrays)
9379 : // Jul 2000 (RJL for Moisture algorithms)
9380 : // Sep 2000 (RKS for new radiant exchange algorithm)
9381 : // Dec 2000 (RKS for radiant system model addition)
9382 : // Aug 2010 (BG added radiant heat flow rate reporting)
9383 : // RE-ENGINEERED Mar 1998 (RKS)
9384 :
9385 : // PURPOSE OF THIS SUBROUTINE:
9386 : // This subroutine performs a heat balance on the outside face of each
9387 : // surface in the building. NOTE that this also sets some coefficients
9388 : // that are needed for radiant system modeling. Thus, it is extremely
9389 : // important that if someone makes changes to the heat balance equations
9390 : // at a later date that they must also make changes to the coefficient
9391 : // setting portion of this subroutine as well.
9392 :
9393 : // METHODOLOGY EMPLOYED:
9394 : // Various boundary conditions are set and additional parameters are set-
9395 : // up. Then, the proper heat balance equation is selected based on the
9396 : // presence of movable insulation, thermal mass of the surface construction,
9397 : // and convection model being used.
9398 :
9399 : // REFERENCES:
9400 : // (I)BLAST legacy routine HBOUT
9401 : // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
9402 :
9403 : // Determine whether or not movable insulation is present
9404 1051053 : bool MovInsulPresent = (HMovInsul > 0.0); // .TRUE. if movable insulation is currently present for surface
9405 : bool QuickConductionSurf; // .TRUE. if the cross CTF term is relatively large
9406 : Real64 F1; // Intermediate calculation variable
9407 : Real64 F2; // Intermediate calculation variable
9408 : // Determine whether this surface is a "slow conductive" or "quick conductive"
9409 : // surface. Designates are inherited from BLAST. Basically, a "quick" surface
9410 : // requires the inside heat balance to be accounted for in the heat balance
9411 : // while a "slow" surface can used the last time step's value for inside
9412 : // surface temperature.
9413 1051053 : auto &s_mat = state.dataMaterial;
9414 :
9415 1051053 : auto &surface = state.dataSurface->Surface(SurfNum);
9416 1051053 : auto const &construct = state.dataConstruction->Construct(ConstrNum);
9417 1051053 : if (construct.CTFCross[0] > 0.01) {
9418 709122 : QuickConductionSurf = true;
9419 709122 : F1 = construct.CTFCross[0] / (construct.CTFInside[0] + state.dataHeatBalSurf->SurfHConvInt(SurfNum));
9420 : } else {
9421 341931 : QuickConductionSurf = false;
9422 : }
9423 :
9424 1051053 : Real64 TSky = state.dataEnvrn->SkyTemp;
9425 1051053 : Real64 TGround = state.dataEnvrn->OutDryBulbTemp;
9426 1051053 : Real64 TSrdSurfs = 0.0;
9427 :
9428 1051053 : if (surface.SurfHasSurroundingSurfProperty) {
9429 6 : int SrdSurfsNum = surface.SurfSurroundingSurfacesNum;
9430 6 : if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched != nullptr) {
9431 3 : TSky = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched->getCurrentVal();
9432 : }
9433 6 : if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched != nullptr) {
9434 1 : TGround = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched->getCurrentVal();
9435 : }
9436 6 : TSrdSurfs = state.dataSurface->Surface(SurfNum).SrdSurfTemp;
9437 : }
9438 1051053 : if (surface.UseSurfPropertyGndSurfTemp) {
9439 3 : TGround = state.dataSurface->GroundSurfsProperty(surface.SurfPropertyGndSurfIndex).SurfsTempAvg;
9440 : }
9441 :
9442 : // Now, calculate the outside surface temperature using the proper heat balance equation.
9443 : // Each case has been separated out into its own IF-THEN block for clarity. Additional
9444 : // cases can simply be added anywhere in the following section. This is the last step
9445 : // in the main loop. Once the proper heat balance is done, the simulation goes on to
9446 : // the next SurfNum.
9447 :
9448 : // Outside heat balance case: Tubular daylighting device
9449 1051053 : Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum));
9450 1051053 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
9451 :
9452 : // Lookup up the TDD:DIFFUSER object
9453 0 : int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
9454 0 : int SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser;
9455 0 : int spaceNum2 = state.dataSurface->Surface(SurfNum2).spaceNum;
9456 0 : Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(PipeNum).Reff; // 1 / effective R value between TDD:DOME and TDD:DIFFUSER
9457 0 : F1 = Ueff / (Ueff + state.dataHeatBalSurf->SurfHConvInt(SurfNum2));
9458 :
9459 : // Similar to opaque surface but inside conditions of TDD:DIFFUSER are used, and no embedded sources/sinks.
9460 : // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
9461 : // SurfOpaqQRadSWOutAbs(SurfNum) does not apply for TDD:DOME, must use SurfWinQRadSWwinAbs(SurfNum,1)/2.0 instead.
9462 : //+Construct(ConstrNum)%CTFSourceOut[0] & TDDs cannot be radiant systems
9463 : // *SurfQsrcHist(1,SurfNum) &
9464 : //+Construct(ConstrNum)%CTFSourceIn[0] & TDDs cannot be radiant systems
9465 : // *SurfQsrcHist(1,SurfNum) &
9466 0 : TH11 = (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
9467 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9468 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) +
9469 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9470 0 : F1 * (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum2, 1) / 2.0 + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum2) +
9471 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum2) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum2).MAT +
9472 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum2))) /
9473 0 : (Ueff + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9474 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9475 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9476 0 : F1 * Ueff); // Instead of SurfOpaqQRadSWOutAbs(SurfNum) | ODB used to approx ground surface temp | Use TDD:DIFFUSER surface | Use
9477 : // TDD:DIFFUSER surface | Use TDD:DIFFUSER surface and zone | Use TDD:DIFFUSER surface
9478 :
9479 : // Outside heat balance case: No movable insulation, slow conduction
9480 1051053 : } else if ((!MovInsulPresent) && (!QuickConductionSurf)) {
9481 : // Add LWR from surrounding surfaces
9482 341930 : if (surface.OSCMPtr == 0) {
9483 341930 : if (construct.SourceSinkPresent) {
9484 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9485 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9486 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9487 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9488 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9489 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
9490 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9491 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9492 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
9493 : } else {
9494 341930 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9495 341930 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9496 341930 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9497 341930 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9498 341930 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
9499 341930 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9500 341930 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9501 341930 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
9502 : }
9503 : // Outside Heat Balance case: Other Side Conditions Model
9504 : } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
9505 : // local copies of variables for clarity in radiation terms
9506 : // TODO: - int OSCMPtr; // "Pointer" to OSCM data structure (other side conditions from a model)
9507 : Real64 RadTemp =
9508 0 : state.dataSurface->OSCM(surface.OSCMPtr).TRad; // local value for Effective radiation temperature for OtherSideConditions model
9509 0 : Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad; // local value for effective (linearized) radiation coefficient
9510 :
9511 : // patterned after "No movable insulation, slow conduction," but with new radiation terms and no sun,
9512 0 : if (construct.SourceSinkPresent) {
9513 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9514 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9515 0 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9516 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
9517 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
9518 : } else {
9519 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9520 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9521 0 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
9522 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
9523 : }
9524 : }
9525 : // Outside heat balance case: No movable insulation, quick conduction
9526 1051053 : } else if ((!MovInsulPresent) && (QuickConductionSurf)) {
9527 709122 : if (surface.OSCMPtr == 0) {
9528 709122 : if (construct.SourceSinkPresent) {
9529 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9530 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9531 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9532 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9533 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9534 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9535 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9536 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9537 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9538 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9539 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9540 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9541 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9542 0 : F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
9543 : } else {
9544 709122 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9545 709122 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9546 709122 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9547 709122 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9548 709122 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
9549 709122 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9550 709122 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9551 709122 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9552 709122 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9553 709122 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9554 709122 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9555 709122 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
9556 709122 : F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
9557 : }
9558 : // Outside Heat Balance case: Other Side Conditions Model
9559 : } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
9560 : // local copies of variables for clarity in radiation terms
9561 0 : Real64 RadTemp = state.dataSurface->OSCM(surface.OSCMPtr).TRad;
9562 0 : Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad;
9563 : // patterned after "No movable insulation, quick conduction," but with new radiation terms and no sun,
9564 0 : if (construct.SourceSinkPresent) {
9565 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9566 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9567 0 : construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9568 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9569 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9570 0 : construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
9571 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9572 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
9573 0 : (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
9574 0 : F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
9575 : } else {
9576 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
9577 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
9578 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9579 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
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 : }
9585 : }
9586 : // Outside heat balance case: Movable insulation, slow conduction
9587 709123 : } else if ((MovInsulPresent) && (!QuickConductionSurf)) {
9588 :
9589 1 : F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9590 1 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9591 1 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
9592 :
9593 1 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9594 1 : construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
9595 1 : F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
9596 1 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9597 1 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9598 1 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
9599 1 : (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul); // ODB used to approx ground surface temp
9600 :
9601 : // Outside heat balance case: Movable insulation, quick conduction
9602 0 : } else if ((MovInsulPresent) && (QuickConductionSurf)) {
9603 :
9604 0 : F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
9605 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
9606 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
9607 :
9608 0 : TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9609 0 : F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
9610 0 : state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
9611 0 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
9612 0 : state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)) +
9613 0 : F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
9614 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9615 0 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
9616 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
9617 0 : (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul - F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp
9618 :
9619 : } // ...end of outside heat balance cases IF-THEN block
9620 :
9621 : // multiply out linearized radiation coeffs for reporting
9622 : Real64 const HExtSurf_fac(
9623 1051053 : -(state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * (TH11 - TSky) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) * (TH11 - TempExt) +
9624 1051053 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * (TH11 - TGround) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * (TH11 - TSrdSurfs)));
9625 1051053 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = HExtSurf_fac;
9626 :
9627 : // Set the radiant system heat balance coefficients if this surface is also a radiant system
9628 1051053 : if (construct.SourceSinkPresent) {
9629 :
9630 1 : if (MovInsulPresent) {
9631 : // Note: if movable insulation is ever added back in correctly, the heat balance equations above must be fixed
9632 2 : ShowSevereError(state, "Exterior movable insulation is not valid with embedded sources/sinks");
9633 1 : ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
9634 2 : ShowContinueError(state,
9635 2 : format("exterior movable insulation {} for a surface with that construction.",
9636 1 : s_mat->materials(state.dataSurface->extMovInsuls(SurfNum).matNum)->Name));
9637 2 : ShowContinueError(state,
9638 : "This is not currently allowed because the heat balance equations do not currently accommodate this combination.");
9639 1 : ErrorFlag = true;
9640 1 : return;
9641 :
9642 : } else {
9643 0 : Real64 const RadSysDiv(1.0 / (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) +
9644 0 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) +
9645 0 : state.dataHeatBalSurf->SurfHGrdExt(SurfNum) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) +
9646 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)));
9647 :
9648 0 : state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
9649 0 : (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
9650 0 : state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
9651 0 : (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
9652 0 : state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround) *
9653 : RadSysDiv; // ODB used to approx ground surface temp
9654 :
9655 0 : state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = construct.CTFCross[0] * RadSysDiv;
9656 :
9657 0 : state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = construct.CTFSourceOut[0] * RadSysDiv;
9658 : }
9659 : }
9660 : }
9661 :
9662 0 : void CalcExteriorVentedCavity(EnergyPlusData &state, int const SurfNum) // index of surface
9663 : {
9664 :
9665 : // SUBROUTINE INFORMATION:
9666 : // AUTHOR B Griffith
9667 : // DATE WRITTEN January 2005
9668 :
9669 : // PURPOSE OF THIS SUBROUTINE:
9670 : // manages calculating the temperatures of baffle and air cavity for
9671 : // multi-skin configuration.
9672 :
9673 : // METHODOLOGY EMPLOYED:
9674 : // derived from CalcPassiveTranspiredCollector
9675 :
9676 : // local working variables
9677 : Real64 HrPlen;
9678 : Real64 HcPlen;
9679 : Real64 Isc;
9680 : Real64 MdotVent;
9681 : Real64 VdotWind;
9682 : Real64 VdotThermal;
9683 :
9684 0 : int CavNum = state.dataSurface->SurfExtCavNum(SurfNum);
9685 0 : Real64 TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
9686 0 : Real64 OutHumRatExt = Psychrometrics::PsyWFnTdbTwbPb(
9687 0 : state, state.dataSurface->SurfOutDryBulbTemp(SurfNum), state.dataSurface->SurfOutWetBulbTemp(SurfNum), state.dataEnvrn->OutBaroPress);
9688 0 : Real64 RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, OutHumRatExt);
9689 0 : Real64 holeArea = state.dataHeatBal->ExtVentedCavity(CavNum).ActualArea * state.dataHeatBal->ExtVentedCavity(CavNum).Porosity;
9690 : // Aspect Ratio of gap
9691 0 : Real64 AspRat = state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL * 2.0 / state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick;
9692 0 : Real64 TmpTscoll = state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast;
9693 0 : Real64 TmpTaPlen = state.dataHeatBal->ExtVentedCavity(CavNum).TairLast;
9694 :
9695 : // all the work is done in this routine located in GeneralRoutines.cc
9696 :
9697 0 : for (int iter = 1; iter <= 3; ++iter) { // this is a sequential solution approach.
9698 :
9699 0 : TranspiredCollector::CalcPassiveExteriorBaffleGap(state,
9700 0 : state.dataHeatBal->ExtVentedCavity(CavNum).SurfPtrs,
9701 : holeArea,
9702 0 : state.dataHeatBal->ExtVentedCavity(CavNum).Cv,
9703 0 : state.dataHeatBal->ExtVentedCavity(CavNum).Cd,
9704 0 : state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL,
9705 0 : state.dataHeatBal->ExtVentedCavity(CavNum).SolAbsorp,
9706 0 : state.dataHeatBal->ExtVentedCavity(CavNum).LWEmitt,
9707 0 : state.dataHeatBal->ExtVentedCavity(CavNum).Tilt,
9708 : AspRat,
9709 0 : state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick,
9710 0 : state.dataHeatBal->ExtVentedCavity(CavNum).BaffleRoughness,
9711 0 : state.dataHeatBal->ExtVentedCavity(CavNum).QdotSource,
9712 : TmpTscoll,
9713 : TmpTaPlen,
9714 : HcPlen,
9715 : HrPlen,
9716 : Isc,
9717 : MdotVent,
9718 : VdotWind,
9719 : VdotThermal);
9720 :
9721 : } // sequential solution
9722 : // now fill results into derived types
9723 0 : state.dataHeatBal->ExtVentedCavity(CavNum).Isc = Isc;
9724 0 : state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav = TmpTaPlen;
9725 0 : state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle = TmpTscoll;
9726 0 : state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen = HrPlen;
9727 0 : state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen = HcPlen;
9728 0 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveACH =
9729 0 : (MdotVent / RhoAir) *
9730 0 : (1.0 / (state.dataHeatBal->ExtVentedCavity(CavNum).ProjArea * state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick)) *
9731 : Constant::rSecsInHour;
9732 0 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotVent = MdotVent;
9733 0 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotWind = VdotWind * RhoAir;
9734 0 : state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotTherm = VdotThermal * RhoAir;
9735 :
9736 : // now do some updates
9737 0 : state.dataHeatBal->ExtVentedCavity(CavNum).TairLast = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
9738 0 : state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
9739 :
9740 : // update the OtherSideConditionsModel coefficients.
9741 0 : int thisOSCM = state.dataHeatBal->ExtVentedCavity(CavNum).OSCMPtr;
9742 :
9743 0 : state.dataSurface->OSCM(thisOSCM).TConv = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
9744 0 : state.dataSurface->OSCM(thisOSCM).HConv = state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen;
9745 0 : state.dataSurface->OSCM(thisOSCM).TRad = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
9746 0 : state.dataSurface->OSCM(thisOSCM).HRad = state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen;
9747 0 : }
9748 :
9749 83022 : void GatherComponentLoadsSurfAbsFact(EnergyPlusData &state)
9750 : {
9751 : // SUBROUTINE INFORMATION:
9752 : // AUTHOR Jason Glazer
9753 : // DATE WRITTEN September 2012
9754 :
9755 : // PURPOSE OF THIS SUBROUTINE:
9756 : // Gather values during sizing used for surface absorption factors
9757 :
9758 : // METHODOLOGY EMPLOYED:
9759 : // Save sequence of values for report during sizing.
9760 :
9761 : // This is by surface, so it works for both space and zone component loads
9762 83022 : if (state.dataGlobal->CompLoadReportIsReq && !state.dataGlobal->isPulseZoneSizing) {
9763 7452 : int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
9764 7452 : auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
9765 82566 : for (int jSurf = 1; jSurf <= state.dataSurface->TotSurfaces; ++jSurf) {
9766 75114 : auto const &surface = state.dataSurface->Surface(jSurf);
9767 75114 : if (!surface.HeatTransSurf || surface.Zone == 0) {
9768 0 : continue; // Skip non-heat transfer surfaces
9769 : }
9770 75114 : if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
9771 0 : continue; // Skip tubular daylighting device domes
9772 : }
9773 75114 : surfCLDayTS.surf[jSurf - 1].ITABSFseq = state.dataHeatBalSurf->SurfAbsThermalInt(jSurf);
9774 75114 : surfCLDayTS.surf[jSurf - 1].TMULTseq = state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).radThermAbsMult;
9775 : }
9776 : }
9777 83022 : }
9778 :
9779 623650 : Real64 GetSurfIncidentSolarMultiplier(EnergyPlusData &state, int SurfNum)
9780 : {
9781 623650 : if (!state.dataSurface->Surface(SurfNum).hasIncSolMultiplier) {
9782 623648 : return 1.0;
9783 2 : } else if (state.dataSurface->SurfIncSolMultiplier(SurfNum).sched != nullptr) {
9784 0 : return state.dataSurface->SurfIncSolMultiplier(SurfNum).sched->getCurrentVal() * state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
9785 : } else {
9786 2 : return state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
9787 : }
9788 : }
9789 :
9790 116 : void InitSurfacePropertyViewFactors(EnergyPlusData &state)
9791 : {
9792 :
9793 : // purpose:
9794 : // Initializes sky and ground surfaces view factors of exterior surfaces
9795 : // used by SurfaceProperty:LocalEnvironment
9796 : // view factors are constant hence should be set only once
9797 :
9798 116 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9799 108 : return;
9800 : }
9801 8 : if (!state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
9802 0 : return;
9803 : }
9804 :
9805 50 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9806 42 : auto &Surface = state.dataSurface->Surface(SurfNum);
9807 42 : if (Surface.SurfHasSurroundingSurfProperty || Surface.IsSurfPropertyGndSurfacesDefined) {
9808 :
9809 18 : int GndSurfsNum = 0;
9810 18 : int SrdSurfsNum = 0;
9811 18 : Real64 SrdSurfsViewFactor = 0.0;
9812 18 : Real64 SurfsSkyViewFactor = 0.0;
9813 18 : Real64 GroundSurfsViewFactor = 0.0;
9814 18 : bool IsSkyViewFactorSet = false;
9815 18 : bool IsGroundViewFactorSet = false;
9816 18 : bool SetGroundViewFactorObject = false;
9817 18 : if (Surface.SurfHasSurroundingSurfProperty) {
9818 18 : SrdSurfsNum = Surface.SurfSurroundingSurfacesNum;
9819 18 : auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
9820 18 : SurfsSkyViewFactor = SrdSurfsProperty.SkyViewFactor;
9821 18 : IsSkyViewFactorSet = SrdSurfsProperty.IsSkyViewFactorSet;
9822 18 : if (SurfsSkyViewFactor > 0.0) {
9823 12 : SrdSurfsViewFactor += SurfsSkyViewFactor;
9824 : }
9825 18 : if (!Surface.IsSurfPropertyGndSurfacesDefined) {
9826 8 : SrdSurfsViewFactor += SrdSurfsProperty.GroundViewFactor;
9827 8 : IsGroundViewFactorSet = SrdSurfsProperty.IsGroundViewFactorSet;
9828 8 : GroundSurfsViewFactor = SrdSurfsProperty.GroundViewFactor;
9829 : }
9830 46 : for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
9831 28 : SrdSurfsViewFactor += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
9832 : }
9833 : }
9834 18 : if (Surface.IsSurfPropertyGndSurfacesDefined) {
9835 10 : GndSurfsNum = Surface.SurfPropertyGndSurfIndex;
9836 10 : IsGroundViewFactorSet = state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet;
9837 10 : GroundSurfsViewFactor = state.dataSurface->GroundSurfsProperty(GndSurfsNum).SurfsViewFactorSum;
9838 10 : SrdSurfsViewFactor += GroundSurfsViewFactor;
9839 : }
9840 :
9841 : // Check if the sum of all defined view factors > 1.0
9842 18 : if (SrdSurfsViewFactor > 1.0) {
9843 0 : ShowSevereError(state, format("Illegal surrounding surfaces view factors for {}.", Surface.Name));
9844 0 : ShowContinueError(state, " The sum of sky, ground, and all surrounding surfaces view factors should be less than or equal to 1.0.");
9845 : }
9846 18 : if (IsSkyViewFactorSet && IsGroundViewFactorSet) {
9847 : // If both surface sky and ground view factor defined, overwrite with the defined value
9848 6 : Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
9849 6 : Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
9850 12 : } else if (IsSkyViewFactorSet && !IsGroundViewFactorSet) {
9851 : // If only sky view factor defined, ground view factor = 1 - all other defined view factors.
9852 6 : Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
9853 6 : Surface.ViewFactorGroundIR = 1 - SrdSurfsViewFactor;
9854 6 : if (GndSurfsNum > 0) {
9855 2 : SetGroundViewFactorObject = true;
9856 2 : state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
9857 : } else {
9858 4 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
9859 : }
9860 6 : } else if (!IsSkyViewFactorSet && IsGroundViewFactorSet) {
9861 : // If only ground view factor defined, sky view factor = 1 - all other defined view factors.
9862 2 : Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
9863 2 : Surface.ViewFactorSkyIR = 1 - SrdSurfsViewFactor;
9864 2 : if (SrdSurfsNum > 0) {
9865 2 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
9866 2 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
9867 : }
9868 : } else {
9869 : // If neither ground nor sky view factor specified, continue to use the original proportion.
9870 4 : Surface.ViewFactorSkyIR *= 1 - SrdSurfsViewFactor;
9871 4 : Surface.ViewFactorGroundIR *= 1 - SrdSurfsViewFactor;
9872 4 : if (SrdSurfsNum > 0) {
9873 4 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
9874 4 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
9875 4 : if (GndSurfsNum == 0) {
9876 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
9877 0 : state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsGroundViewFactorSet = true;
9878 : }
9879 : }
9880 4 : if (GndSurfsNum > 0) {
9881 4 : SetGroundViewFactorObject = true;
9882 4 : state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
9883 : }
9884 : }
9885 18 : if (SetGroundViewFactorObject) {
9886 6 : ReSetGroundSurfacesViewFactor(state, SurfNum);
9887 : }
9888 : }
9889 : }
9890 : }
9891 :
9892 249966 : void GetGroundSurfacesTemperatureAverage(EnergyPlusData &state)
9893 : {
9894 : // returns ground surfaces average temperature (deg C)
9895 : // ground surfaces viewed by a building exterior surface
9896 : // ground surfaces temperature weighed using view factors
9897 :
9898 249966 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9899 249959 : return;
9900 : }
9901 :
9902 37 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9903 30 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
9904 23 : continue;
9905 : }
9906 7 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9907 7 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9908 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9909 0 : continue;
9910 : }
9911 7 : Real64 GndSurfaceTemp = 0.0;
9912 7 : Real64 GndSurfViewFactor = 0.0;
9913 7 : Real64 GndSurfaceTempSum = 0.0;
9914 24 : for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
9915 17 : GndSurfViewFactor = GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor;
9916 17 : if (GndSurfViewFactor == 0.0) {
9917 6 : continue;
9918 : }
9919 11 : if (GndSurfsProperty.GndSurfs(gSurfNum).tempSched == nullptr) {
9920 0 : continue;
9921 : }
9922 11 : GndSurfaceTemp = GndSurfsProperty.GndSurfs(gSurfNum).tempSched->getCurrentVal();
9923 11 : GndSurfaceTempSum += GndSurfViewFactor * pow_4(GndSurfaceTemp + Constant::Kelvin);
9924 : }
9925 7 : if (GndSurfaceTempSum == 0.0) {
9926 0 : GndSurfsProperty.SurfsTempAvg = 0.0;
9927 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9928 0 : continue;
9929 : }
9930 7 : GndSurfsProperty.SurfsTempAvg = root_4(GndSurfaceTempSum / GndSurfsProperty.SurfsViewFactorSum) - Constant::Kelvin;
9931 : }
9932 : }
9933 :
9934 249960 : void GetGroundSurfacesReflectanceAverage(EnergyPlusData &state)
9935 : {
9936 : // returns ground surfaces average reflectance (dimensionless)
9937 : // ground reflectance viewed by a building exterior surface
9938 : // ground surfaces reflectance weighed using view factors
9939 :
9940 249960 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9941 249953 : return;
9942 : }
9943 37 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
9944 :
9945 30 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
9946 23 : continue;
9947 : }
9948 7 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9949 7 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9950 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9951 0 : continue;
9952 : }
9953 7 : Real64 GndSurfRefl = 0.0;
9954 7 : Real64 GndSurfsReflSum = 0.0;
9955 24 : for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
9956 17 : if (GndSurfsProperty.GndSurfs(gSurfNum).reflSched == nullptr) {
9957 5 : continue;
9958 : }
9959 12 : GndSurfRefl = GndSurfsProperty.GndSurfs(gSurfNum).reflSched->getCurrentVal();
9960 12 : GndSurfsReflSum += GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor * GndSurfRefl;
9961 : }
9962 7 : if (GndSurfsReflSum == 0.0) {
9963 3 : GndSurfsProperty.SurfsReflAvg = 0.0;
9964 3 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9965 3 : continue;
9966 : }
9967 4 : GndSurfsProperty.SurfsReflAvg = GndSurfsReflSum / GndSurfsProperty.SurfsViewFactorSum;
9968 : }
9969 : }
9970 :
9971 6 : void ReSetGroundSurfacesViewFactor(EnergyPlusData &state, int const SurfNum)
9972 : {
9973 : // resets ground view factors based on view factors identity
9974 : // the ground view factor value is set to the first element
9975 : // when the ground view factor input field is blank
9976 :
9977 6 : if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
9978 0 : return;
9979 : }
9980 6 : auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
9981 6 : GndSurfsProperty.SurfsViewFactorSum = state.dataSurface->Surface(SurfNum).ViewFactorGroundIR;
9982 :
9983 6 : if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
9984 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
9985 0 : state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
9986 0 : return;
9987 : }
9988 6 : GndSurfsProperty.GndSurfs(1).ViewFactor = GndSurfsProperty.SurfsViewFactorSum;
9989 : }
9990 :
9991 249965 : void GetSurroundingSurfacesTemperatureAverage(EnergyPlusData &state)
9992 : {
9993 : // returns surrounding surfaces average temperature (deg C)
9994 : // surrounding surfaces viewed by an exterior surface
9995 : // surrounding surfaces temperature weighed using view factors
9996 :
9997 249965 : if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
9998 249959 : return;
9999 : }
10000 :
10001 33 : for (auto &surface : state.dataSurface->Surface) {
10002 27 : if (!surface.SurfHasSurroundingSurfProperty) {
10003 17 : continue;
10004 : }
10005 : // local vars
10006 10 : Real64 SrdSurfaceTemp = 0.0;
10007 10 : Real64 SrdSurfaceTempSum = 0.0;
10008 10 : auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(surface.SurfSurroundingSurfacesNum);
10009 26 : for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
10010 16 : SrdSurfaceTemp = SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() + Constant::Kelvin;
10011 16 : SrdSurfaceTempSum += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor * pow_4(SrdSurfaceTemp);
10012 : }
10013 10 : surface.SrdSurfTemp = root_4(SrdSurfaceTempSum / surface.ViewFactorSrdSurfs) - Constant::Kelvin;
10014 6 : }
10015 : }
10016 : } // namespace EnergyPlus::HeatBalanceSurfaceManager
|