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

Storm window refactoring #8674

Merged
merged 22 commits into from
Apr 15, 2021
Merged

Storm window refactoring #8674

merged 22 commits into from
Apr 15, 2021

Conversation

xuanluo113
Copy link
Contributor

@xuanluo113 xuanluo113 commented Mar 30, 2021

Pull request overview

This branch refactors the logic of checking active structure and shaded structure of window surfaces when there is a storm window applies to the surface.

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

@xuanluo113 xuanluo113 added the Performance Includes code changes that are directed at improving the runtime performance of EnergyPlus label Mar 30, 2021
@xuanluo113 xuanluo113 added this to the EnergyPlus Future milestone Mar 30, 2021
@xuanluo113 xuanluo113 self-assigned this Mar 30, 2021
@xuanluo113 xuanluo113 marked this pull request as ready for review April 4, 2021 23:03
@xuanluo113 xuanluo113 requested a review from mjwitte April 4, 2021 23:04
Copy link
Contributor

@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.

@xuanluo113 This is a great improvement - another example of setting something up front instead of checking and re-checking in multiple places.

Comment on lines 1585 to 1586
Array1D<int> SurfWinActiveConstruction; // The currently active construction with storm window (windows only)
Array1D<int> SurfWinActiveShadedConstruction; // The currently active shaded construction with storm window (windows only)
Copy link
Contributor

Choose a reason for hiding this comment

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

These comment descriptions seem wrong. If I'm following correctly

 SurfWinActiveConstruction;            // The currently active unshaded construction with or without storm window (windows only)
SurfWinActiveShadedConstruction;      // The currently active shaded construction with or without storm window (windows only)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't see why they are wrong. Can you suggest?

Copy link
Contributor

Choose a reason for hiding this comment

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

The comment lines currently state "... with storm window" but these variables can be with or without storm window, correct? My comment wasn't clear, I was proposing new comments above.

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 is modified. Besides, I renamed SurfWinActiveConstruction to SurfActiveConstruction to change the current logic of

int constNum = Surface(i).Construction;
if (surface is window) constNum = SurfWinActiveConstruction(i);

to
int const constNum = SurfActiveConstruction(i);

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, that makes sense. So, do these active construction variables get updated correctly if there is an EMS actuator for "Construction State"? I guess if it wasn't, the regressions should catch it, but just wondering if you traced that logic to be sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. This time step reset of SurfWinActiveConstruction happens after InitEMSControlledConstructions (code), where Surface(i).Construction is overwritten by the EMS value. And yes a unit test HeatBalanceManager_EMSConstructionTest assured that.

@@ -2856,8 +2855,7 @@ void InitSolarHeatGains(EnergyPlusData &state)
int const firstSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst;
int const lastSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast;
for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
int ConstrNum = Surface(SurfNum).Construction;
if (state.dataSurface->SurfWinStormWinFlag(SurfNum) == 1) ConstrNum = Surface(SurfNum).StormWinConstruction;
int ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be? int ConstrNum = state.dataSurface->SurfWinActiveConstruction(SurfNum);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Originally I intended to only use SurfWinActiveConstruction to overwrite the exterior window constr index. The opaq surface loop would not need to be overwritten. It may be possible to use SurfActiveConstruction to overwrite any use case of Surface(i).Construction, because this logic

if (state.dataSurface->SurfWinStormWinFlag(SurfNum) == 1) {
    state.dataSurface->SurfWinActiveConstruction(SurfNum) = state.dataSurface->SurfWinStormWinConstr(SurfNum);
} else {
    state.dataSurface->SurfWinActiveConstruction(SurfNum) = state.dataSurface->Surface(SurfNum).Construction;
}

is set at the beginning of the simulation loop.

However, I don't know if the storm window index, when exists, is supposed to overwrite any construction index in any calculations. For example, I noticed that only when WindowModelType(SurfNum) == Window5DetailedModel, the constr index is overwritten, but for BSDF and EQL windows, the construction are still set as the original one (Surface(SurfNum).Construction). I checked the IO Ref and IDD notes and I don't see any restriction to attach a storm window when ComplexFenestration or EQL layers are applied.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, one step at a time here.

Copy link
Contributor

Choose a reason for hiding this comment

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

But this is inside a loop for opaque surfaces, so state.dataSurface->SurfWinStormWinFlag(SurfNum) does not apply here. I think line 2860 if (state.dataSurface->SurfWinStormWinFlag(SurfNum) == 1) ConstrNum = Surface(SurfNum).StormWinConstruction; can be deleted.

Copy link
Contributor Author

@xuanluo113 xuanluo113 Apr 8, 2021

Choose a reason for hiding this comment

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

@mjwitte Regarding this, I just mocked up a test case to apply StormWindow to an exterior window with equivalent layers (idf file attached) and no error checkings prevent me from doing so. The storm index is assigned to the window, but triggers a segfault here to get the Construct(ConstrNum).EQLConsPtr for the storm window construction. So I guess I should fix it by checking the window model here and wherever the storm window is overwriting the original construction number. This should be an existing defect in the develop branch.

EquivalentLayerWindow_test.idf.txt

src/EnergyPlus/HeatBalanceSurfaceManager.cc Outdated Show resolved Hide resolved
Comment on lines 8543 to 8545
int ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
if (state.dataSurface->SurfWinStormWinFlag(SurfNum) == 1) {
ConstrNum = state.dataSurface->Surface(SurfNum).StormWinConstruction;
ConstrNum = state.dataSurface->SurfWinStormWinConstr(SurfNum);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can these lines be replaced with int ConstrNum = state.dataSurface->SurfWinActiveConstruction(SurfNum);?

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 is removed.

Comment on lines 10971 to 10972
ConstrNum = state.dataSurface->SurfWinActiveConstruction(SurfNum);
ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally, it should be possible to localize the scope of every instance of ConstrNum= and ConstrNumSh = (or similar variables). And they should all be int const ConstrNum = Yes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same here. The logic is to assign ConstrNum to the original construction number at the beginning of the loop, but whether to overwrite depends on if the surface is a Window5DetailedModel window. Though ConstrNumSh is, in general, a const.
Maybe a better way of doing so is to check if 5DETAILSMODEL && EXTERIOR WINDOW when assigning.

if (state.dataSurface->SurfWinStormWinFlag(SurfNum) == 1 && 5DETAILSMODEL && ???) {
    state.dataSurface->SurfWinActiveConstruction(SurfNum) = state.dataSurface->SurfWinStormWinConstr(SurfNum);
} else {
    state.dataSurface->SurfWinActiveConstruction(SurfNum) = state.dataSurface->Surface(SurfNum).Construction;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added the checking of 5DETAILSMODEL and make most of the assignment local and static.

Comment on lines 858 to 860
for (int SurfNum = 1; SurfNum <= state->dataSurface->TotSurfaces; SurfNum++) {
state->dataSurface->SurfWinActiveConstruction(SurfNum) = state->dataSurface->Surface(SurfNum).Construction;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps state->dataSurface->SurfWinActiveConstruction(SurfNum) = state->dataSurface->Surface(SurfNum).Construction should be added to whatever function is setting Surface(SurfNum).Construction initially. Then it will always be initialized.

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 assignment is added to the end of GetSurfaceData and these initialization are removed.

@xuanluo113
Copy link
Contributor Author

@mjwitte Thanks for the review. The comments are addressed.

for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
if (Surface(SurfNum).Construction <= 0) continue; // Shading surface, not really a heat transfer surface
ConstrNum = Surface(SurfNum).Construction;
for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this on your do-list for later to move this loop to a separate function and simply loop over opaque surfaces?

Comment on lines 5567 to 5573
for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) {
if (state.dataSurface->SurfWinStormWinFlag(SurfNum) == 1 && state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::Window5DetailedModel) {
state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfWinStormWinConstr(SurfNum);
} else {
state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->Surface(SurfNum).Construction;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a slight performance slowdown for this branch in the performance suite test files (except performance.BenchmarkLargeOfficeNew_USA_CA_SAN_FRANCISCO_10_windows_per_zone which is slightly faster here). I wonder if this is the source of the few extra steps.
Can this loop be moved up inside the if (state.dataSurface->TotStormWin > 0 ? Also, this loop could be over zones then only window surfaces.
Or better yet, delete this entire loop and set state.dataSurface->SurfActiveConstruction(SurfNum) in SetStormWindowControl?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Any of those three approaches would work. Or rather option 1+2, or option 3.

Generally speaking, there is something very intuitively clean and compelling about moving to a "push" model (option 3). However, in practice, theory and practice are different and a push model often results either in the distribution of logic and the proliferation of dependences (which can sometimes be circular) or the use of a "callback style" of programming that is strange in different ways.

All that is to say, that we should probably go with option 1+2 for now because it is local, but then think of whether we want to go to option 3 in the near/medium future and what pattern we want to use to do that.

@mjwitte
Copy link
Contributor

mjwitte commented Apr 13, 2021

@xuanluo113 So, the last set of changes caused diffs in some EMS test files (that modify constructions). Which is correct, before or after?

@xuanluo113
Copy link
Contributor Author

@mjwitte Yes. I'm debugging that issue.

@xuanluo113
Copy link
Contributor Author

Fixed a bug to synchronize the change to surface.Contruction in run time to SurfActiveConstrucion(surfnum). The dependency is a little annoying but does not happen very often (in EMS, ThermochromicWindow, and adding a HT shelf).

Copy link
Contributor

@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.

@xuanluo113 Thanks, looks good.

@mjwitte mjwitte merged commit f72dfec into NREL:develop Apr 15, 2021
@mjwitte mjwitte deleted the storm-window branch April 15, 2021 13:20
@mjwitte
Copy link
Contributor

mjwitte commented Apr 15, 2021

Arrgh, I didn't check the clangformat test before merging. Will push a fix shortly.

@mjwitte mjwitte mentioned this pull request Apr 15, 2021
20 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Performance Includes code changes that are directed at improving the runtime performance of EnergyPlus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants