-
Notifications
You must be signed in to change notification settings - Fork 421
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
Extended HI followup: fix speed issue #10733
Conversation
|
|
|
|
Even with the latest commit, 4f4809f, it's still causing a 10% increase in instruction count in just our performance test files. We can figure out a solution for this, but it doesn't look like it's going in this release. I'm marking this for next release and we'll deal with this later. If this method is trimmed as far down as possible but still this much slower, I would suggest adding a switch to calculate heat index using the old way by default and then enabling the new method as an alternative. This would be a user-facing input option, so definitely not in this current release. |
Thanks, @Myoldmopar . It seems that changing the solver type had the biggest impact. Then I tried adding some result caching but those doesn't save as much (like improved 1-2 percentage point). I also tried to limit the domain of its application (in the old PR there was a plot of how results differ between the old and the new methods. I restricted it to only apply on the bottom right region where the two methods differ a lot). That doesn't help much either. Potentially the new method just requires a lot of computation. (modify): I might have had the equation part wrong for restraining the domain where extended HI is applied (the white region in the following figures. I modified it and tried locally, roughly it improved it by about 6-7%. Might still not be good enough. |
|
src/EnergyPlus/ExtendedHeatIndex.cc
Outdated
constexpr Real64 epsilon = 0.97; // , emissivity of surface, steadman1979 | ||
constexpr Real64 M = 83.6; // kg , mass of average US adults, fryar2018 | ||
constexpr Real64 H = 1.69; // m , height of average US adults, fryar2018 | ||
Real64 A = 0.202 * pow(M, 0.425) * pow(H, 0.725); // m^2 , DuBois formula, parson2014 |
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.
Don't use global variables.
also moved heat index calculation into simulation manager after the other OutputControl thing
|
|
src/EnergyPlus/ExtendedHeatIndex.cc
Outdated
Real64 Rf; | ||
|
||
if (flux1 <= 0.0) { | ||
varname = static_cast<int>(EqvarName::Phi); |
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.
Why cast this to int all the time? Just use the enum, no?
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.
Yeah I should use the enum class instead of casting to int
src/EnergyPlus/ExtendedHeatIndex.cc
Outdated
} | ||
|
||
// Convert the find_T function | ||
Real64 find_T(EnergyPlusData &state, int const eqvar_name, Real64 const eqvar) |
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.
You can use enum
s as parameters, why make it an int
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.
yeah also need to use enum class directly here as well
src/EnergyPlus/ExtendedHeatIndex.hh
Outdated
enum class EqvarName | ||
{ | ||
Invalid = -1, | ||
Phi = 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.
Why are these not starting at 0? Why do you have to assign explicit values to 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.
This extended heat index was based on python code on this page. They have some dictionary defined the indices like this: dic = {"phi":1,"Rf":2,"Rs":3,"Rs*":3,"dTcdt":4}
So I just used the same indices.
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 values are meaningless unless you are using them in an array, but even then you should use them in a std::array
and they should start at 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.
make sense. Let me change this to starting at 0.
src/EnergyPlus/HeatBalanceManager.cc
Outdated
static_cast<HVACSystemRootSolverAlgorithm>(getEnumValue(HVACSystemRootSolverAlgorithmUC, Util::makeUPPER(AlphaName(1)))); | ||
if (HVACSystemRootFinding.HVACSystemRootSolverMethod == HVACSystemRootSolverAlgorithm::Invalid) { | ||
HVACSystemRootFinding.HVACSystemRootSolverMethod = HVACSystemRootSolverAlgorithm::RegulaFalsi; | ||
ShowWarningError(state, |
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 shortcut for this warning called ShowWarningInvalidKey
.
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.
Oh! Didn't realize there's this shortcut.
src/EnergyPlus/ExtendedHeatIndex.cc
Outdated
constexpr Real64 Za_bar = 60.6 / 11.6; // Pa m^2/W, mass transfer resistance through air, clothed part of skin | ||
constexpr Real64 Za_un = 60.6 / 12.3; // Pa m^2/W, mass transfer resistance through air, when being naked | ||
|
||
constexpr Real64 tol = 1e-8; |
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 an absolute tolerance level. What are the reasonable ranges of values here and what level of precision does this tolerance correspond to relative to those values?
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 tolerance was from the python code here this page.
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 someone else chose for the tolerance is not relevant. What is the magnitude of the values produced by this function? 1e-4? 1e-1? 1e+2?
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 function produces SGP (whatever that is) and the values are on the order of 1e-2 then a tolerance of 1e-8 is about six decimal places of precision which is about twice what is needed. I cannot conceive of any quantity that EnergyPlus that would need to know to a precision of more than 0.1% (1% may be okay for many thing too).
In fact, SolveRoot
should probably be revised to use relative tolerance after some small fixed number of iterations. I wonder how much performance over-specific root precision is costing us. It could be quite a lot.
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 I change tol to 1e-4, there will be a 0.6 difference for a target value of about 360 (0.2% relative difference). Using tol=1e-5 keeps the difference to below 0.1 (for values ranging from 200 to 400). Maybe I'll change it to tol = 1e-5?
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.
Absolutely. Those additional digits are costing you iterations for no real benefit in terms of accuracy. Who cares if the SGP is "off" by less than 0.1%? How accurate is that metric anyway?
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.
Normally heat index is reported at either integer or 1 decimal point. The range is mostly two three hundred. Hopefully within 0.1C accuracy is good 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.
Most thermostats used in buildings do not have this resolution.
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.
yeah the inputs of temperature and relative humidity percentage points are integers
|
|
|
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.
@yujiex Thanks for the idd changes.
|
||
This input specifies methods or algorithms used in certain resilience reporting variables. | ||
|
||
\subsubsection{Inputs}\label{inputs-8-020} |
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.
When viewing the changes on github, there is a warning about this line:
Label
inputs-8-020' multiply defined.`
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.
let me check on why this happens
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 see, my label for the inputs section in my latex documentation collides with a existing one. I just changed the label.
|
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.
Outside of the vector/array thing in the unit test code, I don't have any comments. And that's not worth holding this up. I will do final testing and try to get this in.
} | ||
|
||
} // namespace ExtendedHI | ||
} // namespace EnergyPlus |
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 strong use of const and constexpr in this file make me very happy.
@@ -1013,6 +1013,27 @@ namespace SimulationManager { | |||
} | |||
} | |||
|
|||
state.dataHeatBalMgr->CurrentModuleObject = "OutputControl:ResilienceSummaries"; |
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.
In the future, there's no need to use a state variable to hold this string. Just keep a constexpr string view variable of it and use that.
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'll remember and use string view in the future.
TEST_F(EnergyPlusFixture, extendedHI_pvstar) | ||
{ | ||
Real64 tol = 1e-8; | ||
std::vector<Real64> T_values = {200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370}; |
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.
You could use constexpr std::array
all over the place in here. Since this is just in the tests, we don't have to hold this up, but always look for that in the future.
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.
oh! I see I see. I'll take a note and remember to use constexpr next time.
Runs great here, ready to go in. Thanks @yujiex. |
Thanks @Myoldmopar |
Pull request overview
A couple of different approaches were tried out to improve the performance
Bisection
toBisectionThenRegulaFalsi
: this had the biggest impact, bringing the damage from 70% to about 12%The new extend HI method might just requires a lot of computation. So The following object is added to provide a switch from the simplified to the extended HI method.
Regression diff
There's diff in one file: 1ZoneUncontrolled_Win_ASH55_Thermal_Comfort.idf. The diff is a result of the added OutputControl:ResilienceSummaries
![image](https://private-user-images.githubusercontent.com/13421161/411697043-eac22aca-b47d-4914-bdaf-dc6646f8df58.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1MzIwMjEsIm5iZiI6MTczOTUzMTcyMSwicGF0aCI6Ii8xMzQyMTE2MS80MTE2OTcwNDMtZWFjMjJhY2EtYjQ3ZC00OTE0LWJkYWYtZGM2NjQ2ZjhkZjU4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDExMTUyMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTFlYjliY2MxYTM3Njg5OGNiNmU2MTQxM2YxYTQ3NTc3YmU2OWEzNWVlZTQ1YzBkZmQ2ZGFmY2JiNzMyZjFlMGImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.pnnd_izz7_MqfYQd-oNzjoP8JFzNh9DHJ48n6OuK1cM)
NOTE: ENHANCEMENTS MUST FOLLOW A SUBMISSION PROCESS INCLUDING A FEATURE PROPOSAL AND DESIGN DOCUMENT PRIOR TO SUBMITTING CODE
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.