-
Notifications
You must be signed in to change notification settings - Fork 394
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
Add ability to automatically detect groups of similar surfaces for efficient heat balance calculations #8739
Conversation
@nealkruis @lgentile it has been 28 days since this pull request was last updated. |
2 similar comments
@nealkruis @lgentile it has been 28 days since this pull request was last updated. |
@nealkruis @lgentile it has been 28 days since this pull request was last updated. |
@nealkruis IIRC you were going to be doing something else to this branch. Adding/modifying the test file? I'm ready to test/review this just let me know. There appears to be a tiny conflict to resolve, I'm happy to do that, but if you want to pull develop in yourself that's fine too. I'm curious how this will play with the spaces PR....... (FYI @mjwitte) |
@Myoldmopar yeah, I'll add an example file. I've been chatting with @mjwitte about the inevitable collision of our two PRs and need to make one other minor change to accommodate the fact that spaces can cause surfaces to be in separate enclosures within the same zone. I'll take care of that this morning. |
@Myoldmopar this should be ready once the CI returns. |
@nealkruis I'm not sure if you're working this weekend or not, but with spaces in, please go ahead and update this branch as soon as possible so we can do final review and get it merged. |
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.
Only one minor review comment.
Overall this looks good to me. I'll be curious how the conduction work on the windows improves performance.
src/EnergyPlus/DataSurfaces.cc
Outdated
// Make hash key for this surface (used to determine uniqueness) | ||
state.dataSurface->Surface(SurfNum).make_hash_key(state, SurfNum); | ||
// Insert surface key into map. If key already exists, it will not be added. | ||
state.dataSurface->RepresentativeSurfaceMap.insert({state.dataSurface->Surface(SurfNum).calcHashKey, 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.
Relatively minor in the scheme of the PR, but insert
returns a "pair object whose first element is an iterator pointing either to the newly inserted element in the container or to the element whose key is equivalent". This means you can just use that returned iterator below state.dataSurface->Surface(SurfNum).RepresentativeCalcSurfNum = returned_pair.first;
, instead of performing a find
again.
src/EnergyPlus/SurfaceGeometry.cc
Outdated
state.dataSurface->Surface(SurfNum).RepresentativeCalcSurfNum = SurfNum; | ||
// Automatic Surface Multipliers: Assign representative heat transfer surfaces | ||
if (state.dataSurface->UseRepresentativeSurfaceCalculations && state.dataSurface->Surface(SurfNum).HeatTransSurf && | ||
state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneProperty:UserViewFactors:BySurfaceName") == 0) { |
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.
Probably shouldn't call this for every surface. Call once and set a flag. Better yet, split this loop into two and only do the second part if UseRepresentativeSurfaceCalculations
is true and there are no user defined view factors.
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.
@nealkruis This is an interesting approach. I haven't tested it yet to see what kind of impact it has. Some comments at the top of the PR would be useful if you've found a certain file to show x% speedup or % reduction in surfaces in the radiant enclosures. Nice that the changes are very self-contained.
A few comments/questions. Nothing here is a showstopper for I/O Freeze, any changes can happen after that.
@@ -1089,28 +1089,28 @@ \subsection{PerformancePrecisionTradeoffs}\label{performanceprecisiontradeoffs} | |||
|
|||
\paragraph{Field: Override Mode}\label{override-mode} | |||
|
|||
The Override Mode field provides a single field that will override other inputs located in the IDF/epJSON file as well as convergence related values that appear in the remaining fields of the PerformancePrecisionTradeoffs object. The Normal option (default) provides no overrides while the Mode options provide overrides based on the following tables. The Advanced option, allows the remaining fields of the PerformancePrecisionTradeoffs to be used. | |||
The Override Mode field provides a single field that will override other inputs located in the IDF/epJSON file as well as convergence related values that appear in the remaining fields of the PerformancePrecisionTradeoffs object. The Normal option (default) provides no overrides while the Mode options provide overrides based on the following tables. The Advanced option, allows the remaining fields of the PerformancePrecisionTradeoffs to be used. |
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 needs to be more specific now. Only MaxZoneTempDiff and MaxAllowedDelTemp require Override Mode = Advanced. If I'm understanding correctly, the new field for "Use Representative Surfaces for Calculations" isn't affected by Override Mode.
|
||
Surface are grouped based on the following criteria for similarity: | ||
|
||
\begin{itemize} |
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.
Adding \tightlist
might be nice here (before the first item) to remove the space between each item - nice for short one-liner lists like this.
calcHashKey.TAirRef = state.dataSurface->SurfTAirRef(SurfNum); | ||
|
||
auto extBoundCond = state.dataSurface->Surface(SurfNum).ExtBoundCond; | ||
if (extBoundCond > 0) { |
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 will add ExtZone and ExtEnclindex to the hash if it's an interzone surface, otherwise these are zero. I see checks later on for OSC and OSCM, but what about these outside boundary conditions:
\key Outdoors
\key Foundation
\key Ground
\key GroundFCfactorMethod
Unless I'm missing something it looks like these will all have the same hash.
\item WindowProperty:AirflowControl (windows only) | ||
\end{itemize} | ||
|
||
Currently, the only calculations performed across all surfaces with a group is the interior radiation exchange, where surfaces within a group are collected into a single area for participating in interior longwave radiation exchange. This will reduce the scale and complexity of the algorithm with minimal impact on accuracy. Additional calculations may be performed for a group of surfaces in future releases. |
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.
Type - first "with" --> "within"
int enclosureSurfNum = 0; | ||
for (int const spaceNum : thisEnclosure.spaceNums) { | ||
int priorZoneTotEnclSurfs = enclosureSurfNum; | ||
for (int surfNum : state.dataHeatBal->space(spaceNum).surfaces) { | ||
if (state.dataSurface->Surface(surfNum).IsAirBoundarySurf) continue; | ||
++enclosureSurfNum; | ||
thisEnclosure.SurfacePtr(enclosureSurfNum) = surfNum; | ||
// Automatic Surface Multipliers: Only include representative surfaces |
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.
If this loop only adds representative surfaces, can this for loop be skipped if !UseRepresentativeSurfaceCalculations
?
Or maybe it's the next loop that isn't necessary if !UseRepresentativeSurfaceCalculations
?
The usage for RepresentativeCalcSurfNum
is a bit confusing. When I saw it declared in DataSurfaces, I assumed that RepresentativeCalcSurfNum
would be zero for normal calculations, but it appears that's not the case.
If I'm following correctly, if UseRepresentativeSurfaceCalculations is off, then state.dataSurface->Surface(surfNum).RepresentativeCalcSurfNum = surfNum
for all surfaces?
Might be worth an extra comment in DataSurfaces.
EXPECT_EQ(state->dataSurface->Surface(2).RepresentativeCalcSurfNum, 2); | ||
EXPECT_EQ(state->dataSurface->Surface(3).RepresentativeCalcSurfNum, 3); | ||
EXPECT_EQ(state->dataSurface->Surface(4).RepresentativeCalcSurfNum, 1); | ||
} |
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.
File could use one more return at the end.
Serial unit tests all pass. |
This is a great addition. I'm going to merge this in to get us very close to IO freeze, but please open up a ticket right away to address the issues noted by @mjwitte. Thanks @nealkruis ! |
Pull request overview
One time saving technique used in EnergyPlus models is the use of Window Multipliers to reduce redundant heat balance calculations on multiple window surfaces. However, this practice requires users to modify their building geometry to be substantially different from the actual architectural features they are trying to represent. This work will explore, propose, and implement an approach where these simplifications can be inferred automatically from user input and performed behind-the-scenes so that models with many windows (and other heat transfer surfaces) can benefit from time-saving techniques without sacrificing geometric fidelity.
See the NFP here.
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.