Skip to content

Add Plant Manager dynamic operating capacity calls to Chiller:Electric:EIR - #11727

Open
rraustad wants to merge 8 commits into
developfrom
6436-Chiller-RefCap-at-PLRof1-is-constant
Open

Add Plant Manager dynamic operating capacity calls to Chiller:Electric:EIR#11727
rraustad wants to merge 8 commits into
developfrom
6436-Chiller-RefCap-at-PLRof1-is-constant

Conversation

@rraustad

@rraustad rraustad commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Pull request overview

Description of the purpose of this PR

The plant loop Plant Manager dispatches load to plant components according to the PlantLoop Load Distribution Scheme. In order for the Plant Manager to accurately dispatch plant components the Plant Manager must have accurate knowledge of instantaneous operating capacity. For equipment that changes operating capacity based on, for example, leaving water temperature or outdoor air conditions, the instantaneous operating capacity changes as operating conditions change. Fro this reason, a worker function was added to reports back to the Plant Manager the instantaneous operating capacity of the Chiller:Electric:EIR object.

PlantLoop,
  UniformPLR;                 !- Load Distribution Scheme

Pull Request Author

  • 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
  • If adding/removing any output files (e.g., eplustbl.*)
    • Update ..\scripts\Epl-run.bat
    • Update ..\scripts\RunEPlus.bat
    • Update ..\src\EPLaunch\ MainModule.bas, epl-ui.frm, and epl.vbp (VersionComments)
    • Update ...github\workflows\energyplus.py

Reviewer

  • 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

@rraustad rraustad self-assigned this Aug 5, 2026
@rraustad rraustad added the Defect Includes code to repair a defect in EnergyPlus label Aug 5, 2026
Real64 capacityModifierFuncTemp = Curve::CurveValue(state, this->ChillerCapFTIndex, loadSideOutletSetpointTemp, sourceInletTemp);
return this->RefCap * capacityModifierFuncTemp;
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I added this new function, wrote a unit test that tested this function, and then tried to prove the value using a test file. I found no changes at all between develop and this branch and then realized that the Plant Manager was not calling the getDynamicMaxCapacity function in places that mattered. The new calls were added to PlantCondLoopOperation such that the plant manager now knows the dynamic capacity of the EIR chiller.

"Curve:Biquadratic, Air cooled CentCapFT, 0.257896, 0.0389016, -0.00021708, 0.0468684, -0.00094284, -0.00034344, 5, 10, 24, 35, , , , , ;",
"Curve:Biquadratic, Air cooled CentEIRFT, 0.933884, -0.058212, 0.00450036, 0.00243, 0.000486, -0.001215, 5, 10, 24, 35, , , , , ;",
"Curve:Biquadratic, Air cooled CentCapFT, 0.257896, 0.0389016, -0.00021708, 0.0468684, -0.00094284, -0.00034344, 5, 10, 5, 35, , , , , ;",
"Curve:Biquadratic, Air cooled CentEIRFT, 0.933884, -0.058212, 0.00450036, 0.00243, 0.000486, -0.001215, 5, 10, 5, 35, , , , , ;",

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The minimum input limit for OAT in these curves was not providing the change expected when calling getDynamicMaxCapacity, because OAT was 12C and 5C in this unit test, so the minimum OAT limit for the curve object was expanded.

@rraustad

rraustad commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

A test file shows the impact of this change. Starting with test file ElectricEIRChiller, the plant components were changed to have 2 equally sized chillers but the CAPFT curve was adjusted for 1 of the chillers so that chiller had slightly higher capacity.

Curve:Biquadratic,
  ChillerCentCapFT,        !- Name
  0.257896E+00,            !- Coefficient1 Constant

Curve:Biquadratic,
  ChillerCentCapFT2,        !- Name
  0.287896E+00,            !- Coefficient1 Constant

The plant loop was set to use UniformPLR as the Load Distribution Scheme:

PlantLoop,
  Chilled Water Loop,      !- Name
  UniformPLR;                 !- Load Distribution Scheme

ElectricEIRChiller_2Chillers.idf.txt

The results show that this branch dispatches the chillers in a uniform manner based on PLR. In develop, the Plant Manager believes the chillers are the same size and so dispatches the load equally between the chillers (top row). This results in different PLRs for the chillers because they have different real time capacities. In this branch the Plant Manager knows a more accurate representation of instantaneous chiller capacity such that the chillers can be dispatched correctly to yield the same PLR (UniformPLR) for each chiller.

image

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

⚠️ Regressions detected on macos-14 for commit 9c0f146

Regression Summary
  • EIO: 35
  • ERR: 12
  • ESO Big Diffs: 31
  • Table Big Diffs: 21
  • Table String Diffs: 10
  • ESO Small Diffs: 8
  • MTR Small Diffs: 15
  • Table Small Diffs: 5
  • MTR Big Diffs: 15

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

⚠️ Regressions detected on ubuntu-24.04 for commit 9c0f146

Regression Summary
  • EIO: 35
  • ESO Big Diffs: 31
  • ERR: 12
  • Table Big Diffs: 21
  • Table String Diffs: 10
  • ESO Small Diffs: 8
  • MTR Small Diffs: 15
  • Table Small Diffs: 5
  • MTR Big Diffs: 15

@rraustad

rraustad commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

@mitchute there were 2 integration failures.

The following tests FAILED:
471 - integration.PlantLoopHeatPump_EIR_AirSource_and_AWHP (Failed)
753 - integration._ElectricASHRAE205Chiller (Failed)

Neither of these files have Chiller:Electric:EIR yet both were calling the new function (actually these 2 flles were calling getDynamicMaxCapacity in PlantLoopHeatPumpEIR and ElectricChillers, respectively).

Real64 ElectricEIRChillerSpecs::getDynamicMaxCapacity 

in ChillerElectricEIR.cc when I think they should not have (wrong plant component type). I am not sure what is causing that so am asking for some guidance.

auto &this_component = this_loopside.Branch(BranchNum).Comp(CompNum);
this_component.MaxLoad = this_component.getDynamicMaxCapacity(state);

Real64 CompData::getDynamicMaxCapacity(EnergyPlusData &state) const
{
    if (this->compPtr == NULL) {
        return this->MaxLoad;
    }
    Real64 possibleLoad = this->compPtr->getDynamicMaxCapacity(state);
    return (possibleLoad == 0) ? this->MaxLoad : possibleLoad;
}

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

⚠️ Regressions detected on macos-14 for commit 8f7f741

Regression Summary
  • EIO: 37
  • ERR: 14
  • ESO Big Diffs: 33
  • Table Big Diffs: 22
  • Table String Diffs: 10
  • Table Small Diffs: 6
  • ESO Small Diffs: 8
  • MTR Small Diffs: 15
  • MTR Big Diffs: 15

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

⚠️ Regressions detected on ubuntu-24.04 for commit 8f7f741

Regression Summary
  • EIO: 37
  • ESO Big Diffs: 33
  • ERR: 14
  • Table Big Diffs: 23
  • Table String Diffs: 12
  • ESO Small Diffs: 8
  • MTR Small Diffs: 15
  • Table Small Diffs: 5
  • MTR Big Diffs: 15

@rraustad

rraustad commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Ah, so this is the reason. Maybe this is OK as-is since it appears to return the correct RefCap (both test files) which is what it was doing before this new function was added. I am just not sure how to calculate a CapFT for this chiller type, or how to discern what chiller type is calling (e.g., Chiller:Electric:ASHRAE205 or Chiller:Electric:EIR). The CapFT index being 0 for these 2 files that failed is a clue to something that needs fixing, I'm just not sure what that is although the same answer as before is being passed back to the plant so this issue does not pose an immediate problem.

struct ASHRAE205ChillerSpecs : ChillerElectricEIR::ElectricEIRChillerSpecs

struct HeatPumpAirToWater : public EIRPlantLoopHeatPump

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

⚠️ Regressions detected on ubuntu-24.04 for commit d29a994

Regression Summary
  • ERR: 19
  • ESO Small Diffs: 89
  • MTR Small Diffs: 90
  • EIO: 63
  • Table Small Diffs: 30
  • Table String Diffs: 16
  • ESO Big Diffs: 39
  • Table Big Diffs: 27
  • MTR Big Diffs: 17

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

⚠️ Regressions detected on macos-14 for commit d29a994

Regression Summary
  • ERR: 19
  • ESO Small Diffs: 84
  • MTR Small Diffs: 85
  • EIO: 60
  • Table Small Diffs: 27
  • ESO Big Diffs: 38
  • Table Big Diffs: 26
  • Table String Diffs: 15
  • MTR Big Diffs: 17

  Preserve known zero capacity across all plant load distribution schemes.
  Limit optimal and setpoint-based dispatch to the dynamic maximum.
  Account for EIR chiller MaxPLR, fouling, setpoints, and condenser
  temperature while preserving ASHRAE 205 behavior.
@mitchute
mitchute force-pushed the 6436-Chiller-RefCap-at-PLRof1-is-constant branch from 964634b to aa691a9 Compare September 4, 2026 01:41
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

⚠️ Regressions detected on macos-14 for commit 19c102b

Regression Summary
  • ERR: 19
  • ESO Small Diffs: 84
  • MTR Small Diffs: 85
  • EIO: 59
  • Table Small Diffs: 28
  • ESO Big Diffs: 37
  • Table Big Diffs: 24
  • Table String Diffs: 12
  • MTR Big Diffs: 16

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

⚠️ Regressions detected on ubuntu-24.04 for commit 19c102b

Regression Summary
  • ERR: 19
  • ESO Small Diffs: 89
  • MTR Small Diffs: 90
  • EIO: 62
  • Table Small Diffs: 30
  • Table String Diffs: 15
  • ESO Big Diffs: 38
  • Table Big Diffs: 26
  • MTR Big Diffs: 16

  Preserve component design maximum capacity so Optimal dispatch can
  scale its target load while maintaining the configured optimum PLR.

  Treat known dynamic zero capacity as a valid operating condition in
  UniformPLR and SequentialUniformPLR without emitting repeated warnings.

  Add unit coverage for zero capacity, restored capacity, optimum-load
  scaling, redistribution, and warning suppression.
ChangeInLoad = min(ChangeInLoad, dynamicMaxLoad);
}
} else if (hasDynamicMaxLoad) {
ChangeInLoad = min(dynamicMaxLoad, std::abs(RemLoopDemand));

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

We need to discuss this on the call tomorrow.

  - calculate variable-speed tower capacity without altering warning state
  - use the maximum-range fallback when the tower root is outside model bounds
  - exclude known-zero dynamic capacities from UniformLoad allocation
  - add coverage for quiet tower queries and zero-capacity load sharing
  Preserve design minimum PLR when available component capacity changes, and apply the scaled minimum to
  uniform PLR and component-setpoint dispatch. Add tests for reduced and known-zero dynamic capacity.
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

⚠️ Regressions detected on macos-14 for commit 91288e3

Regression Summary
  • ESO Small Diffs: 84
  • MTR Small Diffs: 85
  • EIO: 59
  • Table Small Diffs: 28
  • ERR: 13
  • ESO Big Diffs: 37
  • Table Big Diffs: 24
  • Table String Diffs: 12
  • MTR Big Diffs: 16

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

⚠️ Regressions detected on ubuntu-24.04 for commit 91288e3

Regression Summary
  • ESO Small Diffs: 89
  • MTR Small Diffs: 90
  • EIO: 62
  • Table Small Diffs: 30
  • Table String Diffs: 15
  • ERR: 12
  • ESO Big Diffs: 38
  • Table Big Diffs: 26
  • MTR Big Diffs: 16

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.

Chiller maximum part load ratio = 1 is limiting chiller capacity to rated capacity

3 participants