-
Notifications
You must be signed in to change notification settings - Fork 392
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
Storm window refactoring #8674
Conversation
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.
@xuanluo113 This is a great improvement - another example of setting something up front instead of checking and re-checking in multiple places.
src/EnergyPlus/DataSurfaces.hh
Outdated
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) |
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.
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)
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.
I don't see why they are wrong. Can you suggest?
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.
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.
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.
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);
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.
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.
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.
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; |
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.
Should be? int ConstrNum = state.dataSurface->SurfWinActiveConstruction(SurfNum);
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.
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.
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.
Ok, one step at a time here.
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.
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.
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.
@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.
src/EnergyPlus/SolarShading.cc
Outdated
int ConstrNum = state.dataSurface->Surface(SurfNum).Construction; | ||
if (state.dataSurface->SurfWinStormWinFlag(SurfNum) == 1) { | ||
ConstrNum = state.dataSurface->Surface(SurfNum).StormWinConstruction; | ||
ConstrNum = state.dataSurface->SurfWinStormWinConstr(SurfNum); |
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.
Can these lines be replaced with int ConstrNum = state.dataSurface->SurfWinActiveConstruction(SurfNum);
?
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.
This is removed.
src/EnergyPlus/SolarShading.cc
Outdated
ConstrNum = state.dataSurface->SurfWinActiveConstruction(SurfNum); | ||
ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); |
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.
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?
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.
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;
}
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.
I added the checking of 5DETAILSMODEL
and make most of the assignment local and static.
for (int SurfNum = 1; SurfNum <= state->dataSurface->TotSurfaces; SurfNum++) { | ||
state->dataSurface->SurfWinActiveConstruction(SurfNum) = state->dataSurface->Surface(SurfNum).Construction; | ||
} |
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.
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.
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.
The assignment is added to the end of GetSurfaceData
and these initialization are removed.
@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) { |
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.
Is this on your do-list for later to move this loop to a separate function and simply loop over opaque surfaces?
src/EnergyPlus/HeatBalanceManager.cc
Outdated
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; | ||
} | ||
} |
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.
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
?
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.
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.
@xuanluo113 So, the last set of changes caused diffs in some EMS test files (that modify constructions). Which is correct, before or after? |
@mjwitte Yes. I'm debugging that issue. |
Fixed a bug to synchronize the change to |
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.
@xuanluo113 Thanks, looks good.
Arrgh, I didn't check the clangformat test before merging. Will push a fix shortly. |
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.
Reviewer
This will not be exhaustively relevant to every PR.