Skip to content
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

Correction of Condensers Not Operating Based on Operation Scheme #10653

Merged
merged 7 commits into from
Aug 16, 2024

Conversation

RKStrand
Copy link
Contributor

@RKStrand RKStrand commented Aug 9, 2024

Pull request overview

  • Fixes PlantEquipmentOperation:OutdoorDryBulb does not work with some components #10634
  • It was noted (in test suite IDFs) that condensers were operating even though their operation scheme should have kept them from functioning. For example, in one file, when the outdoor dry-bulb temperature rose above 27C, only one condenser should have operated rather than both. While this may not be realistic, EnergyPlus should have been able to do this. Unfortunately, both cooling towers always ran, even when the temperature rose above the 27C value. This was because three of the four tower models never looked at the load that was assigned to it based on the operation scheme. This included the single speed, two speed, and variable speed cooling tower. The Merkel tower model did in fact use the assigned load. To fix this issue for the other cooling towers, a modified version of the algorithm from the Merkel model was implemented in the other models. Now, in the test file, the only cooling tower that operates when ODB is above 27C is the one that is supposed to and the other turns off. This logic was added as a new subroutine and a unit test was added to verify that the code is doing what it is supposed to do. Differences are expected in numerous files because before the operation schemes weren't being taken into account.

Pull Request Author

Add to this list or remove from it as applicable. This is a simple templated set of guidelines.

  • Title of PR should be user-synopsis style (clearly understandable in a standalone changelog context)
  • Label the PR with at least one of: Defect, Refactoring, NewFeature, Performance, and/or DoNoPublish
  • Pull requests that impact EnergyPlus code must also include unit tests to cover enhancement or defect repair
  • Author should provide a "walkthrough" of relevant code changes using a GitHub code review comment process
  • If any diffs are expected, author must demonstrate they are justified using plots and descriptions
  • If changes fix a defect, the fix should be demonstrated in plots and descriptions
  • If any defect files are updated to a more recent version, upload new versions here or on DevSupport
  • If IDD requires transition, transition source, rules, ExpandObjects, and IDFs must be updated, and add IDDChange label
  • If structural output changes, add to output rules file and add OutputChange label
  • If adding/removing any LaTeX docs or figures, update that document's CMakeLists file dependencies

Reviewer

This will not be exhaustively relevant to every PR.

  • Perform a Code Review on GitHub
  • If branch is behind develop, merge develop and build locally to check for side effects of the merge
  • If defect, verify by running develop branch and reproducing defect, then running PR and reproducing fix
  • If feature, test running new feature, try creative ways to break it
  • CI status: all green or justified
  • Check that performance is not impacted (CI Linux results include performance check)
  • Run Unit Test(s) locally
  • Check any new function arguments for performance impacts
  • Verify IDF naming conventions and styles, memos and notes and defaults
  • If new idf included, locally check the err file and other outputs

This commit includes the fix to the problem for both condensers operating even when the operation scheme said that one of them should not be operating.  It fixes this for all of the cooling tower models that were not set up to look at this.  Results now should that the towers are operating when they are supposed to.
Something about the logical flag wasn't what the custom check wanted.  This is an attempt to fix that.
Unit test was added to exercise the new subroutine that is being used to allow condensers to factor in condenser loop operation schemes.
@RKStrand RKStrand added the Defect Includes code to repair a defect in EnergyPlus label Aug 9, 2024
@RKStrand RKStrand added this to the EnergyPlus 24.2 milestone Aug 9, 2024
@RKStrand
Copy link
Contributor Author

RKStrand commented Aug 9, 2024

Here is a graph that can be compared to the graph that was posted in the original defect. It shows clearly that the second cooling tower shuts down when ODB goes above 27C.

image

Hard to see perhaps in the actual graph, but in the data as soon as ODB is above 27C, the BigTower2 drops to zero heat transfer rate.

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

So what was happening before? The condenser plant was exceeding the set point temperature? Or was the condenser plant set point met because the tower was not turning off based on OAT? From the results this looks correct. Operating a tower on DB temp does not seem practical. @EnergyArchmage ?

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

In the graph is does look like tower 2 is still on when the OAT rises above 27 C. Tower 2 operation is definitely different than shown in the issue description.

@RKStrand
Copy link
Contributor Author

RKStrand commented Aug 9, 2024

@rraustad Yes, I agree--the graph makes it look like it is still operating when the ODB is above 27C. In hour 10, the ODB is 26.975C so both the first and second tower have a positive heat transfer rate. That's hard to see in the graph though because it is so close to 27C. In hour 11 when the ODB is well above 27C, the second tower is off and the first tower takes all of the load. I'll add the test file results here so you can see for yourself, but it is really hard to see on the graph.

eplusoutCondFix.csv

@RKStrand
Copy link
Contributor Author

RKStrand commented Aug 9, 2024

@rraustad to see what was happening before, take a quick look at the defect (#10634) where a graph about what was happening before is shown.

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

Should the water flow through the tower also turn off? Or are these towers somehow in series.

image

@RKStrand
Copy link
Contributor Author

RKStrand commented Aug 9, 2024

Should the water flow through the tower also turn off? Or are these towers somehow in series.

Well, they are not in series. There's no delta T across the second tower, but there's no reason why this is going through the second tower and not the bypass branch. The file in question here is out of the test suite: CoolingTowerDryBulbRangeOp.idf

Corrected an issue with the fix where the mass flow rate when the load was zero was still positive in the defect idf when it should be zero.  This is now corrected.
@RKStrand
Copy link
Contributor Author

RKStrand commented Aug 9, 2024

FYI: The non-zero flow rate when the load was zero problem has been corrected in the latest commit that was just made.

if (std::abs(MyLoad) <= HVAC::SmallLoad) {
// tower doesn't need to do anything
this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
this->WaterMassFlowRate = 0.0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think when there is a local change to plant flow rates, that change should be confirmed using this call. The point is, after the water flow is set to 0 here, there should be a call to the plant component flow control function SetComponentFlowRate. It is possible that the plant flow resolver would want flow through this branch (i.e., maybe there is no bypass and the pump is constant volume).

    PlantUtilities::SetComponentFlowRate(state, this->WaterMassFlowRate, this->WaterInletNodeNum, this->WaterOutletNodeNum, this->plantLoc);

Copy link
Contributor

@rraustad rraustad Aug 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the order of these conditionals be switched? line 6461 and line 6469. Why do this twice? This begs an else if.

@@ -927,8 +928,8 @@ TEST_F(EnergyPlusFixture, CondenserLoopTowers_SingleSpeedSizing)
outletNodeIndex = std::distance(state->dataLoopNodes->NodeID.begin(), outletNode);
}
// TODO: FIXME: This is failing. Actual is -10.409381032746095, expected is 30.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment still needed?

@EnergyArchmage
Copy link
Contributor

It is definitely a good idea to update these old models. In addition to .MyLoad ( or CurLoad here), the operation schemes also set a bool .ON (usually called RunFlag) for each component. In general nowadays, the plant simulate calls should include both MyLoad and RunFlag.

To me, std::abs(MyLoad) <= HVAC::SmallLoad is a bit of hack compared to just examining RunFlag. If a machine is running it should have both RunFlag true and significant load in the right direction, ( MyLoad < SmallLoad ) where sign convention matters and cooling is negative. It could be possible that a positive MyLoad gets passed in and you don't want it to run in that case.

And yes, as @rraustad suggests, if the machine is not running it definitely needs to make a zero flow request via SetComponentFlowRate(). It may still have flow if in series with something else but that will at least make request for zero flow.

I would plot these variables for the towers -- to see how plant flow rates are responding and make sure the tower fan is off.

Output:Variable,*,Plant Component Distributed Demand Rate,detailed; !- HVAC Average [W]    
Output:Variable,*,System Node Requested Mass Flow Rate, detailed; !- HVAC Average [kg/s]
Output:Variable,*,System Node Mass Flow Rate,detailed; !- HVAC Average [kg/s]
Output:Variable,*,Cooling Tower Fan Electricity Rate,detailed; !- HVAC Average [W]

Various review comments were received.  These were all addressed in this commit.
@RKStrand
Copy link
Contributor Author

Thanks, @rraustad and @EnergyArchmage, for your comments. I believe that I have addressed them all with the most recent commit (the one right before I merged in develop). Specifically:

  • PlantUtilities::SetComponentFlowRate is now called after the flow is set to zero
  • The dual if statement has been converted to if-else if and the order of the checks switched
  • Strange "TODO" comment removed in a pre-existing unit test
  • The if check about load has been changed to avoid loads of the wrong sign and also check the run flag
  • The output variables were added as suggested--everything looks like what one would expect (when the second cooling tower isn't running, there is no flow and no fan energy); will post graph/data here shortly

I think that was everything to date. Did I miss anything or is there anything else that needs to be done here?

@RKStrand RKStrand requested a review from rraustad August 13, 2024 19:31
@RKStrand
Copy link
Contributor Author

10634FixGraph

@@ -6355,6 +6344,7 @@ namespace CondenserLoopTowers {
// This subroutine is for passing results to the outlet water node.

// set node information
PlantUtilities::SafeCopyPlantNode(state, this->WaterInletNodeNum, this->WaterOutletNodeNum);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RKStrand hope you don't mind me jumping in here. When components are in series, this is needed to pass data down the branch to the next component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not at all, @EnergyArchmage! Thanks for making that change.

@EnergyArchmage
Copy link
Contributor

This looks good to me!


if (std::abs(MyLoad) <= HVAC::SmallLoad) {
if ((std::abs(MyLoad) <= HVAC::SmallLoad) || !RunFlag) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if just !RunFlag would meet the intent. I would think RunFlag would be false if (std::abs(MyLoad) <= HVAC::SmallLoad) but then I am not sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure either and given that the Merkel model already used MyLoad, I felt like having both would be "safer". My guess is that both of these flags will probably trip this IF at the same time, but I didn't see anything wrong with doing it this way which seemed like it would catch all conditions.

@@ -5529,6 +5513,11 @@ namespace CondenserLoopTowers {
CalcBasinHeaterPower(
state, this->BasinHeaterPowerFTempDiff, this->BasinHeaterSchedulePtr, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
return;
} else if (this->WaterMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance || (MyLoad > HVAC::SmallLoad)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting. If this conditional is checked then the tower is running. I can't be sure if the water mass flow rate could really be this small if the tower is running but then you have the plant resolver making that determination. Also not sure of the load check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that there was a basin heater check in checkMassFlowAndLoad similar to this. Does that make this new code unnecessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left this alone because it was the one that was identified as working properly before the defect was logged. I'll admit, I did not see why it did this check (seemed confusing). However, I left it alone in the Merkel model because I didn't see a compelling reason to fix something that wasn't broken. You'll notice that the code here is slightly different than the code in checkMassFlowAndLoad--intentionally so because I trust the logic in checkMassFlowAndLoad and it makes more logical sense. So, I don't think the new code is unnecessary. It was somewhat based on what was done here in the Merkel model, with changes to the logic (by me and then improved with your suggestions).


bool returnFlagSet = false;
this->checkMassFlowAndLoad(state, MyLoad, RunFlag, returnFlagSet);
if (returnFlagSet) return;
Copy link
Contributor

@rraustad rraustad Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you made this function a bool it would just be if (this->checkMassFlowAndLoad(state, MyLoad, RunFlag) return;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I was concerned that a function would then be setting other parameters and calling other routines, not just getting a bool result. I felt like that was a violation of some standard, but I'll admit that I don't know whether that is an E+ standard or something that I simply picked up over the years that maybe isn't completely true. @Myoldmopar, any thoughts on this?

@Myoldmopar
Copy link
Member

I pulled develop and this is still happy. I'm going to mark this ready for merge, but hold off from actually merging while I await clean CI results on other branches.

@Myoldmopar
Copy link
Member

Pulled develop in and everything is happy, merging this. Thanks @RKStrand

@Myoldmopar Myoldmopar merged commit 9a7218c into develop Aug 16, 2024
15 checks passed
@Myoldmopar Myoldmopar deleted the 10634CondenserNotFollowingPlanOpScheme branch August 16, 2024 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Defect Includes code to repair a defect in EnergyPlus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PlantEquipmentOperation:OutdoorDryBulb does not work with some components
9 participants