diff --git a/src/EnergyPlus/DataGlobals.hh b/src/EnergyPlus/DataGlobals.hh index 81e15527503..bcce92cd4c9 100644 --- a/src/EnergyPlus/DataGlobals.hh +++ b/src/EnergyPlus/DataGlobals.hh @@ -149,7 +149,8 @@ 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 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 e59445a96cf..d8a49cdf68c 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 16bc60debbc..c38dec6e21a 100644 --- a/src/EnergyPlus/HeatBalanceIntRadExchange.cc +++ b/src/EnergyPlus/HeatBalanceIntRadExchange.cc @@ -459,15 +459,13 @@ 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; - 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; @@ -524,8 +522,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 @@ -577,8 +577,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); } @@ -596,53 +598,63 @@ 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) + // 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"; 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 (NoUserInputF) { + bool useSolarViewFactors = ((!state.dataSurface->UseRepresentativeSurfaceCalculations || NumZonesWithUserFbyS > 0) && + !state.dataGlobal->AnyInsideShelf && !state.dataViewFactor->EnclSolInfo(enclosureNum).F.empty()); - // 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 (useSolarViewFactors) { + thisEnclosure.F = state.dataViewFactor->EnclSolInfo(enclosureNum).F; + } else { + 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 (ViewFactorReport) { // Allocate and save user or approximate view factors for reporting. - SaveApproximateViewFactors.allocate(thisEnclosure.NumOfSurfaces, thisEnclosure.NumOfSurfaces); - SaveApproximateViewFactors = thisEnclosure.F; - } + 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); + } - 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); + 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); + } // Calculate the script F factors CalcScriptF(state, thisEnclosure.NumOfSurfaces, thisEnclosure.Area, thisEnclosure.F, thisEnclosure.Emissivity, thisEnclosure.ScriptF); @@ -668,24 +680,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"); @@ -695,7 +709,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", @@ -767,22 +781,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); + } } } } diff --git a/src/EnergyPlus/SolarShading.cc b/src/EnergyPlus/SolarShading.cc index 61e918783d9..364418c9009 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 90e5c25b9b5..b3cd0db6c77 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; diff --git a/tst/EnergyPlus/unit/HeatBalanceAirManager.unit.cc b/tst/EnergyPlus/unit/HeatBalanceAirManager.unit.cc index e39c7af16fd..2cb790b79e0 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",