From 934ae69dfc351d0abaaff0f0d47e8e7e109894a2 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 8 Jun 2026 13:48:01 -0700 Subject: [PATCH 1/8] Check that (horizontal or vertical) dividers fit, nonoverlapping, within the glazed opening. --- src/EnergyPlus/SurfaceGeometry.cc | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/EnergyPlus/SurfaceGeometry.cc b/src/EnergyPlus/SurfaceGeometry.cc index 17b73de79ee..5f55c3d7ff6 100644 --- a/src/EnergyPlus/SurfaceGeometry.cc +++ b/src/EnergyPlus/SurfaceGeometry.cc @@ -13035,13 +13035,34 @@ namespace SurfaceGeometry { // If exterior window has divider, subtract divider area to get glazed area DivWidth = state.dataSurface->FrameDivider(surf.FrameDivider).DividerWidth; if (DivWidth > 0.0 && !ErrorInSurface) { - DivArea = DivWidth * (state.dataSurface->FrameDivider(FrDivNum).HorDividers * surf.Width + - state.dataSurface->FrameDivider(FrDivNum).VertDividers * surf.Height - - state.dataSurface->FrameDivider(FrDivNum).HorDividers * - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth); + if (DivWidth * state.dataSurface->FrameDivider(FrDivNum).HorDividers > surf.Height) { + ShowSevereError(state, std::format("{}Horizontal dividers exceed glazed opening height for window {}", RoutineName, surf.Name)); + ShowContinueError(state, std::format("{}Number of horizontal dividers=[{}], divider width=[{:.2f}] m, glazed opening height=[{:.2f}] m.", + RoutineName, + state.dataSurface->FrameDivider(FrDivNum).HorDividers, + DivWidth, + surf.Height)); + ErrorInSurface = true; + } + if (DivWidth * state.dataSurface->FrameDivider(FrDivNum).VertDividers > surf.Width) { + ShowSevereError(state, std::format("{}Vertical dividers exceed glazed opening width for window {}", RoutineName, surf.Name)); + ShowContinueError(state, std::format("{}Number of vertical dividers=[{}], divider width=[{:.2f}] m, glazed opening width=[{:.2f}] m.", + RoutineName, + state.dataSurface->FrameDivider(FrDivNum).VertDividers, + DivWidth, + surf.Width)); + ErrorInSurface = true; + } + Real64 const DivLenTotal = state.dataSurface->FrameDivider(FrDivNum).HorDividers * surf.Width + state.dataSurface->FrameDivider(FrDivNum).VertDividers * surf.Height; + Real64 const DivLenOvlp = state.dataSurface->FrameDivider(FrDivNum).HorDividers * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth; + DivArea = DivWidth * (DivLenTotal - DivLenOvlp); state.dataSurface->SurfWinDividerArea(ThisSurf) = DivArea * surf.Multiplier; if (DivArea <= 0.0) { - ShowSevereError(state, std::format("{}Calculated Divider Area <= 0.0 for Window={}", RoutineName, surf.Name)); + ShowSevereError(state, std::format("{}Divider area exceeds glazed opening for window {}", RoutineName, surf.Name)); + ShowContinueError(state, + std::format("Window surface area=[{:.2f}] m2, divider area=[{:.2f}] m2.", + surf.Area, + DivArea)); ErrorInSurface = true; } else if ((surf.Area - state.dataSurface->SurfWinDividerArea(ThisSurf)) <= 0.0) { ShowSevereError(state, std::format("{}Divider area exceeds glazed opening for window {}", RoutineName, surf.Name)); From ff781c38e290f5111dca9d4a1852068af07fffe7 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 8 Jun 2026 13:48:24 -0700 Subject: [PATCH 2/8] Update bad divider geometry unit test to check all severe error types. --- tst/EnergyPlus/unit/SurfaceGeometry.unit.cc | 133 +++++++++++++++++++- 1 file changed, 132 insertions(+), 1 deletion(-) diff --git a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc index 6c0831950a7..903ad52789c 100644 --- a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc +++ b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc @@ -12753,6 +12753,50 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_BadDividerGeometry) " 0.8, !- Divider Visible Absorptance", " 0.9; !- Divider Thermal Hemispherical Emissivity", + " WindowProperty:FrameAndDivider,", + " BadDividerGeometry2, !- Name", + " 0.05, !- Frame Width {m}", + " 0.01, !- Frame Outside Projection {m}", + " 0.01, !- Frame Inside Projection {m}", + " 5.0, !- Frame Conductance {W/m2-K}", + " 1.2, !- Ratio of Frame-Edge Glass Conductance to Center-Of-Glass Conductance", + " 0.8, !- Frame Solar Absorptance", + " 0.8, !- Frame Visible Absorptance", + " 0.9, !- Frame Thermal Hemispherical Emissivity", + " DividedLite, !- Divider Type", + " 0.5, !- Divider Width {m}", + " 20, !- Number of Horizontal Dividers", + " 20, !- Number of Vertical Dividers", + " 0.00, !- Divider Outside Projection {m}", + " 0.00, !- Divider Inside Projection {m}", + " 5.0, !- Divider Conductance {W/m2-K}", + " 1.2, !- Ratio of Divider-Edge Glass Conductance to Center-Of-Glass Conductance", + " 0.8, !- Divider Solar Absorptance", + " 0.8, !- Divider Visible Absorptance", + " 0.9; !- Divider Thermal Hemispherical Emissivity", + + " WindowProperty:FrameAndDivider,", + " BadDividerGeometry3, !- Name", + " 0.05, !- Frame Width {m}", + " 0.01, !- Frame Outside Projection {m}", + " 0.01, !- Frame Inside Projection {m}", + " 5.0, !- Frame Conductance {W/m2-K}", + " 1.2, !- Ratio of Frame-Edge Glass Conductance to Center-Of-Glass Conductance", + " 0.8, !- Frame Solar Absorptance", + " 0.8, !- Frame Visible Absorptance", + " 0.9, !- Frame Thermal Hemispherical Emissivity", + " DividedLite, !- Divider Type", + " 0.5, !- Divider Width {m}", + " 50, !- Number of Horizontal Dividers", + " 50, !- Number of Vertical Dividers", + " 0.00, !- Divider Outside Projection {m}", + " 0.00, !- Divider Inside Projection {m}", + " 5.0, !- Divider Conductance {W/m2-K}", + " 1.2, !- Ratio of Divider-Edge Glass Conductance to Center-Of-Glass Conductance", + " 0.8, !- Divider Solar Absorptance", + " 0.8, !- Divider Visible Absorptance", + " 0.9; !- Divider Thermal Hemispherical Emissivity", + " FenestrationSurface:Detailed,", " FenestrationSurface, !- Name", " Window, !- Surface Type", @@ -12768,6 +12812,36 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_BadDividerGeometry) " 9.900000,0.0,0.1000000, !- X,Y,Z ==> Vertex 3 {m}", " 9.900000,0.0,9.900000; !- X,Y,Z ==> Vertex 4 {m}", + " FenestrationSurface:Detailed,", + " FenestrationSurface2, !- Name", + " Window, !- Surface Type", + " WindowConstruction, !- Construction Name", + " Wall2, !- Building Surface Name", + " , !- Outside Boundary Condition Object", + " 0.5000000, !- View Factor to Ground", + " BadDividerGeometry2, !- Frame and Divider Name", + " 1.0, !- Multiplier", + " 4, !- Number of Vertices", + " 0.200000,0.0,9.900000, !- X,Y,Z ==> Vertex 1 {m}", + " 0.200000,0.0,0.1000000, !- X,Y,Z ==> Vertex 2 {m}", + " 9.900000,0.0,0.1000000, !- X,Y,Z ==> Vertex 3 {m}", + " 9.900000,0.0,9.900000; !- X,Y,Z ==> Vertex 4 {m}", + + " FenestrationSurface:Detailed,", + " FenestrationSurface3, !- Name", + " Window, !- Surface Type", + " WindowConstruction, !- Construction Name", + " Wall3, !- Building Surface Name", + " , !- Outside Boundary Condition Object", + " 0.5000000, !- View Factor to Ground", + " BadDividerGeometry3, !- Frame and Divider Name", + " 1.0, !- Multiplier", + " 4, !- Number of Vertices", + " 0.200000,0.0,9.900000, !- X,Y,Z ==> Vertex 1 {m}", + " 0.200000,0.0,0.1000000, !- X,Y,Z ==> Vertex 2 {m}", + " 9.900000,0.0,0.1000000, !- X,Y,Z ==> Vertex 3 {m}", + " 9.900000,0.0,9.900000; !- X,Y,Z ==> Vertex 4 {m}", + " SurfaceProperty:LocalEnvironment,", " LocEnv:FenestrationSurface, !- Name", " FenestrationSurface, !- Exterior Surface Name", @@ -12832,6 +12906,40 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_BadDividerGeometry) " 10.00000,0.0,0.0, !- X,Y,Z ==> Vertex 3 {m}", " 10.00000,0.0,10.00000; !- X,Y,Z ==> Vertex 4 {m}", + " BuildingSurface:Detailed,", + " Wall2, !- Name", + " Wall, !- Surface Type", + " WallConstruction, !- Construction Name", + " Zone, !- Zone Name", + " , !- Space Name", + " Outdoors, !- Outside Boundary Condition", + " , !- Outside Boundary Condition Object", + " SunExposed, !- Sun Exposure", + " WindExposed, !- Wind Exposure", + " 0.5000000, !- View Factor to Ground", + " 4, !- Number of Vertices", + " 1.0,0.000000,10.00000, !- X,Y,Z ==> Vertex 1 {m}", + " 1.0,0.000000,0.0, !- X,Y,Z ==> Vertex 2 {m}", + " 11.00000,0.0,0.0, !- X,Y,Z ==> Vertex 3 {m}", + " 11.00000,0.0,10.00000; !- X,Y,Z ==> Vertex 4 {m}", + + " BuildingSurface:Detailed,", + " Wall3, !- Name", + " Wall, !- Surface Type", + " WallConstruction, !- Construction Name", + " Zone, !- Zone Name", + " , !- Space Name", + " Outdoors, !- Outside Boundary Condition", + " , !- Outside Boundary Condition Object", + " SunExposed, !- Sun Exposure", + " WindExposed, !- Wind Exposure", + " 0.5000000, !- View Factor to Ground", + " 4, !- Number of Vertices", + " 2.0,0.000000,10.00000, !- X,Y,Z ==> Vertex 1 {m}", + " 2.0,0.000000,0.0, !- X,Y,Z ==> Vertex 2 {m}", + " 12.00000,0.0,0.0, !- X,Y,Z ==> Vertex 3 {m}", + " 12.00000,0.0,10.00000; !- X,Y,Z ==> Vertex 4 {m}", + " BuildingSurface:Detailed,", " Floor, !- Name", " Floor, !- Surface Type", @@ -12873,11 +12981,34 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_BadDividerGeometry) HeatBalanceManager::GetConstructData(*state, ErrorsFound); HeatBalanceManager::GetBuildingData(*state, ErrorsFound); + EXPECT_TRUE(ErrorsFound); EXPECT_TRUE(compare_err_stream_substring(delimited_string({ + " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE", + " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE", " ** ~~~ ** Window surface area=[95.06] m2, divider area=[95.10] m2.", - + " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE2", + " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE2", + " ** ~~~ ** ProcessSurfaceVertices: Number of vertical dividers=[20], divider width=[0.50] m, glazed opening width=[9.70] m.", + " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE3", + " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[50], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE3", + " ** ~~~ ** ProcessSurfaceVertices: Number of vertical dividers=[50], divider width=[0.50] m, glazed opening width=[9.70] m.", + " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE3", + " ** ~~~ ** Window surface area=[95.06] m2, divider area=[-137.50] m2." }))); + + int surfNum1 = Util::FindItemInList("FENESTRATIONSURFACE", state->dataSurface->Surface); + EXPECT_GT(surfNum1, 0); + int surfNum2 = Util::FindItemInList("FENESTRATIONSURFACE2", state->dataSurface->Surface); + EXPECT_GT(surfNum2, 0); + int surfNum3 = Util::FindItemInList("FENESTRATIONSURFACE3", state->dataSurface->Surface); + EXPECT_GT(surfNum3, 0); + + EXPECT_GT(state->dataSurface->SurfWinDividerArea(surfNum1), state->dataSurface->Surface(surfNum1).Area); + EXPECT_GT(95.06 - state->dataSurface->SurfWinDividerArea(surfNum2), 0); + EXPECT_GT(0, state->dataSurface->SurfWinDividerArea(surfNum3)); } TEST_F(EnergyPlusFixture, SurfaceGeometry_GetVerticesDropDuplicates) From 7cdddc2bd54443f76c9724331548a119356054e3 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 8 Jun 2026 13:49:31 -0700 Subject: [PATCH 3/8] Formatting. --- tst/EnergyPlus/unit/SurfaceGeometry.unit.cc | 31 ++++++++++----------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc index 903ad52789c..306e3d8d2fb 100644 --- a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc +++ b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc @@ -12982,22 +12982,21 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_BadDividerGeometry) HeatBalanceManager::GetBuildingData(*state, ErrorsFound); EXPECT_TRUE(ErrorsFound); - EXPECT_TRUE(compare_err_stream_substring(delimited_string({ - " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE", - " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", - " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE", - " ** ~~~ ** Window surface area=[95.06] m2, divider area=[95.10] m2.", - " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE2", - " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", - " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE2", - " ** ~~~ ** ProcessSurfaceVertices: Number of vertical dividers=[20], divider width=[0.50] m, glazed opening width=[9.70] m.", - " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE3", - " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[50], divider width=[0.50] m, glazed opening height=[9.80] m.", - " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE3", - " ** ~~~ ** ProcessSurfaceVertices: Number of vertical dividers=[50], divider width=[0.50] m, glazed opening width=[9.70] m.", - " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE3", - " ** ~~~ ** Window surface area=[95.06] m2, divider area=[-137.50] m2." - }))); + EXPECT_TRUE(compare_err_stream_substring(delimited_string( + {" ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE", + " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE", + " ** ~~~ ** Window surface area=[95.06] m2, divider area=[95.10] m2.", + " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE2", + " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE2", + " ** ~~~ ** ProcessSurfaceVertices: Number of vertical dividers=[20], divider width=[0.50] m, glazed opening width=[9.70] m.", + " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE3", + " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[50], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE3", + " ** ~~~ ** ProcessSurfaceVertices: Number of vertical dividers=[50], divider width=[0.50] m, glazed opening width=[9.70] m.", + " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE3", + " ** ~~~ ** Window surface area=[95.06] m2, divider area=[-137.50] m2."}))); int surfNum1 = Util::FindItemInList("FENESTRATIONSURFACE", state->dataSurface->Surface); EXPECT_GT(surfNum1, 0); From 258bfb99d669deba494e2098a03ee706d8607ced Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 8 Jun 2026 14:02:32 -0700 Subject: [PATCH 4/8] Formatting. --- src/EnergyPlus/SurfaceGeometry.cc | 41 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/EnergyPlus/SurfaceGeometry.cc b/src/EnergyPlus/SurfaceGeometry.cc index 5f55c3d7ff6..71df2926d91 100644 --- a/src/EnergyPlus/SurfaceGeometry.cc +++ b/src/EnergyPlus/SurfaceGeometry.cc @@ -13036,33 +13036,38 @@ namespace SurfaceGeometry { DivWidth = state.dataSurface->FrameDivider(surf.FrameDivider).DividerWidth; if (DivWidth > 0.0 && !ErrorInSurface) { if (DivWidth * state.dataSurface->FrameDivider(FrDivNum).HorDividers > surf.Height) { - ShowSevereError(state, std::format("{}Horizontal dividers exceed glazed opening height for window {}", RoutineName, surf.Name)); - ShowContinueError(state, std::format("{}Number of horizontal dividers=[{}], divider width=[{:.2f}] m, glazed opening height=[{:.2f}] m.", - RoutineName, - state.dataSurface->FrameDivider(FrDivNum).HorDividers, - DivWidth, - surf.Height)); + ShowSevereError(state, + std::format("{}Horizontal dividers exceed glazed opening height for window {}", RoutineName, surf.Name)); + ShowContinueError( + state, + std::format("{}Number of horizontal dividers=[{}], divider width=[{:.2f}] m, glazed opening height=[{:.2f}] m.", + RoutineName, + state.dataSurface->FrameDivider(FrDivNum).HorDividers, + DivWidth, + surf.Height)); ErrorInSurface = true; } if (DivWidth * state.dataSurface->FrameDivider(FrDivNum).VertDividers > surf.Width) { - ShowSevereError(state, std::format("{}Vertical dividers exceed glazed opening width for window {}", RoutineName, surf.Name)); - ShowContinueError(state, std::format("{}Number of vertical dividers=[{}], divider width=[{:.2f}] m, glazed opening width=[{:.2f}] m.", - RoutineName, - state.dataSurface->FrameDivider(FrDivNum).VertDividers, - DivWidth, - surf.Width)); + ShowSevereError(state, + std::format("{}Vertical dividers exceed glazed opening width for window {}", RoutineName, surf.Name)); + ShowContinueError( + state, + std::format("{}Number of vertical dividers=[{}], divider width=[{:.2f}] m, glazed opening width=[{:.2f}] m.", + RoutineName, + state.dataSurface->FrameDivider(FrDivNum).VertDividers, + DivWidth, + surf.Width)); ErrorInSurface = true; } - Real64 const DivLenTotal = state.dataSurface->FrameDivider(FrDivNum).HorDividers * surf.Width + state.dataSurface->FrameDivider(FrDivNum).VertDividers * surf.Height; - Real64 const DivLenOvlp = state.dataSurface->FrameDivider(FrDivNum).HorDividers * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth; + Real64 const DivLenTotal = state.dataSurface->FrameDivider(FrDivNum).HorDividers * surf.Width + + state.dataSurface->FrameDivider(FrDivNum).VertDividers * surf.Height; + Real64 const DivLenOvlp = + state.dataSurface->FrameDivider(FrDivNum).HorDividers * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth; DivArea = DivWidth * (DivLenTotal - DivLenOvlp); state.dataSurface->SurfWinDividerArea(ThisSurf) = DivArea * surf.Multiplier; if (DivArea <= 0.0) { ShowSevereError(state, std::format("{}Divider area exceeds glazed opening for window {}", RoutineName, surf.Name)); - ShowContinueError(state, - std::format("Window surface area=[{:.2f}] m2, divider area=[{:.2f}] m2.", - surf.Area, - DivArea)); + ShowContinueError(state, std::format("Window surface area=[{:.2f}] m2, divider area=[{:.2f}] m2.", surf.Area, DivArea)); ErrorInSurface = true; } else if ((surf.Area - state.dataSurface->SurfWinDividerArea(ThisSurf)) <= 0.0) { ShowSevereError(state, std::format("{}Divider area exceeds glazed opening for window {}", RoutineName, surf.Name)); From 448a99b7a49e562b03336e846749e72551c574b6 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 8 Jun 2026 15:01:59 -0700 Subject: [PATCH 5/8] Clean up checks and unit test per review. --- src/EnergyPlus/SurfaceGeometry.cc | 13 +++++++------ tst/EnergyPlus/unit/SurfaceGeometry.unit.cc | 14 +++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/EnergyPlus/SurfaceGeometry.cc b/src/EnergyPlus/SurfaceGeometry.cc index 71df2926d91..db54a1cbdb4 100644 --- a/src/EnergyPlus/SurfaceGeometry.cc +++ b/src/EnergyPlus/SurfaceGeometry.cc @@ -13040,8 +13040,7 @@ namespace SurfaceGeometry { std::format("{}Horizontal dividers exceed glazed opening height for window {}", RoutineName, surf.Name)); ShowContinueError( state, - std::format("{}Number of horizontal dividers=[{}], divider width=[{:.2f}] m, glazed opening height=[{:.2f}] m.", - RoutineName, + std::format("Number of horizontal dividers=[{}], divider width=[{:.2f}] m, glazed opening height=[{:.2f}] m.", state.dataSurface->FrameDivider(FrDivNum).HorDividers, DivWidth, surf.Height)); @@ -13052,8 +13051,7 @@ namespace SurfaceGeometry { std::format("{}Vertical dividers exceed glazed opening width for window {}", RoutineName, surf.Name)); ShowContinueError( state, - std::format("{}Number of vertical dividers=[{}], divider width=[{:.2f}] m, glazed opening width=[{:.2f}] m.", - RoutineName, + std::format("Number of vertical dividers=[{}], divider width=[{:.2f}] m, glazed opening width=[{:.2f}] m.", state.dataSurface->FrameDivider(FrDivNum).VertDividers, DivWidth, surf.Width)); @@ -13066,8 +13064,11 @@ namespace SurfaceGeometry { DivArea = DivWidth * (DivLenTotal - DivLenOvlp); state.dataSurface->SurfWinDividerArea(ThisSurf) = DivArea * surf.Multiplier; if (DivArea <= 0.0) { - ShowSevereError(state, std::format("{}Divider area exceeds glazed opening for window {}", RoutineName, surf.Name)); - ShowContinueError(state, std::format("Window surface area=[{:.2f}] m2, divider area=[{:.2f}] m2.", surf.Area, DivArea)); + ShowSevereError(state, std::format("{}Calculated divider area <= 0.0 for window {}", RoutineName, surf.Name)); + ShowContinueError(state, + std::format("Window surface area=[{:.2f}] m2, divider area=[{:.2f}] m2.", + surf.Area, + state.dataSurface->SurfWinDividerArea(ThisSurf))); ErrorInSurface = true; } else if ((surf.Area - state.dataSurface->SurfWinDividerArea(ThisSurf)) <= 0.0) { ShowSevereError(state, std::format("{}Divider area exceeds glazed opening for window {}", RoutineName, surf.Name)); diff --git a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc index 306e3d8d2fb..b300e53337a 100644 --- a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc +++ b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc @@ -12984,18 +12984,18 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_BadDividerGeometry) EXPECT_TRUE(ErrorsFound); EXPECT_TRUE(compare_err_stream_substring(delimited_string( {" ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE", - " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** ~~~ ** Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE", " ** ~~~ ** Window surface area=[95.06] m2, divider area=[95.10] m2.", " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE2", - " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** ~~~ ** Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE2", - " ** ~~~ ** ProcessSurfaceVertices: Number of vertical dividers=[20], divider width=[0.50] m, glazed opening width=[9.70] m.", + " ** ~~~ ** Number of vertical dividers=[20], divider width=[0.50] m, glazed opening width=[9.70] m.", " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE3", - " ** ~~~ ** ProcessSurfaceVertices: Number of horizontal dividers=[50], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** ~~~ ** Number of horizontal dividers=[50], divider width=[0.50] m, glazed opening height=[9.80] m.", " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE3", - " ** ~~~ ** ProcessSurfaceVertices: Number of vertical dividers=[50], divider width=[0.50] m, glazed opening width=[9.70] m.", - " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE3", + " ** ~~~ ** Number of vertical dividers=[50], divider width=[0.50] m, glazed opening width=[9.70] m.", + " ** Severe ** ProcessSurfaceVertices: Calculated divider area <= 0.0 for window FENESTRATIONSURFACE3", " ** ~~~ ** Window surface area=[95.06] m2, divider area=[-137.50] m2."}))); int surfNum1 = Util::FindItemInList("FENESTRATIONSURFACE", state->dataSurface->Surface); @@ -13006,7 +13006,7 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_BadDividerGeometry) EXPECT_GT(surfNum3, 0); EXPECT_GT(state->dataSurface->SurfWinDividerArea(surfNum1), state->dataSurface->Surface(surfNum1).Area); - EXPECT_GT(95.06 - state->dataSurface->SurfWinDividerArea(surfNum2), 0); + EXPECT_GT(95.06, state->dataSurface->SurfWinDividerArea(surfNum2)); // divider error doesn't exceed but we still get other severe error(s) EXPECT_GT(0, state->dataSurface->SurfWinDividerArea(surfNum3)); } From 80427a59f8c6887642cb2fe631febc888dfe2631 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 9 Jun 2026 08:56:21 -0700 Subject: [PATCH 6/8] Formatting. --- tst/EnergyPlus/unit/SurfaceGeometry.unit.cc | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc index b300e53337a..8b73e015844 100644 --- a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc +++ b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc @@ -12982,21 +12982,21 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_BadDividerGeometry) HeatBalanceManager::GetBuildingData(*state, ErrorsFound); EXPECT_TRUE(ErrorsFound); - EXPECT_TRUE(compare_err_stream_substring(delimited_string( - {" ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE", - " ** ~~~ ** Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", - " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE", - " ** ~~~ ** Window surface area=[95.06] m2, divider area=[95.10] m2.", - " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE2", - " ** ~~~ ** Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", - " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE2", - " ** ~~~ ** Number of vertical dividers=[20], divider width=[0.50] m, glazed opening width=[9.70] m.", - " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE3", - " ** ~~~ ** Number of horizontal dividers=[50], divider width=[0.50] m, glazed opening height=[9.80] m.", - " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE3", - " ** ~~~ ** Number of vertical dividers=[50], divider width=[0.50] m, glazed opening width=[9.70] m.", - " ** Severe ** ProcessSurfaceVertices: Calculated divider area <= 0.0 for window FENESTRATIONSURFACE3", - " ** ~~~ ** Window surface area=[95.06] m2, divider area=[-137.50] m2."}))); + EXPECT_TRUE(compare_err_stream_substring( + delimited_string({" ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE", + " ** ~~~ ** Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE", + " ** ~~~ ** Window surface area=[95.06] m2, divider area=[95.10] m2.", + " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE2", + " ** ~~~ ** Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE2", + " ** ~~~ ** Number of vertical dividers=[20], divider width=[0.50] m, glazed opening width=[9.70] m.", + " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE3", + " ** ~~~ ** Number of horizontal dividers=[50], divider width=[0.50] m, glazed opening height=[9.80] m.", + " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE3", + " ** ~~~ ** Number of vertical dividers=[50], divider width=[0.50] m, glazed opening width=[9.70] m.", + " ** Severe ** ProcessSurfaceVertices: Calculated divider area <= 0.0 for window FENESTRATIONSURFACE3", + " ** ~~~ ** Window surface area=[95.06] m2, divider area=[-137.50] m2."}))); int surfNum1 = Util::FindItemInList("FENESTRATIONSURFACE", state->dataSurface->Surface); EXPECT_GT(surfNum1, 0); From 9552be70c0b1c2db8a9a778454cfc9f807b27519 Mon Sep 17 00:00:00 2001 From: Matt Mitchell Date: Tue, 9 Jun 2026 13:32:56 -0600 Subject: [PATCH 7/8] simplify divider calcs --- src/EnergyPlus/SurfaceGeometry.cc | 34 ++++++++------------- tst/EnergyPlus/unit/SurfaceGeometry.unit.cc | 17 +---------- 2 files changed, 13 insertions(+), 38 deletions(-) diff --git a/src/EnergyPlus/SurfaceGeometry.cc b/src/EnergyPlus/SurfaceGeometry.cc index db54a1cbdb4..8b1c3587693 100644 --- a/src/EnergyPlus/SurfaceGeometry.cc +++ b/src/EnergyPlus/SurfaceGeometry.cc @@ -13057,28 +13057,18 @@ namespace SurfaceGeometry { surf.Width)); ErrorInSurface = true; } - Real64 const DivLenTotal = state.dataSurface->FrameDivider(FrDivNum).HorDividers * surf.Width + - state.dataSurface->FrameDivider(FrDivNum).VertDividers * surf.Height; - Real64 const DivLenOvlp = - state.dataSurface->FrameDivider(FrDivNum).HorDividers * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth; - DivArea = DivWidth * (DivLenTotal - DivLenOvlp); - state.dataSurface->SurfWinDividerArea(ThisSurf) = DivArea * surf.Multiplier; - if (DivArea <= 0.0) { - ShowSevereError(state, std::format("{}Calculated divider area <= 0.0 for window {}", RoutineName, surf.Name)); - ShowContinueError(state, - std::format("Window surface area=[{:.2f}] m2, divider area=[{:.2f}] m2.", - surf.Area, - state.dataSurface->SurfWinDividerArea(ThisSurf))); - ErrorInSurface = true; - } else if ((surf.Area - state.dataSurface->SurfWinDividerArea(ThisSurf)) <= 0.0) { - ShowSevereError(state, std::format("{}Divider area exceeds glazed opening for window {}", RoutineName, surf.Name)); - ShowContinueError(state, - std::format("Window surface area=[{:.2f}] m2, divider area=[{:.2f}] m2.", - surf.Area, - state.dataSurface->SurfWinDividerArea(ThisSurf))); - ErrorInSurface = true; - } else { - surf.Area -= state.dataSurface->SurfWinDividerArea(ThisSurf); // Glazed area + if (!ErrorInSurface) { + // total divider length + Real64 const DivLenTotal = state.dataSurface->FrameDivider(FrDivNum).HorDividers * surf.Width + + state.dataSurface->FrameDivider(FrDivNum).VertDividers * surf.Height; + // length of dividers overlapping themselves + Real64 const DivLenOvlp = state.dataSurface->FrameDivider(FrDivNum).HorDividers * + state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth; + // actual divider area minus self-overlap + DivArea = DivWidth * (DivLenTotal - DivLenOvlp); + state.dataSurface->SurfWinDividerArea(ThisSurf) = DivArea * surf.Multiplier; + // Glazed area + surf.Area -= state.dataSurface->SurfWinDividerArea(ThisSurf); } } diff --git a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc index 8b73e015844..9be567173bf 100644 --- a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc +++ b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc @@ -12985,8 +12985,6 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_BadDividerGeometry) EXPECT_TRUE(compare_err_stream_substring( delimited_string({" ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE", " ** ~~~ ** Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", - " ** Severe ** ProcessSurfaceVertices: Divider area exceeds glazed opening for window FENESTRATIONSURFACE", - " ** ~~~ ** Window surface area=[95.06] m2, divider area=[95.10] m2.", " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE2", " ** ~~~ ** Number of horizontal dividers=[20], divider width=[0.50] m, glazed opening height=[9.80] m.", " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE2", @@ -12994,20 +12992,7 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_BadDividerGeometry) " ** Severe ** ProcessSurfaceVertices: Horizontal dividers exceed glazed opening height for window FENESTRATIONSURFACE3", " ** ~~~ ** Number of horizontal dividers=[50], divider width=[0.50] m, glazed opening height=[9.80] m.", " ** Severe ** ProcessSurfaceVertices: Vertical dividers exceed glazed opening width for window FENESTRATIONSURFACE3", - " ** ~~~ ** Number of vertical dividers=[50], divider width=[0.50] m, glazed opening width=[9.70] m.", - " ** Severe ** ProcessSurfaceVertices: Calculated divider area <= 0.0 for window FENESTRATIONSURFACE3", - " ** ~~~ ** Window surface area=[95.06] m2, divider area=[-137.50] m2."}))); - - int surfNum1 = Util::FindItemInList("FENESTRATIONSURFACE", state->dataSurface->Surface); - EXPECT_GT(surfNum1, 0); - int surfNum2 = Util::FindItemInList("FENESTRATIONSURFACE2", state->dataSurface->Surface); - EXPECT_GT(surfNum2, 0); - int surfNum3 = Util::FindItemInList("FENESTRATIONSURFACE3", state->dataSurface->Surface); - EXPECT_GT(surfNum3, 0); - - EXPECT_GT(state->dataSurface->SurfWinDividerArea(surfNum1), state->dataSurface->Surface(surfNum1).Area); - EXPECT_GT(95.06, state->dataSurface->SurfWinDividerArea(surfNum2)); // divider error doesn't exceed but we still get other severe error(s) - EXPECT_GT(0, state->dataSurface->SurfWinDividerArea(surfNum3)); + " ** ~~~ ** Number of vertical dividers=[50], divider width=[0.50] m, glazed opening width=[9.70] m."}))); } TEST_F(EnergyPlusFixture, SurfaceGeometry_GetVerticesDropDuplicates) From d0aedd7666974298807b248e5f36d1800ec74fb4 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 9 Jun 2026 12:40:02 -0700 Subject: [PATCH 8/8] Update docs with divider limitations. --- .../src/overview/group-thermal-zone-description-geometry.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/input-output-reference/src/overview/group-thermal-zone-description-geometry.tex b/doc/input-output-reference/src/overview/group-thermal-zone-description-geometry.tex index fdf04a0d4e4..05ac62fc52d 100644 --- a/doc/input-output-reference/src/overview/group-thermal-zone-description-geometry.tex +++ b/doc/input-output-reference/src/overview/group-thermal-zone-description-geometry.tex @@ -4971,11 +4971,11 @@ \subsubsection{Inputs}\label{inputs-33-001} \paragraph{Field: Number of Horizontal Dividers}\label{field-number-of-horizontal-dividers} -The number of divider elements parallel to the top and bottom of the window. Default: 0. +The number of divider elements parallel to the top and bottom of the window. Default: 0. The total horizontal divider width (Divider Width times Number of Horizontal Dividers) must not exceed the glazed opening height of the window. \paragraph{Field: Number of Vertical Dividers}\label{field-number-of-vertical-dividers} -The number of divider elements parallel to the sides of the window. Default: 0. +The number of divider elements parallel to the sides of the window. Default: 0. The total vertical divider width (Divider Width times Number of Vertical Dividers) must not exceed the glazed opening width of the window. \paragraph{Field: Divider Outside Projection}\label{field-divider-outside-projection}