-
Notifications
You must be signed in to change notification settings - Fork 389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #10103 - CheckConvexity removes colinear vertices but stops when surface is determined non-convex, causing vertex size mismatch fatal error #10114
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15788,30 +15788,33 @@ namespace SurfaceGeometry { | |
} | ||
|
||
if (SignFlag != PrevSignFlag) { | ||
if (state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal && surfaceTmp.ExtSolar) { | ||
if (state.dataGlobal->DisplayExtraWarnings) { | ||
ShowWarningError(state, | ||
format("CheckConvexity: Zone=\"{}\", Surface=\"{}\" is non-convex.", | ||
state.dataHeatBal->Zone(surfaceTmp.Zone).Name, | ||
surfaceTmp.Name)); | ||
int Np1 = n + 1; | ||
if (Np1 > NSides) { | ||
Np1 -= NSides; | ||
} | ||
int Np2 = n + 2; | ||
if (Np2 > NSides) { | ||
Np2 -= NSides; | ||
} | ||
ShowContinueError(state, format("...vertex {} to vertex {} to vertex {}", n, Np1, Np2)); | ||
ShowContinueError(state, format("...vertex {}=[{:.2R},{:.2R},{:.2R}]", n, X(n), Y(n), Z(n))); | ||
ShowContinueError(state, format("...vertex {}=[{:.2R},{:.2R},{:.2R}]", Np1, X(n + 1), Y(n + 1), Z(n + 1))); | ||
ShowContinueError(state, format("...vertex {}=[{:.2R},{:.2R},{:.2R}]", Np2, X(n + 2), Y(n + 2), Z(n + 2))); | ||
// ShowContinueError(state, format("...theta angle=[{:.6R}]", Theta)); | ||
// ShowContinueError(state, format("...last theta angle=[{:.6R}]", LastTheta)); | ||
} | ||
if (state.dataGlobal->DisplayExtraWarnings && surfaceTmp.ExtSolar && | ||
(state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal) && | ||
// Warn only once | ||
surfaceTmp.IsConvex) { | ||
ShowWarningError(state, | ||
format("CheckConvexity: Zone=\"{}\", Surface=\"{}\" is non-convex.", | ||
state.dataHeatBal->Zone(surfaceTmp.Zone).Name, | ||
surfaceTmp.Name)); | ||
int Np1 = n + 1; | ||
if (Np1 > NSides) { | ||
Np1 -= NSides; | ||
} | ||
int Np2 = n + 2; | ||
if (Np2 > NSides) { | ||
Np2 -= NSides; | ||
} | ||
ShowContinueError(state, format("...vertex {} to vertex {} to vertex {}", n, Np1, Np2)); | ||
ShowContinueError(state, format("...vertex {}=[{:.2R},{:.2R},{:.2R}]", n, X(n), Y(n), Z(n))); | ||
ShowContinueError(state, format("...vertex {}=[{:.2R},{:.2R},{:.2R}]", Np1, X(n + 1), Y(n + 1), Z(n + 1))); | ||
ShowContinueError(state, format("...vertex {}=[{:.2R},{:.2R},{:.2R}]", Np2, X(n + 2), Y(n + 2), Z(n + 2))); | ||
// ShowContinueError(state, format("...theta angle=[{:.6R}]", Theta)); | ||
// ShowContinueError(state, format("...last theta angle=[{:.6R}]", LastTheta)); | ||
} | ||
surfaceTmp.IsConvex = false; | ||
break; | ||
// #10103 - We do not want to break early, because we do want to consistently remove colinear vertices | ||
// to avoid potential vertex size mismatch fatal errors | ||
// break; | ||
Comment on lines
15814
to
+15817
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And do NOT break, so we ensure we do drop all colinear vertices and do not end up with a vertex size mistmatch. |
||
} | ||
PrevSignFlag = SignFlag; | ||
LastTheta = Theta; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3274,6 +3274,86 @@ TEST_F(EnergyPlusFixture, SurfaceGeometry_CheckConvexityTest_ASHRAE901_Hospital_ | |
EXPECT_FALSE(surface.IsConvex); | ||
} | ||
|
||
TEST_F(EnergyPlusFixture, SurfaceGeometry_CheckConvexity_ColinearStability) | ||
{ | ||
// Test for #10103 - Regardless of the order of the vertices, we should drop colinear vertices consistently to avoid a fatal error due to vertex | ||
// side mismatch | ||
// | ||
// y | ||
// ▲ 7 8 9 | ||
// │ ┌─────x────┐ | ||
// │ │ │ | ||
// │ │ │ | ||
// │ │ │ | ||
// │5 │ │ | ||
// ├──────────┘ │ | ||
// │ 6 │ | ||
// │ │ | ||
// │ │ | ||
// │ │10 | ||
// └────x─────x─────x────┴─────► | ||
// 4 3 2 1 x | ||
Comment on lines
+3279
to
+3295
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unit test case. We expect 1, 2, 3, and 8 to be dropped, resulting in 6 vertices in the end. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before the fix, the floor is checked in the order show above. so it drops 2 and 3, then finds a non convex situation when checking (5, 6, 7) and bails. We end up with 8 vertices. For the ceiling, the vertices are reversed. So it drops 8 (shown above, 3 in actual order), finds the non convex situation at (7, 6, 5) (shown above, (4, 5, 6 in actual order)) and bails. We end up with 9 vertices. (I explained the same on #10103 when I reported the defect) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
const std::vector<Vector> floorVertices = { | ||
{30.0, 0., 0.}, | ||
{20.0, 0., 0.}, | ||
{10.0, 0., 0.}, | ||
{0.0, 0., 0.}, | ||
{0.0, 20., 0.}, | ||
{20.0, 20., 0.}, | ||
{20.0, 40., 0.}, | ||
{30.0, 40., 0.}, | ||
{40.0, 40., 0.}, | ||
{40.0, 0., 0.}, | ||
}; | ||
const int nVertices = static_cast<int>(floorVertices.size()); | ||
|
||
state->dataSurface->TotSurfaces = 2; | ||
constexpr int floorSurfNum = 1; | ||
constexpr int ceilingSurfNum = 2; | ||
state->dataSurface->MaxVerticesPerSurface = nVertices; | ||
state->dataSurfaceGeometry->SurfaceTmp.allocate(state->dataSurface->TotSurfaces); | ||
|
||
auto &floorSurface = state->dataSurfaceGeometry->SurfaceTmp(floorSurfNum); | ||
auto &ceilingSurface = state->dataSurfaceGeometry->SurfaceTmp(ceilingSurfNum); | ||
{ | ||
floorSurface.Azimuth = 0.0; | ||
floorSurface.Tilt = 0.0; | ||
floorSurface.Sides = nVertices; | ||
floorSurface.GrossArea = 100.0; | ||
floorSurface.Name = "Floor"; | ||
floorSurface.Vertex.allocate(nVertices); | ||
|
||
floorSurface.Vertex = floorVertices; | ||
|
||
CheckConvexity(*state, floorSurfNum, floorSurface.Sides); | ||
|
||
EXPECT_EQ(6, floorSurface.Sides); | ||
EXPECT_FALSE(floorSurface.IsConvex); | ||
} | ||
|
||
{ | ||
auto ceilingVertices = floorVertices; | ||
std::reverse(ceilingVertices.begin(), ceilingVertices.end()); | ||
|
||
ceilingSurface.Azimuth = 0.0; | ||
ceilingSurface.Tilt = 0.0; | ||
ceilingSurface.Sides = nVertices; | ||
ceilingSurface.GrossArea = 100.0; | ||
ceilingSurface.Name = "Ceiling"; | ||
ceilingSurface.Vertex.allocate(nVertices); | ||
|
||
ceilingSurface.Vertex = ceilingVertices; | ||
|
||
CheckConvexity(*state, ceilingSurfNum, ceilingSurface.Sides); | ||
|
||
EXPECT_EQ(6, ceilingSurface.Sides); | ||
EXPECT_FALSE(ceilingSurface.IsConvex); | ||
} | ||
|
||
EXPECT_EQ(floorSurface.Sides, ceilingSurface.Sides); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before fix:
|
||
} | ||
|
||
TEST_F(EnergyPlusFixture, InitialAssociateWindowShadingControlFenestration_test) | ||
{ | ||
state->dataSurface->TotWinShadingControl = 3; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When warning, do it only once (when surfaceTmp.IsConvex, before that's set to false)