Skip to content
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 vector error for when a zone or space has no surfaces #10309

Merged
merged 5 commits into from Dec 1, 2023

Conversation

mjwitte
Copy link
Contributor

@mjwitte mjwitte commented Nov 29, 2023

Pull request overview

  • Fixes Vector error when zone has no surfaces #10305
  • Protect against using invalid AllSurfaceFirst/Last as a subscript.
  • Clean up some related error messages.
  • Allow a space to have no surfaces.
  • But an enclosure with no surfaces will still fatal out.

Pull Request Author

Add to this list or remove from it as applicable. This is a simple templated set of guidelines.

  • Title of PR should be user-synopsis style (clearly understandable in a standalone changelog context)
  • Label the PR with at least one of: Defect, Refactoring, NewFeature, Performance, and/or DoNoPublish
  • Pull requests that impact EnergyPlus code must also include unit tests to cover enhancement or defect repair
  • Author should provide a "walkthrough" of relevant code changes using a GitHub code review comment process
  • If any diffs are expected, author must demonstrate they are justified using plots and descriptions
  • If changes fix a defect, the fix should be demonstrated in plots and descriptions
  • If any defect files are updated to a more recent version, upload new versions here or on DevSupport
  • If IDD requires transition, transition source, rules, ExpandObjects, and IDFs must be updated, and add IDDChange label
  • If structural output changes, add to output rules file and add OutputChange label
  • If adding/removing any LaTeX docs or figures, update that document's CMakeLists file dependencies

Reviewer

This will not be exhaustively relevant to every PR.

  • Perform a Code Review on GitHub
  • If branch is behind develop, merge develop and build locally to check for side effects of the merge
  • If defect, verify by running develop branch and reproducing defect, then running PR and reproducing fix
  • If feature, test running new feature, try creative ways to break it
  • CI status: all green or justified
  • Check that performance is not impacted (CI Linux results include performance check)
  • Run Unit Test(s) locally
  • Check any new function arguments for performance impacts
  • Verify IDF naming conventions and styles, memos and notes and defaults
  • If new idf included, locally check the err file and other outputs

@mjwitte mjwitte added the Defect Includes code to repair a defect in EnergyPlus label Nov 29, 2023
@mjwitte
Copy link
Contributor Author

mjwitte commented Nov 30, 2023

Defect file error output before:

   ** Severe  ** vector too long
   ************* Warning:  Node connection errors not checked - most system input has not been read (see previous warning).
   ************* Fatal error -- final processing.  Program exited before simulations began.  See previous error messages.

With this branch;

   ** Warning ** createSpaceSurfaceLists: Space=PLENUM-1 has no surfaces.
   ** Warning ** No floor exists in Zone="PLENUM-1", zone floor area is zero. All values for this zone that are entered per floor area will be zero.
   ** Warning ** CheckUsedConstructions: There are 2 nominally unused constructions in input.
   **   ~~~   ** For explicit details on each unused construction, use Output:Diagnostics,DisplayExtraWarnings;
   ** Severe  ** InitSolarViewFactors: No surfaces in enclosure=PLENUM-1.
   ** Warning ** Surfaces in Zone/Enclosure="PLENUM-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.
   **  Fatal  ** InitSolarViewFactors: Errors found during initialization of diffuse solar distribution.  Program terminated.

Copy link
Contributor Author

@mjwitte mjwitte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code walk through.

@@ -499,7 +500,10 @@ namespace HeatBalanceIntRadExchange {
thisEnclosure.NumOfSurfaces = numEnclosureSurfaces;
state.dataHeatBalIntRadExchg->MaxNumOfRadEnclosureSurfs =
max(state.dataHeatBalIntRadExchg->MaxNumOfRadEnclosureSurfs, numEnclosureSurfaces);
if (numEnclosureSurfaces < 1) ShowFatalError(state, "No surfaces in an enclosure in InitInteriorRadExchange");
if (numEnclosureSurfaces < 1) {
ShowSevereError(state, format("{}No surfaces in enclosure={}.", RoutineName, thisEnclosure.Name));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some error message cleanup - should throw a severe here and set ErrorsFound, then fatal throws later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a nice addition - let it find more errors on the first pass.

Real64 TotSurfArea = 0.0;
thisZone.Centroid = Vector(0.0, 0.0, 0.0);
if (state.dataSurface->Surface(thisZone.AllSurfaceFirst).Sides > 0) {
if ((thisZone.AllSurfaceFirst > 0) && (state.dataSurface->Surface(thisZone.AllSurfaceFirst).Sides > 0)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check for valid subscript before using it.

Comment on lines +577 to +581
if (thisSurface.Class == SurfaceClass::IntMass) {
internalMassSurfacesPresent = true;
continue;
}
if (!thisSurface.IsAirBoundarySurf) nonInternalMassSurfacesPresent = true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean up this check. Previously, the internal mass warning below was firing even when there was no internal mass in the zone (or any surfaces at all). Also, an air boundary surface shouldn't be counted as a valid nonInternalMassSurface.

@@ -2257,110 +2261,7 @@ namespace SurfaceGeometry {
}
}

//**********************************************************************************
// Set up Zone Surface Pointers
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The methodology here for setting *SurfaceFirst/Last for zone and spaces was flawed, especially if a space had no surfaces. This has been redone and move to a new function setSurfaceFirstLast.

Comment on lines -3014 to +2917
// TODO MJW: Is this necessary? Check that all Spaces have at least one Surface
for (int spaceNum = 1; spaceNum < state.dataGlobal->numSpaces; ++spaceNum) {
for (int spaceNum = 1; spaceNum <= state.dataGlobal->numSpaces; ++spaceNum) {
if (int(state.dataHeatBal->space(spaceNum).surfaces.size()) == 0) {
ShowSevereError(state, format("{}Space = {} has no surfaces.", RoutineName, state.dataHeatBal->space(spaceNum).Name));
ErrorsFound = true;
ShowWarningError(state, format("{}Space={} has no surfaces.", RoutineName, state.dataHeatBal->space(spaceNum).Name));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this to allow a space with no surfaces to pass through. However, if an enclosure has no surfaces, that will severe/fatal out. This does open the possibility of having a space with no surfaces sharing the same enclosure with other space(s) that do have surfaces. So, is that something we really want to allow?

}
}
}

void setSurfaceFirstLast(EnergyPlusData &state)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new function with a more robust method.

@@ -8661,10 +8661,6 @@ TEST_F(EnergyPlusFixture, GetSurfaceData_SurfaceOrder)

SetupZoneGeometry(*state, ErrorsFound);
EXPECT_FALSE(ErrorsFound); // expect no errors

GetSurfaceData(*state, ErrorsFound); // setup zone geometry and get zone data
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is already called from SetupZoneGeometry. Otherwise, no substantive changes to the exisiting GetSurfaceData_SurfaceOrder unit test.

@@ -9058,6 +9054,2395 @@ TEST_F(EnergyPlusFixture, GetSurfaceData_SurfaceOrder)
EXPECT_FALSE(std::find(HTKivaSurfaces.begin(), HTKivaSurfaces.end(), thisSurface) != HTKivaSurfaces.end());
}

TEST_F(EnergyPlusFixture, GetSurfaceData_SurfaceOrder2)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added three new unit tests that are subsets of GetSurfaceData_SurfaceOrder where the first zone/space has no surfaces (GetSurfaceData_SurfaceOrder2), the middle zone has no surfaces (GetSurfaceData_SurfaceOrder3), and the last zone has no surfaces (GetSurfaceData_SurfaceOrder4).

@mjwitte mjwitte marked this pull request as ready for review November 30, 2023 21:09
@mjwitte
Copy link
Contributor Author

mjwitte commented Nov 30, 2023

CI is all green. Ready for review.

Copy link
Member

@Myoldmopar Myoldmopar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great to me. Thanks @mjwitte

@@ -499,7 +500,10 @@ namespace HeatBalanceIntRadExchange {
thisEnclosure.NumOfSurfaces = numEnclosureSurfaces;
state.dataHeatBalIntRadExchg->MaxNumOfRadEnclosureSurfs =
max(state.dataHeatBalIntRadExchg->MaxNumOfRadEnclosureSurfs, numEnclosureSurfaces);
if (numEnclosureSurfaces < 1) ShowFatalError(state, "No surfaces in an enclosure in InitInteriorRadExchange");
if (numEnclosureSurfaces < 1) {
ShowSevereError(state, format("{}No surfaces in enclosure={}.", RoutineName, thisEnclosure.Name));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a nice addition - let it find more errors on the first pass.

int firstSpaceNum = state.dataHeatBal->Zone(ZoneNum).spaceIndexes(1);
state.dataHeatBal->Zone(ZoneNum).AllSurfaceFirst = state.dataHeatBal->space(firstSpaceNum).AllSurfaceFirst;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a little difficult to grasp the changes since the code is moved entirely, but I understand that this is a positive move. And your unit tests are fleshed out heavily, so that builds confidence.

@Myoldmopar
Copy link
Member

CI is 100% green, and this branch is up to date with develop, so this goes right in. Thanks @mjwitte

@Myoldmopar Myoldmopar merged commit 4ccd87a into develop Dec 1, 2023
15 checks passed
@Myoldmopar Myoldmopar deleted the ZoneNoSurfs10305 branch December 1, 2023 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Defect Includes code to repair a defect in EnergyPlus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Vector error when zone has no surfaces
7 participants