Skip to content

#11567: ZoneHVAC:HybridUnitaryHVAC - Add choice to optimize Supply Temperature#11581

Open
kevin-moos wants to merge 11 commits into
NatLabRockies:developfrom
bigladder:HybridUnitaryHVAC-add-choice-to-optimize-supply-temperature
Open

#11567: ZoneHVAC:HybridUnitaryHVAC - Add choice to optimize Supply Temperature#11581
kevin-moos wants to merge 11 commits into
NatLabRockies:developfrom
bigladder:HybridUnitaryHVAC-add-choice-to-optimize-supply-temperature

Conversation

@kevin-moos
Copy link
Copy Markdown
Collaborator

Pull request overview

Description of the purpose of this PR

Rename "Objective Function to Minimize" to "Objective Function to Optimize" and add a choice to optimize Supply Temperature.

If cooling is required, minimize the supply air temperature.
If heating is required, maximize the supply air temperature. (This is the reason for renaming the field)
If only ventilation is required, minimize electricity usage (i.e. fan power).

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

@nealkruis nealkruis added the IDDChange Code changes impact the IDD file (cannot be merged after IO freeze) label May 7, 2026
@kevin-moos kevin-moos marked this pull request as ready for review May 19, 2026 16:20
@mitchute mitchute added the NewFeature Includes code to add a new feature to EnergyPlus label Jun 3, 2026
Copy link
Copy Markdown
Collaborator

@mitchute mitchute left a comment

Choose a reason for hiding this comment

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

A couple questions for consideration, which will help me finalize the review.

\paragraph{Field: Objective Function to Minimize}
In each time step ZoneHVAC:HybridUnitaryHVAC will choose one or more combinations of the controlled independent variables, subject to constraints, so as to best satisfy sensible load, latent load, and scheduled ventilation with the least amount of resource consumption. This alpha field specifies which resource will be minimized by the optimization. Valid choices include: Electricity Use, Second Fuel Use, Third Fuel Use, and Water Use. If this field is blank, the objective function will minimize electricity use.

\paragraph{Field: Objective Function to Optimize}
Copy link
Copy Markdown
Collaborator

@mitchute mitchute Jun 4, 2026

Choose a reason for hiding this comment

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

I see you are proposing to change this from "minimize" to "optimize," which I presume is due to adding this new option which you probably don't want to "minimize" in the true sense of the word. But now, we have the ambiguity of what you mean by "optimize." Can you add some descriptions of what the expected behavior is for each of the options now?

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.

Correct, the new option will either minimize or maximize the supply temperature (depending on cooling or heating). Everything else will still be minimized. I'll update the .tex and .idd to clarify this.

bool DidWePartlyMeetLoad = false;
Real64 OptimalSetting_RunFractionTotalFuel = IMPLAUSIBLE_POWER;
Real64 OptimalSetting_RunFractionSupplyTemperature =
CoolingRequested ? std::numeric_limits<Real64>::max() : std::numeric_limits<Real64>::min();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not just : 0 here? Not a big deal.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I saw this as a starting value convention for "checking and holding the final value" as:

            if (ObjectiveFunction == ObjectiveFunctionType::SupplyTemperature) {
                if (CoolingRequested && RunFractionSupplyTemperature < OptimalSetting_RunFractionSupplyTemperature) {
                    store_best_performing_mode = true;
                    OptimalSetting_RunFractionSupplyTemperature = RunFractionSupplyTemperature;
                }
                if (HeatingRequested && RunFractionSupplyTemperature > OptimalSetting_RunFractionSupplyTemperature) {
                    store_best_performing_mode = true;
                    OptimalSetting_RunFractionSupplyTemperature = RunFractionSupplyTemperature;
                }

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.

0 didn't work when the supply temperatures were all negative because I'm trying to find the max supply temperature. Another option could be -273.15.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Isn't std::numeric_limits<Real64>::min() approximately 0? Maybe you want lowest() instead?

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.

Ah, yes! I'll get that fixed. Thanks for pointing this out!

Comment thread idd/Energy+.idd.in
\note If this field is blank, default third fuel type = None.
\default None
A18, \field Objective Function to Minimize
A18, \field Objective Function to Optimize
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm pretty sure we don't need a transition rule on this since you're just renaming and not changing the current/default values.

bool DidWePartlyMeetLoad = false;
Real64 OptimalSetting_RunFractionTotalFuel = IMPLAUSIBLE_POWER;
Real64 OptimalSetting_RunFractionSupplyTemperature =
CoolingRequested ? std::numeric_limits<Real64>::max() : std::numeric_limits<Real64>::lowest();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There used to be comments here. I guess that's because you submitted this from a fork? NBD. I see you fixed the issue.

Comment on lines 1198 to +1485
@@ -1454,37 +1456,60 @@ namespace HybridEvapCoolingModel {

// Calculate partload fraction required to meet all requirements
// Fraction can be above 1 meaning its not able to do it completely in a time step
Real64 PartRuntimeFraction = CalculatePartRuntimeFraction(MinOA_Msa,
thisSetting.Supply_Air_Ventilation_Volume * state.dataEnvrn->StdRhoAir,
StepIns.RequestedCoolingLoad,
StepIns.RequestedHeatingLoad,
SensibleRoomORZone,
StepIns.ZoneDehumidificationLoad,
StepIns.ZoneMoistureLoad,
latentRoomORZone);

Real64 RunFractionTotalFuel;
thisSetting.Runtime_Fraction = CalculatePartRuntimeFraction(MinOA_Msa,
thisSetting.Supply_Air_Ventilation_Volume * state.dataEnvrn->StdRhoAir,
StepIns.RequestedCoolingLoad,
StepIns.RequestedHeatingLoad,
SensibleRoomORZone,
StepIns.ZoneDehumidificationLoad,
StepIns.ZoneMoistureLoad,
latentRoomORZone);

Real64 RunFractionTotalFuel(0);
Real64 RunFractionSupplyTemperature(0);
switch (ObjectiveFunction) {
default:
case ObjectiveFunctionType::ElectricityUse:
RunFractionTotalFuel = thisSetting.ElectricalPower * PartRuntimeFraction;
RunFractionTotalFuel = thisSetting.ElectricalPower * thisSetting.Runtime_Fraction;
break;
case ObjectiveFunctionType::SecondFuelUse:
RunFractionTotalFuel = thisSetting.SecondaryFuelConsumptionRate * PartRuntimeFraction;
RunFractionTotalFuel = thisSetting.SecondaryFuelConsumptionRate * thisSetting.Runtime_Fraction;
break;
case ObjectiveFunctionType::ThirdFuelUse:
RunFractionTotalFuel = thisSetting.ThirdFuelConsumptionRate * PartRuntimeFraction;
RunFractionTotalFuel = thisSetting.ThirdFuelConsumptionRate * thisSetting.Runtime_Fraction;
break;
case ObjectiveFunctionType::WaterUse:
RunFractionTotalFuel = thisSetting.WaterConsumptionRate * PartRuntimeFraction;
RunFractionTotalFuel = thisSetting.WaterConsumptionRate * thisSetting.Runtime_Fraction;
break;
case ObjectiveFunctionType::SupplyTemperature:
RunFractionSupplyTemperature = thisSetting.SupplyAirTemperature * thisSetting.Runtime_Fraction;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm trying to understand how the works. Is this supposed to be multiplied by the RTF here? It looks to me like the supply air temperature for thisSetting is based on the Mode <N> Supply Air Temperature Lookup Table Name from the object, and presumably you could have different combinations of SAT * RTF that don't actually minimize/maximize the supply air temp. Am I understanding this right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

IDDChange Code changes impact the IDD file (cannot be merged after IO freeze) NewFeature Includes code to add a new feature to EnergyPlus

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ZoneHVAC:HybridUnitaryHVAC - Add choice to optimize Supply Temperature

5 participants