From 2e877f415e786e6cc16730bf7dd261c40b58a505 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Tue, 5 Mar 2024 14:32:22 -0600 Subject: [PATCH 1/8] InitInteriorRadExchange efficiencies --- src/EnergyPlus/HeatBalanceIntRadExchange.cc | 134 +++++++++++--------- 1 file changed, 74 insertions(+), 60 deletions(-) diff --git a/src/EnergyPlus/HeatBalanceIntRadExchange.cc b/src/EnergyPlus/HeatBalanceIntRadExchange.cc index 4302656ac7e..e345285cdd6 100644 --- a/src/EnergyPlus/HeatBalanceIntRadExchange.cc +++ b/src/EnergyPlus/HeatBalanceIntRadExchange.cc @@ -452,13 +452,12 @@ namespace HeatBalanceIntRadExchange { static constexpr std::string_view RoutineName("InitInteriorRadExchange: "); bool NoUserInputF; // Logical flag signifying no input F's for zone bool ErrorsFound(false); - Real64 CheckValue1; - Real64 CheckValue2; - Real64 FinalCheckValue; + Real64 CheckValue1 = 0.0; + Real64 CheckValue2 = 0.0; + Real64 FinalCheckValue = 0.0; Array2D SaveApproximateViewFactors; // Save for View Factor reporting - Real64 RowSum; - Real64 FixedRowSum; - int NumIterations; + Real64 FixedRowSum = 0.0; + int NumIterations = 0; std::string Option1; // view factor report option auto &ViewFactorReport = state.dataHeatBalIntRadExchg->ViewFactorReport; @@ -513,8 +512,10 @@ namespace HeatBalanceIntRadExchange { thisEnclosure.Emissivity.dimension(numEnclosureSurfaces, 0.0); thisEnclosure.Azimuth.dimension(numEnclosureSurfaces, 0.0); thisEnclosure.Tilt.dimension(numEnclosureSurfaces, 0.0); - thisEnclosure.Fp.dimension(numEnclosureSurfaces, 1.0); - thisEnclosure.FMRT.dimension(numEnclosureSurfaces, 0.0); + if (state.dataHeatBalIntRadExchg->CarrollMethod) { + thisEnclosure.Fp.dimension(numEnclosureSurfaces, 1.0); + thisEnclosure.FMRT.dimension(numEnclosureSurfaces, 0.0); + } thisEnclosure.SurfacePtr.dimension(numEnclosureSurfaces, 0); // Initialize the enclosure surface arrays @@ -562,8 +563,10 @@ namespace HeatBalanceIntRadExchange { // If there is only one surface in a zone, then there is no radiant exchange thisEnclosure.F = 0.0; thisEnclosure.ScriptF = 0.0; - thisEnclosure.Fp = 0.0; - thisEnclosure.FMRT = 0.0; + if (state.dataHeatBalIntRadExchg->CarrollMethod) { + thisEnclosure.Fp = 0.0; + thisEnclosure.FMRT = 0.0; + } if (state.dataGlobal->DisplayAdvancedReportVariables) print(state.files.eio, "Surface View Factor Check Values,{},0,0,0,-1,0,0\n", thisEnclosure.Name); continue; // Go to the next enclosure in the loop @@ -597,7 +600,11 @@ namespace HeatBalanceIntRadExchange { ErrorsFound); // Obtains user input view factors from input file } - if (NoUserInputF) { + // If there is user input, use that as the approximate view factors. + // If there is no user input, but UseRepresentativeSurfaceCalculations is true, then calc approximate view factors + // If no user input and not UseRepresentativeSurfaceCalculations, then copy final view factors from the solar enclosure + bool useSolarViewFactors = (NoUserInputF && !state.dataSurface->UseRepresentativeSurfaceCalculations); + if (NoUserInputF && state.dataSurface->UseRepresentativeSurfaceCalculations) { // Calculate the view factors and make sure they satisfy reciprocity CalcApproximateViewFactors(state, @@ -608,26 +615,29 @@ namespace HeatBalanceIntRadExchange { thisEnclosure.F, thisEnclosure.SurfacePtr); } + if (useSolarViewFactors) { + thisEnclosure.F = state.dataViewFactor->EnclSolInfo(enclosureNum).F; + } else { + if (ViewFactorReport) { // Allocate and save user or approximate view factors for reporting. + SaveApproximateViewFactors.allocate(thisEnclosure.NumOfSurfaces, thisEnclosure.NumOfSurfaces); + SaveApproximateViewFactors = thisEnclosure.F; + } - if (ViewFactorReport) { // Allocate and save user or approximate view factors for reporting. - SaveApproximateViewFactors.allocate(thisEnclosure.NumOfSurfaces, thisEnclosure.NumOfSurfaces); - SaveApproximateViewFactors = thisEnclosure.F; + bool anyIntMassInZone = DoesZoneHaveInternalMass(state, thisEnclosure.NumOfSurfaces, thisEnclosure.SurfacePtr); + FixViewFactors(state, + thisEnclosure.NumOfSurfaces, + thisEnclosure.Area, + thisEnclosure.F, + thisEnclosure.Name, + thisEnclosure.spaceNums, + CheckValue1, + CheckValue2, + FinalCheckValue, + NumIterations, + FixedRowSum, + anyIntMassInZone); } - bool anyIntMassInZone = DoesZoneHaveInternalMass(state, thisEnclosure.NumOfSurfaces, thisEnclosure.SurfacePtr); - FixViewFactors(state, - thisEnclosure.NumOfSurfaces, - thisEnclosure.Area, - thisEnclosure.F, - thisEnclosure.Name, - thisEnclosure.spaceNums, - CheckValue1, - CheckValue2, - FinalCheckValue, - NumIterations, - FixedRowSum, - anyIntMassInZone); - // Calculate the script F factors CalcScriptF(state, thisEnclosure.NumOfSurfaces, thisEnclosure.Area, thisEnclosure.F, thisEnclosure.Emissivity, thisEnclosure.ScriptF); if (ViewFactorReport) { // Write to SurfInfo File @@ -652,24 +662,26 @@ namespace HeatBalanceIntRadExchange { print(state.files.eio, "\n"); } - print(state.files.eio, "Approximate or User Input ViewFactors,To Surface,Surface Class,RowSum"); - for (int SurfNum : thisEnclosure.SurfaceReportNums) { - print(state.files.eio, ",{}", state.dataSurface->Surface(thisEnclosure.SurfacePtr(SurfNum)).Name); - } - print(state.files.eio, "\n"); - - for (int Findex : thisEnclosure.SurfaceReportNums) { - RowSum = sum(SaveApproximateViewFactors(_, Findex)); - print(state.files.eio, - "{},{},{},{:.4R}", - "View Factor", - state.dataSurface->Surface(thisEnclosure.SurfacePtr(Findex)).Name, - cSurfaceClass(state.dataSurface->Surface(thisEnclosure.SurfacePtr(Findex)).Class), - RowSum); + if (!useSolarViewFactors) { + print(state.files.eio, "Approximate or User Input ViewFactors,To Surface,Surface Class,RowSum"); for (int SurfNum : thisEnclosure.SurfaceReportNums) { - print(state.files.eio, ",{:.4R}", SaveApproximateViewFactors(SurfNum, Findex)); + print(state.files.eio, ",{}", state.dataSurface->Surface(thisEnclosure.SurfacePtr(SurfNum)).Name); } print(state.files.eio, "\n"); + + for (int Findex : thisEnclosure.SurfaceReportNums) { + Real64 RowSum = sum(SaveApproximateViewFactors(_, Findex)); + print(state.files.eio, + "{},{},{},{:.4R}", + "View Factor", + state.dataSurface->Surface(thisEnclosure.SurfacePtr(Findex)).Name, + cSurfaceClass(state.dataSurface->Surface(thisEnclosure.SurfacePtr(Findex)).Class), + RowSum); + for (int SurfNum : thisEnclosure.SurfaceReportNums) { + print(state.files.eio, ",{:.4R}", SaveApproximateViewFactors(SurfNum, Findex)); + } + print(state.files.eio, "\n"); + } } print(state.files.eio, "Final ViewFactors,To Surface,Surface Class,RowSum"); @@ -679,7 +691,7 @@ namespace HeatBalanceIntRadExchange { print(state.files.eio, "\n"); for (int Findex : thisEnclosure.SurfaceReportNums) { - RowSum = sum(thisEnclosure.F(_, Findex)); + Real64 RowSum = sum(thisEnclosure.F(_, Findex)); print(state.files.eio, "{},{},{},{:.4R}", "View Factor", @@ -751,22 +763,24 @@ namespace HeatBalanceIntRadExchange { SaveApproximateViewFactors.deallocate(); } - RowSum = 0.0; - for (int Findex : thisEnclosure.SurfaceReportNums) { - RowSum += sum(thisEnclosure.F(_, Findex)); - } - RowSum = std::abs(RowSum - thisEnclosure.NumOfSurfaces); - FixedRowSum = std::abs(FixedRowSum - thisEnclosure.NumOfSurfaces); - if (state.dataGlobal->DisplayAdvancedReportVariables) { - print(state.files.eio, - "Surface View Factor Check Values,{},{:.6R},{:.6R},{:.6R},{},{:.6R},{:.6R}\n", - thisEnclosure.Name, - CheckValue1, - CheckValue2, - FinalCheckValue, - NumIterations, - FixedRowSum, - RowSum); + if (!useSolarViewFactors) { + Real64 RowSum = 0.0; + for (int Findex : thisEnclosure.SurfaceReportNums) { + RowSum += sum(thisEnclosure.F(_, Findex)); + } + RowSum = std::abs(RowSum - thisEnclosure.NumOfSurfaces); + FixedRowSum = std::abs(FixedRowSum - thisEnclosure.NumOfSurfaces); + if (state.dataGlobal->DisplayAdvancedReportVariables) { + print(state.files.eio, + "Surface View Factor Check Values,{},{:.6R},{:.6R},{:.6R},{},{:.6R},{:.6R}\n", + thisEnclosure.Name, + CheckValue1, + CheckValue2, + FinalCheckValue, + NumIterations, + FixedRowSum, + RowSum); + } } } } From aefcf34f563844a74b356b8cc5054055c0860eda Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Mon, 20 May 2024 13:15:10 -0500 Subject: [PATCH 2/8] Tweak useSolarViewFactors --- src/EnergyPlus/HeatBalanceIntRadExchange.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/EnergyPlus/HeatBalanceIntRadExchange.cc b/src/EnergyPlus/HeatBalanceIntRadExchange.cc index e345285cdd6..7dca10ee2d3 100644 --- a/src/EnergyPlus/HeatBalanceIntRadExchange.cc +++ b/src/EnergyPlus/HeatBalanceIntRadExchange.cc @@ -603,9 +603,12 @@ namespace HeatBalanceIntRadExchange { // If there is user input, use that as the approximate view factors. // If there is no user input, but UseRepresentativeSurfaceCalculations is true, then calc approximate view factors // If no user input and not UseRepresentativeSurfaceCalculations, then copy final view factors from the solar enclosure - bool useSolarViewFactors = (NoUserInputF && !state.dataSurface->UseRepresentativeSurfaceCalculations); - if (NoUserInputF && state.dataSurface->UseRepresentativeSurfaceCalculations) { + bool useSolarViewFactors = (NoUserInputF && !state.dataSurface->UseRepresentativeSurfaceCalculations && + !state.dataViewFactor->EnclSolInfo(enclosureNum).F.empty()); + if (useSolarViewFactors) { + thisEnclosure.F = state.dataViewFactor->EnclSolInfo(enclosureNum).F; + } else { // Calculate the view factors and make sure they satisfy reciprocity CalcApproximateViewFactors(state, thisEnclosure.NumOfSurfaces, @@ -614,10 +617,7 @@ namespace HeatBalanceIntRadExchange { thisEnclosure.Tilt, thisEnclosure.F, thisEnclosure.SurfacePtr); - } - if (useSolarViewFactors) { - thisEnclosure.F = state.dataViewFactor->EnclSolInfo(enclosureNum).F; - } else { + if (ViewFactorReport) { // Allocate and save user or approximate view factors for reporting. SaveApproximateViewFactors.allocate(thisEnclosure.NumOfSurfaces, thisEnclosure.NumOfSurfaces); SaveApproximateViewFactors = thisEnclosure.F; From 8b110fd30c9ab33be5b644312dec0a68e6589226 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Tue, 25 Nov 2025 15:25:31 -0600 Subject: [PATCH 3/8] Fix unit test --- tst/EnergyPlus/unit/HeatBalanceAirManager.unit.cc | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tst/EnergyPlus/unit/HeatBalanceAirManager.unit.cc b/tst/EnergyPlus/unit/HeatBalanceAirManager.unit.cc index c2fcbb7833b..4d1c6b3e6ab 100644 --- a/tst/EnergyPlus/unit/HeatBalanceAirManager.unit.cc +++ b/tst/EnergyPlus/unit/HeatBalanceAirManager.unit.cc @@ -849,18 +849,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceAirManager_GetMixingAndCrossMixing) " ** ~~~ ** So, when there are three or less surfaces in a zone, EnergyPlus will make sure there are no losses of energy but", " ** ~~~ ** it will not exchange the full amount of radiation with the rest of the zone as it would if there was a completed " "enclosure.", - " ** Warning ** CalcApproximateViewFactors: Zero area for all other zone surfaces.", // Why are these errors being reported twice, because - // something is being calculated twice? - " ** ~~~ ** Happens for Surface=\"DUMMY SPACE 1A FLOOR\" in Zone=ZONE 1", - " ** Warning ** CalcApproximateViewFactors: Zero area for all other zone surfaces.", - " ** ~~~ ** Happens for Surface=\"DUMMY SPACE 1B FLOOR\" in Zone=ZONE 1", - " ** Warning ** Surfaces in Zone/Enclosure=\"ZONE 1\" do not define an enclosure.", - " ** ~~~ ** Number of surfaces <= 3, view factors are set to force reciprocity but may not fulfill completeness.", - " ** ~~~ ** Reciprocity means that radiant exchange between two surfaces will match and not lead to an energy loss.", - " ** ~~~ ** Completeness means that all of the view factors between a surface and the other surfaces in a zone add up to unity.", - " ** ~~~ ** So, when there are three or less surfaces in a zone, EnergyPlus will make sure there are no losses of energy but", - " ** ~~~ ** it will not exchange the full amount of radiation with the rest of the zone as it would if there was a completed " - "enclosure.", " ************* Testing Individual Branch Integrity", " ************* All Branches passed integrity testing", " ************* Testing Individual Supply Air Path Integrity", From ec497786362664c0d7e5c8ba29f10ab390ffe660 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Tue, 9 Dec 2025 17:35:26 -0600 Subject: [PATCH 4/8] Copy solar view factors unless CarrollMRT or UseRepresentativeSurfaceCalculations --- src/EnergyPlus/HeatBalanceIntRadExchange.cc | 23 +++++---------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/EnergyPlus/HeatBalanceIntRadExchange.cc b/src/EnergyPlus/HeatBalanceIntRadExchange.cc index 3a8c690e637..6834b61d278 100644 --- a/src/EnergyPlus/HeatBalanceIntRadExchange.cc +++ b/src/EnergyPlus/HeatBalanceIntRadExchange.cc @@ -459,7 +459,6 @@ namespace HeatBalanceIntRadExchange { // SUBROUTINE LOCAL VARIABLE DECLARATIONS: static constexpr std::string_view RoutineName("InitInteriorRadExchange: "); - bool NoUserInputF; // Logical flag signifying no input F's for zone bool ErrorsFound(false); Real64 CheckValue1 = 0.0; Real64 CheckValue2 = 0.0; @@ -599,27 +598,15 @@ namespace HeatBalanceIntRadExchange { CalcFMRT(state, thisEnclosure.NumOfSurfaces, thisEnclosure.Area, thisEnclosure.FMRT); CalcFp(thisEnclosure.NumOfSurfaces, thisEnclosure.Emissivity, thisEnclosure.FMRT, thisEnclosure.Fp); } else { - // Get user supplied view factors if available in idf. - - NoUserInputF = true; + // For radiant enclosures: + // If UseRepresentativeSurfaceCalculations is true and there are no user input view factors, then calc approx view factors + // (If User supplied view factors are present, then UseRepresentativeSurfaceCalculations is skipped in SufaceGeometry::GetSurfaceData) + // Otherwise, copy final view factors from the solar enclosure constexpr std::string_view cCurrentModuleObject = "ZoneProperty:UserViewFactors:BySurfaceName"; int NumZonesWithUserFbyS = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject); - if (NumZonesWithUserFbyS > 0) { - - GetInputViewFactorsbyName(state, - thisEnclosure.Name, - thisEnclosure.NumOfSurfaces, - thisEnclosure.F, - thisEnclosure.SurfacePtr, - NoUserInputF, - ErrorsFound); // Obtains user input view factors from input file - } - // If there is user input, use that as the approximate view factors. - // If there is no user input, but UseRepresentativeSurfaceCalculations is true, then calc approximate view factors - // If no user input and not UseRepresentativeSurfaceCalculations, then copy final view factors from the solar enclosure - bool useSolarViewFactors = (NoUserInputF && !state.dataSurface->UseRepresentativeSurfaceCalculations && + bool useSolarViewFactors = ((!state.dataSurface->UseRepresentativeSurfaceCalculations || NumZonesWithUserFbyS > 0) && !state.dataViewFactor->EnclSolInfo(enclosureNum).F.empty()); if (useSolarViewFactors) { From ffc52e463ec751520ee9012b26b7602b00e28df1 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 17 Dec 2025 10:04:27 -0600 Subject: [PATCH 5/8] Fix misspelled name for AnyShadingControlInModel --- src/EnergyPlus/DataGlobals.hh | 2 +- src/EnergyPlus/SolarShading.cc | 2 +- src/EnergyPlus/SurfaceGeometry.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EnergyPlus/DataGlobals.hh b/src/EnergyPlus/DataGlobals.hh index 42eeb43a1fa..56066a71efd 100644 --- a/src/EnergyPlus/DataGlobals.hh +++ b/src/EnergyPlus/DataGlobals.hh @@ -149,7 +149,7 @@ struct DataGlobal : BaseGlobalStruct bool AnyEnergyManagementSystemInModel = false; // true if there is any EMS or Erl in model. otherwise false bool AnySurfPropOverridesInModel = false; // true if there is any EMS or Erl overriding the surface properties for any surface. bool AnyConstrOverridesInModel = false; // true if there is any EMS or Erl overriding the constructions for any surface. - bool AndShadingControlInModel = false; // true if there is any window shading control for any fenestration surface + bool AnyShadingControlInModel = false; // true if there is any window shading control for any fenestration surface bool AnyLocalEnvironmentsInModel = false; // true if there is any local environmental data objected defined in model, otherwise false bool AnyPlantInModel = false; // true if there are any plant or condenser loops in model, otherwise false bool AnyIdealCondEntSetPointInModel = false; // true if there is any ideal condenser entering set point manager in model. diff --git a/src/EnergyPlus/SolarShading.cc b/src/EnergyPlus/SolarShading.cc index 2a5cd96da0a..474923b8016 100644 --- a/src/EnergyPlus/SolarShading.cc +++ b/src/EnergyPlus/SolarShading.cc @@ -10287,7 +10287,7 @@ void CheckGlazingShadingStatusChange(EnergyPlusData &state) for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfRadiantEnclosures; ++enclosureNum) { state.dataViewFactor->EnclRadInfo(enclosureNum).radReCalc = false; } - if (!state.dataGlobal->AndShadingControlInModel) { + if (!state.dataGlobal->AnyShadingControlInModel) { return; } for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) { diff --git a/src/EnergyPlus/SurfaceGeometry.cc b/src/EnergyPlus/SurfaceGeometry.cc index c254d24f790..a5dcc402ba4 100644 --- a/src/EnergyPlus/SurfaceGeometry.cc +++ b/src/EnergyPlus/SurfaceGeometry.cc @@ -10089,7 +10089,7 @@ namespace SurfaceGeometry { int curShadedConstruction = state.dataSurface->WindowShadingControl(iShadeCtrl).getInputShadedConstruction; for (int jFeneRef = 1; jFeneRef <= state.dataSurface->WindowShadingControl(iShadeCtrl).FenestrationCount; ++jFeneRef) { if (Util::SameString(state.dataSurface->WindowShadingControl(iShadeCtrl).FenestrationName(jFeneRef), surfTemp.Name)) { - state.dataGlobal->AndShadingControlInModel = true; + state.dataGlobal->AnyShadingControlInModel = true; surfTemp.HasShadeControl = true; surfTemp.windowShadingControlList.push_back(iShadeCtrl); surfTemp.activeWindowShadingControl = iShadeCtrl; From 6c617dddd9f6de0286afa703c4c99cee46b4641c Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 17 Dec 2025 10:19:45 -0600 Subject: [PATCH 6/8] Recalc radiant view factors if any inside light shelf --- src/EnergyPlus/DataGlobals.hh | 1 + src/EnergyPlus/DaylightingDevices.cc | 1 + src/EnergyPlus/HeatBalanceIntRadExchange.cc | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/EnergyPlus/DataGlobals.hh b/src/EnergyPlus/DataGlobals.hh index 56066a71efd..0b267d4a837 100644 --- a/src/EnergyPlus/DataGlobals.hh +++ b/src/EnergyPlus/DataGlobals.hh @@ -150,6 +150,7 @@ struct DataGlobal : BaseGlobalStruct bool AnySurfPropOverridesInModel = false; // true if there is any EMS or Erl overriding the surface properties for any surface. bool AnyConstrOverridesInModel = false; // true if there is any EMS or Erl overriding the constructions for any surface. bool AnyShadingControlInModel = false; // true if there is any window shading control for any fenestration surface + bool AnyInsideShelf = false; // true if these is any inside daylighting shelf bool AnyLocalEnvironmentsInModel = false; // true if there is any local environmental data objected defined in model, otherwise false bool AnyPlantInModel = false; // true if there are any plant or condenser loops in model, otherwise false bool AnyIdealCondEntSetPointInModel = false; // true if there is any ideal condenser entering set point manager in model. diff --git a/src/EnergyPlus/DaylightingDevices.cc b/src/EnergyPlus/DaylightingDevices.cc index d92e665841b..3c2acd31737 100644 --- a/src/EnergyPlus/DaylightingDevices.cc +++ b/src/EnergyPlus/DaylightingDevices.cc @@ -377,6 +377,7 @@ namespace Dayltg { if (ShelfSurf > 0) { // Double surface area so that both sides of the shelf are treated as internal mass state.dataSurface->Surface(ShelfSurf).Area *= 2.0; + state.dataGlobal->AnyInsideShelf = true; // Set this to force recalc for radiant view factors due to area change } ShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf; diff --git a/src/EnergyPlus/HeatBalanceIntRadExchange.cc b/src/EnergyPlus/HeatBalanceIntRadExchange.cc index 6834b61d278..c1970fa6d2f 100644 --- a/src/EnergyPlus/HeatBalanceIntRadExchange.cc +++ b/src/EnergyPlus/HeatBalanceIntRadExchange.cc @@ -607,7 +607,7 @@ namespace HeatBalanceIntRadExchange { int NumZonesWithUserFbyS = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject); bool useSolarViewFactors = ((!state.dataSurface->UseRepresentativeSurfaceCalculations || NumZonesWithUserFbyS > 0) && - !state.dataViewFactor->EnclSolInfo(enclosureNum).F.empty()); + !state.dataGlobal->AnyInsideShelf && !state.dataViewFactor->EnclSolInfo(enclosureNum).F.empty()); if (useSolarViewFactors) { thisEnclosure.F = state.dataViewFactor->EnclSolInfo(enclosureNum).F; From 4989108d44827c8576366f3a01e5c4456bf45655 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 17 Dec 2025 16:09:41 -0600 Subject: [PATCH 7/8] Added comment --- src/EnergyPlus/HeatBalanceIntRadExchange.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/EnergyPlus/HeatBalanceIntRadExchange.cc b/src/EnergyPlus/HeatBalanceIntRadExchange.cc index c1970fa6d2f..af123557623 100644 --- a/src/EnergyPlus/HeatBalanceIntRadExchange.cc +++ b/src/EnergyPlus/HeatBalanceIntRadExchange.cc @@ -601,6 +601,7 @@ namespace HeatBalanceIntRadExchange { // For radiant enclosures: // If UseRepresentativeSurfaceCalculations is true and there are no user input view factors, then calc approx view factors // (If User supplied view factors are present, then UseRepresentativeSurfaceCalculations is skipped in SufaceGeometry::GetSurfaceData) + // If there are any inside light shelfs then calc approx view factors (because the light shelf area is doubled for heat transfer) // Otherwise, copy final view factors from the solar enclosure constexpr std::string_view cCurrentModuleObject = "ZoneProperty:UserViewFactors:BySurfaceName"; From cdc5cfd484981f4f787d89725774121b8f4c2fdc Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 17 Dec 2025 16:35:07 -0600 Subject: [PATCH 8/8] Allow for possible user view factors when useSolarViewFactors is false --- src/EnergyPlus/HeatBalanceIntRadExchange.cc | 30 +++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/EnergyPlus/HeatBalanceIntRadExchange.cc b/src/EnergyPlus/HeatBalanceIntRadExchange.cc index af123557623..a2a8643a19e 100644 --- a/src/EnergyPlus/HeatBalanceIntRadExchange.cc +++ b/src/EnergyPlus/HeatBalanceIntRadExchange.cc @@ -613,14 +613,28 @@ namespace HeatBalanceIntRadExchange { if (useSolarViewFactors) { thisEnclosure.F = state.dataViewFactor->EnclSolInfo(enclosureNum).F; } else { - // Calculate the view factors and make sure they satisfy reciprocity - CalcApproximateViewFactors(state, - thisEnclosure.NumOfSurfaces, - thisEnclosure.Area, - thisEnclosure.Azimuth, - thisEnclosure.Tilt, - thisEnclosure.F, - thisEnclosure.SurfacePtr); + bool NoUserInputF = true; + if (NumZonesWithUserFbyS > 0) { + + GetInputViewFactorsbyName(state, + thisEnclosure.Name, + thisEnclosure.NumOfSurfaces, + thisEnclosure.F, + thisEnclosure.SurfacePtr, + NoUserInputF, + ErrorsFound); // Obtains user input view factors from input file + } + + if (NoUserInputF) { + // Calculate the view factors and make sure they satisfy reciprocity + CalcApproximateViewFactors(state, + thisEnclosure.NumOfSurfaces, + thisEnclosure.Area, + thisEnclosure.Azimuth, + thisEnclosure.Tilt, + thisEnclosure.F, + thisEnclosure.SurfacePtr); + } if (ViewFactorReport) { // Allocate and save user or approximate view factors for reporting. SaveApproximateViewFactors.allocate(thisEnclosure.NumOfSurfaces, thisEnclosure.NumOfSurfaces);