Skip to content

Dew-point temperature setpoint for zone humidity control#11500

Open
lymereJ wants to merge 10 commits intodevelopfrom
dewpoint_humidistat
Open

Dew-point temperature setpoint for zone humidity control#11500
lymereJ wants to merge 10 commits intodevelopfrom
dewpoint_humidistat

Conversation

@lymereJ
Copy link
Copy Markdown
Collaborator

@lymereJ lymereJ commented Apr 7, 2026

Pull request overview

Description of the purpose of this PR

This (small) feature proposal to allow users to specify a maximum/minimum dew-point temperature setpoint for zone humidity control.

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

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

@lymereJ lymereJ added NewFeature Includes code to add a new feature to EnergyPlus IDDChange Code changes impact the IDD file (cannot be merged after IO freeze) labels Apr 7, 2026
@NatLabRockies NatLabRockies deleted a comment from github-actions bot Apr 7, 2026
@NatLabRockies NatLabRockies deleted a comment from github-actions bot Apr 7, 2026
@NatLabRockies NatLabRockies deleted a comment from github-actions bot Apr 7, 2026
@lymereJ
Copy link
Copy Markdown
Collaborator Author

lymereJ commented Apr 7, 2026

Here's a sample result of the new example file with dew-point temperature humidity control (dehumidifying setpoint set to 14.0 deg. C):
image

Copy link
Copy Markdown
Collaborator Author

@lymereJ lymereJ left a comment

Choose a reason for hiding this comment

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

Code walkthrough:

Comment on lines -35264 to +35276
A3 , \field Humidifying Relative Humidity Setpoint Schedule Name
A3 , \field Humidifying Setpoint Schedule Name
\required-field
\note hourly schedule values should be in Relative Humidity (percent)
\type object-list
\object-list ScheduleNames
A4 ; \field Dehumidifying Relative Humidity Setpoint Schedule Name
\note hourly schedule values should be in Relative Humidity (percent)
A4 , \field Dehumidifying Setpoint Schedule Name
\type object-list
\object-list ScheduleNames
A5 ; \field Control Variable
\note When using RelativeHumidity, the schedule values should be in percentages.
\type choice
\key RelativeHumidity
\key Dewpoint
\default RelativeHumidity
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.

Make the existing schedule inputs non-variable specific and add a control variable to indicate what variable is described by the schedules.

Comment on lines +3500 to +3517
if (humidityControlZone.humidityControlVariableType == DataZoneControls::HumidityCtrlVarType::RelativeHumidity) {
ZoneRHHumidifyingSetPoint = humidityControlZone.humidifyingSched->getCurrentVal();
ZoneRHDehumidifyingSetPoint = humidityControlZone.dehumidifyingSched->getCurrentVal();
} else if (humidityControlZone.humidityControlVariableType ==
DataZoneControls::HumidityCtrlVarType::DewPoint) { // Recalculate RH setpoint from DP
ZoneRHHumidifyingSetPoint =
100 * Psychrometrics::PsyRhFnTdbWPb(
state,
this->ZT,
Psychrometrics::PsyWFnTdpPb(state, humidityControlZone.humidifyingSched->getCurrentVal(), state.dataEnvrn->OutBaroPress),
state.dataEnvrn->OutBaroPress);
ZoneRHDehumidifyingSetPoint =
100 * Psychrometrics::PsyRhFnTdbWPb(
state,
this->ZT,
Psychrometrics::PsyWFnTdpPb(state, humidityControlZone.dehumidifyingSched->getCurrentVal(), state.dataEnvrn->OutBaroPress),
state.dataEnvrn->OutBaroPress);
}
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.

Use the less "invasive" approach; If a dew-point setpoint is used convert to RH since the existing approach uses RH.

Comment on lines +628 to +632
ASSERT_EQ(10.0, state->dataZoneCtrls->HumidityControlZone(CoolHeatZoneNum).humidifyingSched->getCurrentVal());
ASSERT_EQ(14.0, state->dataZoneCtrls->HumidityControlZone(CoolHeatZoneNum).dehumidifyingSched->getCurrentVal());
EXPECT_NEAR(-357.443,
state->dataZoneEnergyDemand->ZoneSysMoistureDemand(CoolHeatZoneNum).OutputRequiredToDehumidifyingSP,
0.001); // calculated based on 14 deg. C dew-point temperature
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.

Check that the moisture demand is calculated based on the DP setpont.

@lymereJ lymereJ marked this pull request as ready for review April 7, 2026 16:23
@NatLabRockies NatLabRockies deleted a comment from github-actions bot Apr 7, 2026
if (!s_ipsc->lAlphaFieldBlanks(5)) {
humidControlledZone.humidityControlVariableType =
static_cast<DataZoneControls::HumidityCtrlVarType>(getEnumValue(DataZoneControls::humidityCtrlVarTypeNamesUC, s_ipsc->cAlphaArgs(5)));
}
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.

This field has a default so cannot be blank.

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... Addressed.

A3 , \field Humidifying Relative Humidity Setpoint Schedule Name
A3 , \field Humidifying Setpoint Schedule Name
\required-field
\note hourly schedule values should be in Relative Humidity (percent)
Copy link
Copy Markdown
Collaborator

@rraustad rraustad Apr 7, 2026

Choose a reason for hiding this comment

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

Maybe keep the notes and add "or Dew Point (C) based on the Control Variable field." That would also send home that both schedules need to have the same units.

@mitchute
Copy link
Copy Markdown
Collaborator

Thanks, @lymereJ. Your implementation looks correct to me. However, while reviewing I noticed this block:

ZoneRHHumidifyingSetPoint = state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).humidifyingSched->getCurrentVal();
ZoneRHDehumidifyingSetPoint = state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).dehumidifyingSched->getCurrentVal();

which reads the RH setpoints directly from the schedules, even though we're inside of a dew point control block. Am I reading this right? If so, that looks like a bug.

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.

This looks ready. We still need to investigate what I noted here, but we can take that as a separate issue.

@lymereJ
Copy link
Copy Markdown
Collaborator Author

lymereJ commented Apr 13, 2026

@mitchute. Thanks for pointing this out. I looked at the code and I suspect that it might be correct.

This block that's located above determines if the ventilation control status is open or closed based on outdoor air dew-point temperature:

case VentCtrlType::DewPoint: {
if (state.dataEnvrn->OutDewPointTemp >= hybridVentMgr.MinOutdoorDewPoint &&
state.dataEnvrn->OutDewPointTemp <= hybridVentMgr.MaxOutdoorDewPoint) {
hybridVentMgr.ctrlStatus = VentCtrlStatus::Open;
} else {
hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
}
} break;

Then, if it is open ...
if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Open) {

... we get to the block that you shared. My understanding is that the intent is to ensure we don’t set the ventilation control status to “open” when the outdoor air has a humidity ratio above or below the level corresponding to the humidistat setpoint (which previously was evaluated only in terms of relative humidity). That makes sense to me. It also looks like I should add a check for the control variable I introduced to handle cases where the humidistat is controlled by dew point rather than RH. I’ll push those changes.

// Dew point control mode
if (hybridVentMgr.ctrlType == VentCtrlType::DewPoint) {
ZoneAirRH = PsyRhFnTdbWPb(state, thisZoneHB.MAT, thisZoneHB.airHumRat, state.dataEnvrn->OutBaroPress) * 100.0;
ZoneAirDewPoint = PsyTdpFnWPb(state, thisZoneHB.airHumRat, state.dataEnvrn->OutBaroPress);
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 don't think that this was used.

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.

4 participants