-
Notifications
You must be signed in to change notification settings - Fork 389
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
FluidProperties API #10616
FluidProperties API #10616
Conversation
#ifdef EP_cache_GlycolSpecificHeat | ||
int constexpr t_sh_cache_size = 1024 * 1024; | ||
int constexpr t_sh_precision_bits = 24; | ||
std::uint64_t constexpr t_sh_cache_mask = (t_sh_cache_size - 1); | ||
#endif | ||
|
||
struct FluidPropsRefrigerantData | ||
enum class RefrigError |
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.
Error enum
s.
} | ||
std::array<ErrorCountIndex, (int)RefrigError::Num> errors; | ||
|
||
Real64 getQuality(EnergyPlusData &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.
New object oriented API.
int CondLowTempIndex; // Low Temperature Min Index for Cond (>0.0) | ||
int CondHighTempIndex; // High Temperature Max Index for Cond (>0.0) | ||
#ifdef PERFORMANCE_OPT | ||
int LoRhoTempIdxLast = 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.
For performance optimization.
constexpr static std::string_view EthyleneGlycol("EthyleneGlycol"); | ||
constexpr static std::string_view PropyleneGlycol("PropyleneGlycol"); | ||
|
||
#undef PERFORMANCE_OPT |
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.
Change this to #define PERFORMANCE_OPT
to enable the local optimizations.
int &RefrigIndex, // Index to Refrigerant Properties | ||
std::string_view CalledFrom // routine this function was called from (error messages) | ||
); | ||
|
||
Real64 GetSatPressureRefrig(EnergyPlusData &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.
Old API is still here. Can get rid of it once all uses have been converted.
src/EnergyPlus/FluidProperties.hh
Outdated
@@ -666,7 +636,12 @@ struct FluidPropertiesData : BaseGlobalStruct | |||
|
|||
void clear_state() override | |||
{ | |||
new (this) FluidPropertiesData(); | |||
|
|||
for (int i = 1; i <= refrigs.isize(); ++i) delete refrigs(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.
Using arrays of pointers to fluid objects, so remember to delete in clear_state
.
if (Util::FindItemInList(thisVrfFluidCtrl.RefrigerantName, state.dataFluidProps->RefrigData, state.dataFluidProps->NumOfRefrigerants) == 0) { | ||
ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfFluidCtrl.Name); | ||
ShowContinueError(state, "Illegal " + cAlphaFieldNames(4) + " = " + cAlphaArgs(4)); | ||
thisVrfFluidCtrl.refrigName = cAlphaArgs(4); |
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.
Grabbing the pointer to the refrigerant here so that we can use the new fluid API.
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.
Got it. And as with the plant component work, the refrig pointer is not owning. It's just an address, and we need to check null before using it. Good to go.
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 don't really need to check it, unless the option of not having a fluid at all is a legitimate option. Pointer ownership is about who has to free the memory when it is no longer used, not about checking for nullptr
.
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 just mean check for null once during get input routines in case there is an invalid refrigerant string passed in from user input to the GetRefrig function. Once state is all setup, definitely shouldn't be checking it over and over again.
RefTHigh = state.dataFluidProps->RefrigData(RefrigerantIndex).PsHighTempValue; // High Temperature Value for Ps (max in tables) | ||
RefPLow = state.dataFluidProps->RefrigData(RefrigerantIndex).PsLowPresValue; // Low Pressure Value for Ps (>0.0) | ||
RefPHigh = state.dataFluidProps->RefrigData(RefrigerantIndex).PsHighPresValue; // High Pressure Value for Ps (max in tables) | ||
RefMinPe = this->refrig->getSatPressure(state, RefMinTe, RoutineName); |
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.
New refrigerant API.
@@ -1231,6 +1231,56 @@ void ShowRecurringSevereErrorAtEnd(EnergyPlusData &state, | |||
state, " ** Severe ** " + Message, MsgIndex, ReportMaxOf, ReportMinOf, ReportSumOf, ReportMaxUnits, ReportMinUnits, ReportSumUnits); | |||
} | |||
|
|||
void ShowRecurringSevereErrorAtEnd(EnergyPlusData &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.
Added this reduced argument wrapper for ShowRecurringError
.
@@ -213,6 +213,18 @@ public: // Assignment: Array | |||
|
|||
public: // Assignment: Value | |||
|
|||
template< typename U, Size s, class = typename std::enable_if< std::is_assignable< T&, U >::value >::type > |
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.
Added template for assigning std::array
to Array1S
(i.e., Array1
slices of higher dimensional ArrayXD
).
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 gonna lie, it's a little offputting to see more being added to Array1D after we've spent so much time stripping it down. Nothing red flag, just surprising. I wonder if this method was already available in the past and it wasn't used so it was removed at some point.
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 get it. I wasn't happy about this either. I added it so that built-in glycols and user-defined glycols could be handled with the same code. The real solution is to just convert this entire module to std::vector
which is eminently doable since it is quite self contained, but just something that I didn't feel like doing in this PR. I do have another pass planned having to do with caching, so I might do it then.
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.
Big changes here! The new API looks great. Since I'm already working on the EnergyPlus C API, I'll try to convert it over to the new interface in there as well. I made a couple comments, but nothing worth any extra changes. I also applied clang format and fixed the format string failure in custom check. I'll let CI make one more pass and this should be ready.
if (Util::FindItemInList(thisVrfFluidCtrl.RefrigerantName, state.dataFluidProps->RefrigData, state.dataFluidProps->NumOfRefrigerants) == 0) { | ||
ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfFluidCtrl.Name); | ||
ShowContinueError(state, "Illegal " + cAlphaFieldNames(4) + " = " + cAlphaArgs(4)); | ||
thisVrfFluidCtrl.refrigName = cAlphaArgs(4); |
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.
Got it. And as with the plant component work, the refrig pointer is not owning. It's just an address, and we need to check null before using it. Good to go.
@@ -213,6 +213,18 @@ public: // Assignment: Array | |||
|
|||
public: // Assignment: Value | |||
|
|||
template< typename U, Size s, class = typename std::enable_if< std::is_assignable< T&, U >::value >::type > |
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 gonna lie, it's a little offputting to see more being added to Array1D after we've spent so much time stripping it down. Nothing red flag, just surprising. I wonder if this method was already available in the past and it wasn't used so it was removed at some point.
I saw the |
All good, merging. Thanks @amirroth |
This is a cleanup and quick refactor of the
FluidProperties
module. It is enabled by the recentinit_state()
PR which callsEnergyPlusData::initi_state()
early in the simulation.FluidProperties::init_state()
is the second call made byEnergyPlusData::init_state()
ensuring thatFluidProperty
are created before any objects that reference them.This allows us to replace the
GetPropertyGlycol(state, glycolName, arg1, arg2, glycolIndex, calledFrom)
API which loadsFluidProperty
data on first call for any fluid, and has to locate thefluidIndex
on first call to each fluid from each context with a cleanerGlycolProps::getProperty(state, arg1, arg2, calledFrom)
API that relies on the fluid object being located on construction. That is the main change in this PR. For now, the old API has been retained and has been turned into a skinny-wrapper for the new API. Only one module (HVACVariableRefrigerantFlow
) has been moved to the new API. When the rest of the modules have moved, either opportunistically or in a pass, the old API can be deleted.Several other changes:
GetFluidPropertiesInput
was refactored. The old code used nested loops where the outer loop iterated over fluids, then for each property of each fluid iterated overFluidProperties
objects to find the right object. With this approach,FluidProperties
objects were read and multiple times. In the worst case, each object had to be readN
times where is the number ofFluidProperties
objects. The new code uses a single loop that iterates overFluidProperties
objects and acts based on which property and which fluid they refer to. In addition to being about 1,200 lines shorter, this refactor also sped up theDataSetFixture.FluidProperties
unit test by a factor of 3, from 55 seconds to 18.(Property(bin+1) - Property(bin)) / (Temp(bin+1) - (Temp(bin))
for every bin. This expression is the scaling factor used in interpolation of property values within a bin. I don't know how much time these save because the performance suite CI machines appear to be down. These optimizations are guarded by#ifdef PERFORMANCE_OPT
which is currently not defined.