-
Notifications
You must be signed in to change notification settings - Fork 397
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
Fix #10817 - Avoid crash in FluidCooler/EvaporativeFluidCooler when Water flow rate autosized and no Sizing:Plant #10855
base: develop
Are you sure you want to change the base?
Conversation
…ng it to an empty (invalid / default initialized) FluidCooler!
…t loop This makes no difference in test results, but it was bothering me that they were on the demand side as it's not logical
…ater flow rate autosized and no Sizing:Plant
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 have noticed more problems, but they will likely result in diffs in results so I didn't had them right now, as I'd like CI to report green.
@@ -356,10 +356,10 @@ TEST_F(EnergyPlusFixture, SizeFunctionTestWhenPlantSizingIndexIsZero) | |||
auto &thisFluidCooler = state->dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum); | |||
|
|||
state->dataPlnt->PlantLoop.allocate(FluidCoolerNum); | |||
state->dataFluidCoolers->SimpleFluidCooler.allocate(FluidCoolerNum); |
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.
Fix an existing test. When I tried to reuse it, I realized that the allocate after GetInput was resetting it to an empty (invalid / default initialized) FluidCooler
state->dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).plantLoc.loopNum = 1; | ||
state->dataPlnt->PlantLoop(FluidCoolerNum).PlantSizNum = 0; | ||
|
||
EXPECT_EQ("DRY COOLER", thisFluidCooler.Name); |
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 would fail, before
@@ -389,10 +389,10 @@ TEST_F(EnergyPlusFixture, ExerciseSingleSpeedFluidCooler) | |||
|
|||
FluidCoolerspecs *ptr = FluidCoolerspecs::factory(*state, DataPlant::PlantEquipmentType::FluidCooler_SingleSpd, "DRY COOLER"); | |||
|
|||
PlantLocation pl{1, EnergyPlus::DataPlant::LoopSideLocation::Demand, 1, 1}; | |||
PlantLocation pl{1, EnergyPlus::DataPlant::LoopSideLocation::Supply, 1, 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.
Unrelated, but place the fluid coolers on the supply side of the plant loop.
This makes no difference in test results, but it was bothering me that all of the FluidCooler.unit.cc / EvaporativeFluidCooler.unit.cc had the fluid coolers on the demand side
TEST_F(EnergyPlusFixture, FluidCooler_SizeWhenPlantSizingIndexIsZeroAndAutosized) | ||
{ | ||
// Test for #10817 | ||
std::string const idf_objects = delimited_string({ | ||
" FluidCooler:SingleSpeed,", | ||
" Dry Cooler, !- Name", | ||
" Dry Cooler Inlet Node, !- Water Inlet Node Name", | ||
" Dry Cooler Outlet Node, !- Water Outlet Node Name", | ||
" NominalCapacity, !- Performance Input Method", | ||
" Autosize, !- Design Air Flow Rate U-factor Times Area Value {W/K}", | ||
" 58601, !- Nominal Capacity {W}", | ||
" 50, !- Design Entering Water Temperature {C}", | ||
" 35, !- Design Entering Air Temperature {C}", | ||
" 25, !- Design Entering Air Wetbulb Temperature {C}", | ||
" Autosize, !- Design Water Flow Rate {m3/s}", | ||
" Autosize, !- Design Air Flow Rate {m3/s}", | ||
" Autosize; !- Design Air Flow Rate Fan Power {W}", | ||
}); | ||
|
||
ASSERT_TRUE(process_idf(idf_objects)); | ||
|
||
GetFluidCoolerInput(*state); | ||
int FluidCoolerNum(1); | ||
|
||
state->dataPlnt->PlantLoop.allocate(FluidCoolerNum); | ||
state->dataPlnt->PlantLoop(FluidCoolerNum).PlantSizNum = 0; | ||
|
||
auto &thisFluidCooler = state->dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum); | ||
thisFluidCooler.plantLoc.loopNum = 1; | ||
|
||
// Necessary to trigger the crash from # | ||
state->dataPlnt->PlantFirstSizesOkayToFinalize = false; | ||
|
||
EXPECT_TRUE(thisFluidCooler.DesignWaterFlowRateWasAutoSized); | ||
EXPECT_TRUE(thisFluidCooler.HighSpeedFanPowerWasAutoSized); | ||
EXPECT_TRUE(thisFluidCooler.HighSpeedAirFlowRateWasAutoSized); | ||
EXPECT_TRUE(thisFluidCooler.HighSpeedFluidCoolerUAWasAutoSized); | ||
|
||
thisFluidCooler.size(*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 test, crashes before fix
TEST_F(EnergyPlusFixture, EvapFluidCooler_SizeWhenPlantSizingIndexIsZeroAndAutosized) | ||
{ | ||
// Test for #10817 | ||
std::string const idf_objects = delimited_string({ | ||
"EvaporativeFluidcooler:SingleSpeed,", | ||
" Big EvaporativeFluidCooler, !- Name", | ||
" Condenser EvaporativeFluidcooler Inlet Node, !- Water Inlet Node Name", | ||
" Condenser EvaporativeFluidcooler Outlet Node, !- Water Outlet Node Name", | ||
" Autosize, !- Design Air Flow Rate {m3/s}", | ||
" Autosize, !- Design Air Flow Rate Fan Power {W}", | ||
" 0.002208, !- Design Spray Water Flow Rate {m3/s}", | ||
" UFactorTimesAreaAndDesignWaterFlowRate, !- Performance Input Method", | ||
" , !- Outdoor Air Inlet Node Name", | ||
" , !- Heat Rejection Capacity and Nominal Capacity Sizing Ratio", | ||
" , !- Standard Design Capacity {W}", | ||
" Autosize, !- Design Air Flow Rate U-factor Times Area Value {W/K}", | ||
" Autosize, !- Design Water Flow Rate {m3/s}", | ||
" , !- User Specified Design Capacity {W}", | ||
" 46.11, !- Design Entering Water Temperature {C}", | ||
" 35, !- Design Entering Air Temperature {C}", | ||
" 25.6; !- Design Entering Air Wet-bulb Temperature {C}", | ||
}); | ||
|
||
ASSERT_TRUE(process_idf(idf_objects)); | ||
|
||
EvapFluidCoolerSpecs *ptr = | ||
EvapFluidCoolerSpecs::factory(*state, DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd, "BIG EVAPORATIVEFLUIDCOOLER"); | ||
|
||
state->dataPlnt->PlantLoop.allocate(1); | ||
state->dataPlnt->PlantLoop(1).PlantSizNum = 0; | ||
ptr->plantLoc.loopNum = 1; | ||
|
||
// Necessary to trigger the crash from # | ||
state->dataPlnt->PlantFirstSizesOkayToFinalize = false; | ||
|
||
EXPECT_TRUE(ptr->DesignWaterFlowRateWasAutoSized); | ||
EXPECT_TRUE(ptr->HighSpeedAirFlowRateWasAutoSized); | ||
EXPECT_TRUE(ptr->HighSpeedFanPowerWasAutoSized); | ||
EXPECT_TRUE(ptr->HighSpeedEvapFluidCoolerUAWasAutoSized); | ||
|
||
ptr->SizeEvapFluidCooler(*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.
Realized the same was happening for EvaporativeFluidCooler:XX objects, so added a test there too
if (PltSizCondNum > 0) { | ||
|
||
// Check when the user specified Condenser/Evaporative Fluid Cooler water design setpoint | ||
// temperature is less than design inlet air wet bulb temperature | ||
Real64 DesignEnteringAirWetBulb = 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.
Fix is to basically ensure the check is done INSIDE the if(PltSizCondNum > 0)
If PltSizCondNum is not > 0, it'll throw anyways
@@ -1380,28 +1403,6 @@ namespace EvaporativeFluidCoolers { | |||
ShowFatalError(state, "Autosizing of evaporative fluid cooler condenser flow rate requires a loop Sizing:Plant object."); |
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.
Throw when PltSizCondNum is not > 0 is here.
src/EnergyPlus/FluidCoolers.cc
Outdated
// This is to trap when the user specified Condenser/Fluid Cooler water design setpoint temperature is less than design inlet air dry bulb | ||
// temperature | ||
auto ensureSizingPlantExitTempIsNotLessThanDesignEnteringAirTemp = [this, &state, PltSizCondNum]() { | ||
if (state.dataSize->PlantSizData(PltSizCondNum).ExitTemp <= this->DesignEnteringAirTemp && state.dataPlnt->PlantFirstSizesOkayToFinalize) { | ||
ShowSevereError(state, format("Error when autosizing the UA value for fluid cooler = {}.", this->Name)); | ||
ShowContinueError(state, | ||
format("Design Loop Exit Temperature ({:.2R} C) must be greater than design entering air dry-bulb temperature " | ||
"({:.2R} C) when autosizing the fluid cooler UA.", | ||
state.dataSize->PlantSizData(PltSizCondNum).ExitTemp, | ||
this->DesignEnteringAirTemp)); | ||
ShowContinueError(state, | ||
"It is recommended that the Design Loop Exit Temperature = design inlet air dry-bulb temp plus the Fluid Cooler " | ||
"design approach temperature (e.g., 4 C)."); | ||
ShowContinueError(state, | ||
"If using HVACTemplate:Plant:ChilledWaterLoop, then check that input field Condenser Water Design Setpoint must be " | ||
"> design inlet air dry-bulb temp if autosizing the Fluid Cooler."); | ||
ShowFatalError(state, "Review and revise design input values as appropriate."); | ||
} | ||
}; |
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.
Fluid cooler had the same block 4 times, so I reuse a lambda instead
// This is to trap when the user specified Condenser/Fluid Cooler water design setpoint temperature is less than design inlet air dry bulb | ||
// temperature | ||
auto ensureSizingPlantExitTempIsNotLessThanDesignEnteringAirTemp = [this, &state, PltSizCondNum]() { | ||
if (state.dataSize->PlantSizData(PltSizCondNum).ExitTemp <= this->DesignEnteringAirTemp && state.dataPlnt->PlantFirstSizesOkayToFinalize) { |
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 think it's necessary to delay until PlantFirstSizesOkayToFinalize is true, but I didn't want to change the existing behavior
``` rg Fluidcool -l | xargs sed -i 's/Fluidcooler/FluidCooler/g' ```
…nd used to report Range & Approach)
7284c44
to
4aaa7c0
Compare
|
Regressions are all expected. The Before: After: FluidCooler.idf Design Water Flow Rate is harcoded to 0.001388, so the Design Leaving Water Temperature was zero before and approach & range were wrong before: After: FluidCoolerTwoSpeed Same here as the ASHRAE901, the Design Water Flow Rate is autosized so the Design Leaving Water Temperature was correctly calcualted before: After: |
@jmarrec it has been 7 days since this pull request was last updated. |
@jmarrec it has been 10 days since this pull request was last updated. |
@jmarrec it has been 8 days since this pull request was last updated. |
Pull request overview
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.