-
Notifications
You must be signed in to change notification settings - Fork 379
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
Update thermal histories refactoring #8873
Conversation
state.dataHeatBalSurf->SumSurfaceHeatEmission = 0.0; | ||
|
||
for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { | ||
if (Surface(SurfNum).ExtBoundCond == ExternalEnvironment) { |
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 is executed frequently, it may be worthwhile to make a std::vector of all surfaces that have ExternalEnvironment
as their boundary condition.
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 condition Surface(SurfNum).ExtBoundCond == ExternalEnvironment
is used frequently but is always paired with and/or with other conditions. A lot of those happen in 'HTSurfaceFirst' to last or 'WinFirst` to last.
As for this loop alone, it gets executed every zone time step. Not sure if it's frequent enough.
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.
Well ... do they occur frequently enough that we want to sort the Window surfaces within each Zone into Exterior and Interior Windows? And same for Opaque 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.
Not sure if it's worth it. Half of the time the check is paired with ExternalEnvironment || Ground
or ExternalEnvironment || OtherSideCoefNoCalcExt
or ExternalEnvironment || SurfaceClass == wall
, and half of the time the condition is checked in an enclosure loop where we don't have the sorted zone surface priviledge.
for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { | ||
if (Surface(SurfNum).ExtBoundCond == ExternalEnvironment) { | ||
state.dataHeatBalSurf->SumSurfaceHeatEmission += state.dataHeatBalSurf->QHeatEmiReport(SurfNum) * state.dataGlobal->TimeStepZoneSec; | ||
} |
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.
Another question about this specifically. Are Surface heat emissions calculated and reported by default or only if the user asks for them?
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.
displayHeatEmissionsSummary
is True with AllSummary
declared in Output:Table:SummaryReports
, and AllSummary
is somewhat frequently declared for tabular reports. But yes I should escape this loop when displayHeatEmissionsSummary
is False.
Currently displayHeatEmissionsSummary
is read at the end of the first zone time step (where"Output:Table:SummaryReports"
is read). I should bring this piece of input processing upfront. (Maybe all getIDFInput functions should.)
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.
TBD next branch.
(state.dataHeatBalSurf->QdotRadNetSurfInRepPerArea(SurfNum) = state.dataHeatBalSurf->SurfNetLWRadToSurf(SurfNum)) * surfaceArea; | ||
state.dataHeatBalSurf->QRadNetSurfInReport(SurfNum) = state.dataHeatBalSurf->QdotRadNetSurfInRep(SurfNum) * state.dataGlobal->TimeStepZoneSec; | ||
|
||
if (Surface(SurfNum).Class != SurfaceClass::Window) { // not a window... |
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 also noticed that this test was there and was going to mention it. Glad you caught it.
TBD:
|
Yes, you should definitely do this except:
Also, I don't really understand what
|
Tmin = minval(TH(2, 1, {Zone(ZoneNum).HTSurfaceFirst, Zone(ZoneNum).HTSurfaceLast})); | ||
Tmax = maxval(TH(2, 1, {Zone(ZoneNum).HTSurfaceFirst, Zone(ZoneNum).HTSurfaceLast})); | ||
Tmin = minval(state.dataHeatBalSurf->SurfInTempHistCurr({Zone(ZoneNum).HTSurfaceFirst, Zone(ZoneNum).HTSurfaceLast})); | ||
Tmax = maxval(state.dataHeatBalSurf->SurfInTempHistCurr({Zone(ZoneNum).HTSurfaceFirst, Zone(ZoneNum).HTSurfaceLast})); |
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 you are looking for both minval
and maxval
in a given range, it is faster to look for both of them together than to look for them separately.
for (SurfNum = Zone(ZoneNum).HTSurfFirst; SurfNum <= Zone(ZoneNum).HTSurfLast; ++SurfNum) {
Real64 SurfTemp = SurfInTempCurr(SurfNum);
if (SurfTemp < Tmin) Tmin = SurfTemp;
else if (SurfTemp > Tmax) Tmin = SurfTemp;
}
Not only are you traversing the elements once instead of twice, but you are also only checking for Tmax
those elements that are greater than Tmin
.
@amirroth 👍 * 100 for |
Note: The ESO small diffs of 26 tests are caused by the floating-point rounding diff due to the change of floating-point addition order of this loop. |
@amirroth Please see the latest commit. I'm working on the UpdateThermalHistoriesSimpleCTF to allow the address shift to replace the copying. The |
@amirroth Current copying is element by element because when |
@mjwitte Hi Mike, would you mind reviewing this branch, please? Code changes are described in PR overview. CI is clean (small diffs explained in PR overview). 1.68% speedup in CI suites. |
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.
Excellent chunk of work! Just a few questions.
Real64 DeltaTemp(0.0); // temporary temperature difference (Tsurf - Tair) | ||
int SurfLoop; // local for separate looping across surfaces in the zone that has SurfNum | ||
Real64 Tmin(std::numeric_limits<float>::min()); // temporary min surf temp | ||
Real64 Tmax(std::numeric_limits<float>::max()); // temporary max surf temp |
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.
What does std::numeric_limits<float>::max()
do?
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.
Since Tmin
and Tmax
are used to find the min and max in an array in one loop, by comparing values, I initialized them with the maximum and minimum floating-point numbers in C++ (previously they were initialized with zeros). Then I realized I put them in the wrong order and I just fixed that.
state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux = 0.0; | ||
state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux = 0.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.
Should these be zeroed in a loop?
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.
state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr; | ||
state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting | ||
state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr; | ||
state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = std::abs(state.dataHeatBalSurf->SurfOpaqInsFaceCond(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 line looks wrong. SurfOpaqInsFaceCondGainRep
is set in line 5674 inside if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) >= 0.0)
Delete this line?
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.
Right. Done.
if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) >= 0.0) { | ||
state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum); | ||
} else { | ||
state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(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.
I think this can be deleted here. The same update is done later in ReportSurfaceHeatBalance
. Is there a reason this is needed here also?
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. Deleted. Thanks!
@mjwitte Mike. I think this branch is ready to be merged. I pulled upstream develop so far and things are working fine. |
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.
@xuanluo0113 Ran an annual simulation with RadLoTempHydrHeatCoolMultiZone just to be sure we aren't missing any cumulative diffs, and the ABUPS outputs are identical vs develop. I've merged in develop for one last CI round (if I wait long enough for that). And I'm running one last set of unit tests locally. Otherwise this looks great.
Pull request overview
SimpleCTFOnly
flag to the simulation to apply shift-only update thermal historyNote:
The ESO small diffs of 26 tests are caused by the floating-point rounding diff due to the change of floating-point addition order of this loop.
In develop branch, the
SurfCTFConstInPart
is added up in surface sequence with the CTF fluxes and the Source fluxes of all historical terms. To avoid checking if construction has a source or sink present at each term, the CTF fluxes are added up first altogether and the source fluxed are added later on. The difference in the order of addition is causing a 10E-14 difference inSurfCTFConstInPart
from the second time step of the simulation to the end, and that further causes the regression diffs all over.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.
If defect, verify by running develop branch and reproducing defect, then running PR and reproducing fixIf feature, test running new feature, try creative ways to break itVerify IDF naming conventions and styles, memos and notes and defaultsIf new idf included, locally check the err file and other outputs