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

Fix chiller chilling when it is off #10793

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
Draft

Conversation

mjwitte
Copy link
Contributor

@mjwitte mjwitte commented Oct 17, 2024

Pull request overview

  • Added some temporary warnings for chiller condition where the chiller has been shut off due to zero condenser water flow, but produces phantom cooling if the evaporator flow is > zero (probably because it's on a series-active branch). e.g. from local annual simulation:
   ** Warning ** Chiller should be off, evap flow rate=1.4389689535199999, but EvapInletTemp=7.38915769242907 is != EvapOutletTemp=6.900575452477234, EvapInletNodeNum.Temp =7.38915769242907, EvapOutletNodeNum).Temp=6.900575452477234
   **   ~~~   ** MyLoad=-833.961772284167, RunFlag=true, QEvaporator=0, QCondenser=0, EvapMassFlowRate=1.4389689535199999, CondMassFlowRate = 0, Power=0 
   **   ~~~   **  Environment=RUN PERIOD 1, at Simulation time=05/16 09:15 - 09:30
   ** Warning ** Chiller should be off, evap flow rate=1.4389689535199999, but EvapInletTemp=7.396212077191015 is != EvapOutletTemp=6.6766091195480035, EvapInletNodeNum.Temp =7.396212077191015, EvapOutletNodeNum).Temp=6.6766091195480035
   **   ~~~   ** MyLoad=-868.746569242984, RunFlag=true, QEvaporator=0, QCondenser=0, EvapMassFlowRate=1.4389689535199999, CondMassFlowRate = 0, Power=0 
   **   ~~~   **  Environment=RUN PERIOD 1, at Simulation time=05/16 09:23 - 09:30
   ** Warning ** Chiller should be off, evap flow rate=1.4389689535199999, but EvapInletTemp=7.440021886600333 is != EvapOutletTemp=6.1678902101263375, EvapInletNodeNum.Temp =7.440021886600333, EvapOutletNodeNum).Temp=6.1678902101263375
   **   ~~~   ** MyLoad=-1084.7813548033087, RunFlag=true, QEvaporator=0, QCondenser=0, EvapMassFlowRate=1.4389689535199999, CondMassFlowRate = 0, Power=0 
   **   ~~~   **  Environment=RUN PERIOD 1, at Simulation time=05/20 09:00 - 09:15
  • Next commit fixes the issue by setting MyLoad to zero if lack of condenser water flow causes the chiller to be off. No more of the above warnings are produced (with a full annual regression).
  • Temporary warning code removed.

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

@mjwitte mjwitte added the Defect Includes code to repair a defect in EnergyPlus label Oct 17, 2024
@mjwitte
Copy link
Contributor Author

mjwitte commented Oct 17, 2024

@rraustad @EnergyArchmage This condition occurs when the chiller has a load, but the chiller shuts down here due to zero condenser water flow and leaves calculate with

// Set initial mass flow rates
if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
this->CondMassFlowRate = this->CondMassFlowRateMax;
PlantUtilities::SetComponentFlowRate(state, this->CondMassFlowRate, this->CondInletNodeNum, this->CondOutletNodeNum, this->CDPlantLoc);
PlantUtilities::PullCompInterconnectTrigger(
state, this->CWPlantLoc, this->CondMassFlowIndex, this->CDPlantLoc, DataPlant::CriteriaType::MassFlowRate, this->CondMassFlowRate);
if (this->CondMassFlowRate < DataBranchAirLoopPlant::MassFlowTolerance) {
if (this->EvapMassFlowRate < DataBranchAirLoopPlant::MassFlowTolerance) {
// Use PlantUtilities::SetComponentFlowRate to decide actual flow
PlantUtilities::SetComponentFlowRate(
state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
}
return;
}
}

This has been set before this exit:

this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp;

(which seems wrong, wouldn't you want to intialize outlet=inlet before that actual calcs happen?)

After this, update thinks the chiller is on, because there is a load and the evap mass flow rate is >0 so it skips the chiller of block:

if (MyLoad >= 0 || !RunFlag) { // Chiller not running so pass inlet states to outlet states
// Set node conditions
state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
if (this->CondenserType != DataPlant::CondenserType::WaterCooled) {
state.dataLoopNodes->Node(this->CondOutletNodeNum).HumRat = state.dataLoopNodes->Node(this->CondInletNodeNum).HumRat;
state.dataLoopNodes->Node(this->CondOutletNodeNum).Enthalpy = state.dataLoopNodes->Node(this->CondInletNodeNum).Enthalpy;
state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate = 0.0;
state.dataLoopNodes->Node(this->CondOutletNodeNum).MassFlowRate = 0.0;
}

And those line setting condense mass flow rates to zero seem wrong, because the chiller could have flow forced through the condenser even when it's off. this is ok, it's for aircooled condenser.

@mjwitte
Copy link
Contributor Author

mjwitte commented Oct 17, 2024

Oh, never mind the condenser flow rate comment, those lines are for aircooled condenser.

Copy link

⚠️ Regressions detected on macos-14 for commit ce1be3e

Regression Summary
  • ERR: 1

@rraustad
Copy link
Contributor

Line 1939 does seem wrong as something to do before a potential return at line 1970. Also, as an observation, if the return at 1970 happens I would think the calc routine would want to inform other later functions that the chiller RunFlag = false,

@mjwitte
Copy link
Contributor Author

mjwitte commented Oct 17, 2024

Line 1939 does seem wrong as something to do before a potential return at line 1970. Also, as an observation, if the return at 1970 happens I would think the calc routine would want to inform other later functions that the chiller RunFlag = false,

Given the arguments here

void ElectricEIRChillerSpecs::simulate(
    EnergyPlusData &state, const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag)

ElectricEIRChillerSpecs::calculate(EnergyPlusData &state, Real64 &MyLoad, bool const RunFlag)

Perhaps MyLoad should be set to zero before returning?

@rraustad
Copy link
Contributor

Perhaps MyLoad should be set to zero before returning?

Probably, because that return value for &CurLoad will be used by the calling routine (I think) to update the remaining load.

@rraustad
Copy link
Contributor

If the calling routine does use &CurLoad then I would think that MyLoad should represent exactly what load the chiller met. I don't think I have ever considered that before.

@EnergyArchmage
Copy link
Contributor

Yes, that is the idea. So it can update remaining load for dispatch to other machines if any.

Copy link

⚠️ Regressions detected on macos-14 for commit 41d5e18

Regression Summary
  • EIO: 1
  • ERR: 1
  • ESO Big Diffs: 1
  • Table Big Diffs: 1

Copy link

⚠️ Regressions detected on macos-14 for commit c9e51bd

Regression Summary
  • EIO: 1
  • ERR: 1
  • ESO Big Diffs: 1
  • Table Big Diffs: 1

@@ -1962,6 +1962,8 @@ void ElectricEIRChillerSpecs::calculate(EnergyPlusData &state, Real64 &MyLoad, b
state, this->CWPlantLoc, this->CondMassFlowIndex, this->CDPlantLoc, DataPlant::CriteriaType::MassFlowRate, this->CondMassFlowRate);

if (this->CondMassFlowRate < DataBranchAirLoopPlant::MassFlowTolerance) {
// Shut chiller off if there is no condenser water flow
MyLoad = 0.0;
Copy link
Contributor

@rraustad rraustad Oct 19, 2024

Choose a reason for hiding this comment

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

This does look like it boils down to this. I looked at PullCompInterconnectTrigger to see what that was trying to accomplish. This code looks like it can be deleted. I'm not asking for that to happen here but it's extra clock cycles. Removed in #10794,

    // Check to make sure we didn't reuse the index in multiple components
    if (CurCriteria.CallingCompLoopNum != plantLoc.loopNum || CurCriteria.CallingCompLoopSideNum != plantLoc.loopSideNum ||
        CurCriteria.CallingCompBranchNum != plantLoc.branchNum || CurCriteria.CallingCompCompNum != plantLoc.compNum) {
        // Diagnostic fatal: component does not properly utilize unique indexing
    }

@mjwitte
Copy link
Contributor Author

mjwitte commented Oct 29, 2024

With the same fix applied to all chiller types, annual regression results:

  "diffs": {
    "big_math": [ 37 files ]
      "5ZoneCoolBeam", eso
      "5ZoneDetailedIceStorageSimpleCtrl", eso and mtr
      "5ZoneDetailedIceStorage", eso and mtr
      "5ZoneDetailedIceStorage2", eso and mtr
      "5ZoneDetailedIceStorageCubicLinear", eso and mtr
      "5ZoneIceStorage", eso and mtr
      "ASHRAE901_OfficeLarge_STD2019_Denver_Chiller205", eso
      "ASHRAE901_OfficeLarge_STD2019_Denver_Chiller205_Detailed", eso
      "ASHRAE901_OfficeLarge_STD2019_Denver_ChillerEIR", eso
      "CompSetPtControl", eso and mtr
      "FourPipeBeamLargeOffice", eso
      "FreeCoolingChiller_wWaterSideEconomizer", eso
      "IceStorage-Series-ChillerUpstream", eso
      "IceStorage-Series-ChillerDownstream", eso
      "RadLoTempHydrCtrlOpt", eso
      "RadLoTempHydrHeatCool", eso and mtr
      "RadLoTempHydrCtrlOpt2", eso
      "RadLoTempHydrHeatCoolDry", eso and mtr
      "RadLoTempHydrISOPipeHT", eso
      "SeriesActiveBranch", eso and mtr
      "RadLoTempHydrHeatCoolDryCondFD", eso
      "RadLoTempCFloHeatCoolCondFD", eso
      "TermReheatPri-SecLoop", eso
      "WaterSideEconomizer_NonIntegrated", eso and mtr
      "WaterCooledChillerWithVSCondenserControl", eso
      "RadLoTempHydrCtrlOpt3" eso and mtr
    ],
    "small_math": [ 61 files ]
    "big_table": [ 18 files ]
      "5ZoneDetailedIceStorageSimpleCtrl", 0.8% cooling electricity
      "5ZoneDetailedIceStorage", 0.8% cooling electricity
      "5ZoneDetailedIceStorage2", 0.8% cooling electricity
      "5ZoneDetailedIceStorageCubicLinear", 0.8% cooling electricity
      "5ZoneIceStorage", 0.8% cooling electricity, 1% pumps
      "ASHRAE901_OfficeLarge_STD2019_Denver", no big diffs in ABUPS, some <1% diffs in resilience and OA limits
      "ASHRAE901_OfficeLarge_STD2019_Denver_Chiller205", 1% heat rejection water
      "ASHRAE901_OfficeLarge_STD2019_Denver_Chiller205_Detailed", 1.1% heat rejection elec, 0.6% heat rejection water
      "ASHRAE901_OfficeLarge_STD2019_Denver_ChillerEIR", no big diffs in ABUPS, some 1-2% diffs in resilience and OA limits
      "CompSetPtControl", 2% cooling electricity, pumps, and heat rejection
      "ASHRAE901_Hospital_STD2019_Denver", no big diffs in ABUPS, some 1-2% diffs in resilience and OA limits
      "EMSPlantLoopOverrideControl", no big diffs in ABUPS, some 1-2% diffs in resilience and OA limits
      "FourPipeBeamLargeOffice", no big diffs in ABUPS, <1% diff in cooling electricity at peak demand
      "PythonPluginPlantLoopOverrideControl", no big diffs in ABUPS, some <1% diffs in Monthly Roof Irrigation(?)
      "RadLoTempHydrHeatCool", 3% district cooling, 0.1% cooling electricity
      "RadLoTempHydrHeatCoolDry", 3% district cooling, 0.1% cooling electricity
      "SeriesActiveBranch", no big diffs in ABUPS, some big diffs in peak electricity time bins
      "WaterSideEconomizer_NonIntegrated", 3% natural gas, 6% fans, 10% pumps, 
                       7% Setpoint Not Met During Occupied Cooling (increase from 144 to 512, hmmmmmm)
    ],
    "small_table": [ 16 files ]
    "textual": [ 30 files, some eio, some err, some both ]
      "5ZoneCoolBeam",
      "5ZoneDetailedIceStorageSimpleCtrl",
      "5ZoneDetailedIceStorage",
      "5ZoneDetailedIceStorage2",
      "5ZoneDetailedIceStorageCubicLinear",
      "5ZoneIceStorage",
      "ASHRAE901_OfficeLarge_STD2019_Denver",
      "ASHRAE901_OfficeLarge_STD2019_Denver_Chiller205",
      "ASHRAE901_OfficeLarge_STD2019_Denver_Chiller205_Detailed",
      "ASHRAE901_OfficeLarge_STD2019_Denver_ChillerEIR",
      "CompSetPtControl",
      "ASHRAE901_Hospital_STD2019_Denver",
      "FourPipeBeamLargeOffice",
      "IceStorage-Series-ChillerDownstream",
      "HospitalLowEnergy",
      "PlantApplicationsGuide_Example1",
      "RadLoTempHydrHeatCool",
      "RadLoTempHydrHeatCoolDry",
      "SeriesActiveBranch",
      "RadLoTempHydrHeatCoolDryCondFD",
      "WaterSideEconomizer_NonIntegrated",
      "WaterCooledChillerWithVSCondenserControl",
      "RadLoTempHydrCtrlOpt3"
    ]

Copy link

⚠️ Regressions detected on macos-14 for commit 31375e7

Regression Summary
  • EIO: 16
  • ESO Big Diffs: 12
  • MTR Small Diffs: 14
  • Table Small Diffs: 7
  • Table Big Diffs: 9
  • ERR: 8
  • Table String Diffs: 4
  • ESO Small Diffs: 11
  • MTR Big Diffs: 3

@mjwitte
Copy link
Contributor Author

mjwitte commented Oct 29, 2024

@rraustad I'm doubting this approach now due to these results:

"WaterSideEconomizer_NonIntegrated", 3% natural gas, 6% fans, 10% pumps, 7% Setpoint Not Met During Occupied Cooling (increase from 144 to 512, hmmmmmm)

Maybe this needs to check for (gasp) flowlock before setting MyLoad=0.0? Or skip that on FirstHVACIteration?

@rraustad
Copy link
Contributor

Well, it looked good when I reviewed this. MyLoad is disconnected from water flow rate so, for now, I think no need to look at flowlock and this is just a way to tell the plant that this component did not meet a load or what was actually met (and probably should not exceed original MyLoad?). Since this does look like the correct approach I think verifying a components operation in 1 of these files. Was this component meeting a load that it shouldn't have, or is now passing that load to another component, or is off now and the plant load increases on the next iteration? Too hard to think this through without some hard data.

@mjwitte
Copy link
Contributor Author

mjwitte commented Oct 29, 2024

For WaterSideEconomizer_NonIntegrated-Chiller, here are some hours where the chiller is showing evap outlet temp < evap inlet temp when the chiller is off. Develop is on the left, this branch on the right.
image

This file has 652 hours like that with develop, zero hours with this branch, so maybe this is fixing a real problem.
WaterSideEconomizer_NonIntegrated-Develop.zip
WaterSideEconomizer_NonIntegrated.zip

@rraustad
Copy link
Contributor

rraustad commented Oct 29, 2024

I do think this is fixing something. Note the integrated economizer inlet now tracks the correct water temp. Why this temp changed from 10 C to 16 C is a bit of a mystery but without that free cooling the plant temps have risen. What are the plant outlet node temps wrt set point? maybe a plant outlet temp vs plant mass flow rate plot. And if the plant return water temp is > 12 C, why isn't the chiller on? is there a bypass pipe that has flow? There was no mass flow rate at the chiller before so it seems it should be off, but why? Availability Manager?

@mjwitte
Copy link
Contributor Author

mjwitte commented Oct 30, 2024

So, the waterside economizer HX hardly ever runs, and I haven't figured out why the chiller is off when there's a high loop demand. There's no plant availability manager, and a simple plant operating scheme with the chiller always available. There is flow through the HX on the chilled water side, but no flow on the other side of the HX. Not sure why the HX has flow if it's not contributing.

Hmmm, this is a water cooled Chiller:EngineDriven. Looking at 02/23 10:00-15:00, in both branches, the CENTRAL CHILLER:Chiller Evaporator Mass Flow Rate kg/s is zero, but there is flow on the Central Chiller Inlet/Outlet Nodes(!). The chiller is LeavingSetpointModulated, maybe that's not working right?
image

@rraustad
Copy link
Contributor

@EnergyArchmage has found a few places in code where the WWHX is not passing information correctly (i.e., SafeCopyPlantNode is needed in a few places). I can't recall exactly what the details are so maybe he could comment on what you are seeing.

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.

7 participants