Skip to content

Commit

Permalink
ChW controller improve temperature and humidity control
Browse files Browse the repository at this point in the history
  • Loading branch information
mjwitte committed Mar 10, 2019
1 parent 865c9f0 commit 53543cb
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 71 deletions.
88 changes: 18 additions & 70 deletions src/EnergyPlus/HVACControllers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1280,54 +1280,23 @@ namespace HVACControllers {
}

} else if (SELECT_CASE_var == iTemperatureAndHumidityRatio) { // 'TemperatureAndHumidityRatio'
ControllerProps(ControlNum).SensedValue = Node(SensedNode).Temp;
// Setpoint temp calculated once each HVAC time step to identify approach temp and whether or not humrat control is necessary
// WARNING: The scheme for computing the setpoint for the dual temperature and humidity ratio
// control strategy breaks down whenever the sensed node temperature is modified by
// a controller fired after the current one. Indeed the final sensed node temperature
// is likely to have changed in the meantime if the other controller is active,
// thereby invalidating the setpoint calculation for the other controller performed
// earlier on the air loop.
if (ControllerProps(ControlNum).HumRatCtrlOverride) {
// Humidity ratio control
ControllerProps(ControlNum).SensedValue = Node(SensedNode).HumRat;
} else {
// Temperature control
ControllerProps(ControlNum).SensedValue = Node(SensedNode).Temp;
}
if (!ControllerProps(ControlNum).IsSetPointDefinedFlag) {
// NOTE: For TEMPANDHUMRAT control the computed value ControllerProps(ControlNum)%SetPointValue
// depends on:
// - Node(SensedNode)%HumRatMax
// - Node(SensedNode)%Temp
// - Node(SensedNode)%HumRat
if ((Node(SensedNode).HumRatMax > 0) && (Node(SensedNode).HumRat > Node(SensedNode).HumRatMax)) {
// Setpoint can only be computed once per time step
// Check if outlet air humidity ratio is greater than the set point. If so, calculate new temperature based set point.
// See routine CalcSimpleController() for the sequence of operations.
// Calculate the approach temperature (difference between SA dry-bulb temp and SA dew point temp)
ApproachTemp = Node(SensedNode).Temp - PsyTdpFnWPb(Node(SensedNode).HumRat, OutBaroPress);
// Calculate the dew point temperature at the SA humidity ratio setpoint
DesiredDewPoint = PsyTdpFnWPb(Node(SensedNode).HumRatMax, OutBaroPress);
// Adjust the calculated dew point temperature by the approach temp. Should be within 0.3C of air temperature.
HumidityControlTempSetPoint = DesiredDewPoint + min(0.3, ApproachTemp);
// NOTE: The next line introduces a potential discontinuity into the residual function
// which could prevent the root finder from finding the root it if were done at each
// controller iteration. For this reason we perform the setpoint calculation only
// once at the beginning of the controller and air loop simulation.
// Use lower of temperature and humidity based set point.
// See routine CalcSimpleController() for the sequence of operations.
ControllerProps(ControlNum).SetPointValue = min(
Node(SensedNode).TempSetPoint,
HumidityControlTempSetPoint); // Pure temperature setpoint | Temperature setpoint to achieve the humidity ratio setpoint
// Don't allow set point temperature to be below the actuator node water temperature
ControllerProps(ControlNum).SetPointValue =
max(ControllerProps(ControlNum).SetPointValue, Node(ControllerProps(ControlNum).ActuatedNode).Temp);
// Overwrite the "pure" temperature setpoint with the actual setpoint that takes into
// account the humidity ratio setpoint.
// NOTE: Check that this does not create side-effects somewhere else in the code.
Node(SensedNode).TempSetPoint = ControllerProps(ControlNum).SetPointValue;
// Finally indicate thate the setpoint has been computed
ControllerProps(ControlNum).IsSetPointDefinedFlag = true;
if (ControllerProps(ControlNum).HumRatCtrlOverride) {
// Humidity ratio control
ControllerProps(ControlNum).SetPointValue = Node(SensedNode).HumRatMax;
} else {
// Pure temperature setpoint control strategy
ControllerProps(ControlNum).SetPointValue = Node(SensedNode).TempSetPoint;
// Finally indicate thate the setpoint has been computed
ControllerProps(ControlNum).IsSetPointDefinedFlag = true;
}
// Finally indicate thate the setpoint has been computed
ControllerProps(ControlNum).IsSetPointDefinedFlag = true;
}

} else if (SELECT_CASE_var == iHumidityRatio) { // 'HumidityRatio'
Expand Down Expand Up @@ -1465,6 +1434,10 @@ namespace HVACControllers {
(0.001 / (2100.0 * max(ControllerProps(ControlNum).MaxVolFlowActuated, SmallWaterVolFlow))) * (HVACEnergyToler / 10.0);
// do not let the controller tolerance exceed 1/10 of the loop temperature tolerance.
ControllerProps(ControlNum).Offset = min(0.1 * HVACTemperatureToler, ControllerProps(ControlNum).Offset);
if (ControllerProps(ControlNum).ControlVar == HVACControllers::iTemperatureAndHumidityRatio) {
// for temperature and humidity control, need tighter tolerance if humidity control kicks in
ControllerProps(ControlNum).Offset = ControllerProps(ControlNum).Offset*0.1;
}
ReportSizingOutput(ControllerProps(ControlNum).ControllerType,
ControllerProps(ControlNum).ControllerName,
"Controller Convergence Tolerance",
Expand Down Expand Up @@ -1587,33 +1560,8 @@ namespace HVACControllers {
FindRootSimpleController(ControlNum, FirstHVACIteration, IsConvergedFlag, IsUpToDateFlag, ControllerName);

} else {

// We need to evaluate the sensed node temperature with the max actuated value before
// we can compute the actual setpoint for the dual humidity ratio / temperature strategy.
{
auto const SELECT_CASE_var(ControllerProps(ControlNum).ControlVar);
if ((SELECT_CASE_var == iTemperature) || (SELECT_CASE_var == iHumidityRatio) || (SELECT_CASE_var == iFlow)) {
// Always start with min point by default for the other control strategies
ControllerProps(ControlNum).NextActuatedValue = RootFinders(ControlNum).MinPoint.X;

} else if (SELECT_CASE_var == iTemperatureAndHumidityRatio) {
if (!ControllerProps(ControlNum).IsSetPointDefinedFlag) {
// Always start with max point if setpoint not yet computed. See routine InitController().
ControllerProps(ControlNum).NextActuatedValue = RootFinders(ControlNum).MaxPoint.X;
} else {
// If setpoint already exists (i.e., HumRatMax <= 0) then try min point first as in simple
// temperature control case.
ControllerProps(ControlNum).NextActuatedValue = RootFinders(ControlNum).MinPoint.X;
}

} else {
// Should never happen
ShowSevereError("CalcSimpleController: HVAC controller failed at " + CreateHVACStepFullString());
ShowContinueError(" Controller name=" + ControllerProps(ControlNum).ControllerName);
ShowContinueError(" Unrecognized control variable type=" + TrimSigDigits(ControllerProps(ControlNum).ControlVar));
ShowFatalError("Preceding error causes program termination.");
}
}
// Always start with min point by default
ControllerProps(ControlNum).NextActuatedValue = RootFinders(ControlNum).MinPoint.X;
}

// Process current iterate and compute next candidate if needed
Expand Down
4 changes: 3 additions & 1 deletion src/EnergyPlus/HVACControllers.hh
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ namespace HVACControllers {
bool BypassControllerCalc; // set true for OA sys water coils
int AirLoopControllerIndex; // index to controller on specific air loop

bool HumRatCtrlOverride; // true if TemperatureAndHumidityRatio control switches to humidity ratio control

// Default Constructor
ControllerPropsType()
: ControllerType_Num(ControllerSimple_Type), ControlVar(iNoControlVariable), ActuatorVar(0), Action(iNoAction), InitFirstPass(true),
Expand All @@ -242,7 +244,7 @@ namespace HVACControllers {
ActuatedNodePlantLoopNum(0), ActuatedNodePlantLoopSide(0), ActuatedNodePlantLoopBranchNum(0), SensedNode(0),
IsSetPointDefinedFlag(false), SetPointValue(0.0), SensedValue(0.0), DeltaSensed(0.0), Offset(0.0), HumRatCntrlType(0), Range(0.0),
Limit(0.0), TraceFileUnit(0), FirstTraceFlag(true), BadActionErrCount(0), BadActionErrIndex(0), FaultyCoilSATFlag(false),
FaultyCoilSATIndex(0), FaultyCoilSATOffset(0.0), BypassControllerCalc(false), AirLoopControllerIndex(0)
FaultyCoilSATIndex(0), FaultyCoilSATOffset(0.0), BypassControllerCalc(false), AirLoopControllerIndex(0), HumRatCtrlOverride(false)
{
}
};
Expand Down
28 changes: 28 additions & 0 deletions src/EnergyPlus/SimAirServingZones.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2864,6 +2864,9 @@ namespace SimAirServingZones {
// E.g., actuator inlet water flow
for (int AirLoopControlNum = 1; AirLoopControlNum <= PrimaryAirSystem(AirLoopNum).NumControllers; ++AirLoopControlNum) {

// For temperature and humidity control reset humidity control override
HVACControllers::ControllerProps(PrimaryAirSystem(AirLoopNum).ControllerIndex(AirLoopControlNum)).HumRatCtrlOverride = false;

// BypassOAController is true here since we do not want to simulate the controller if it has already been simulated in the OA system
// ControllerConvergedFlag is returned true here for water coils in OA system
ManageControllers(PrimaryAirSystem(AirLoopNum).ControllerName(AirLoopControlNum),
Expand Down Expand Up @@ -2960,6 +2963,31 @@ namespace SimAirServingZones {
// not converge
ControllerConvergedFlag = PrimaryAirSystem(AirLoopNum).ControlConverged(AirLoopControlNum);
IsUpToDateFlag = true;
} else {
{
auto &thisController(HVACControllers::ControllerProps(PrimaryAirSystem(AirLoopNum).ControllerIndex(AirLoopControlNum)));
if (thisController.ControlVar == HVACControllers::iTemperatureAndHumidityRatio) {
// For temperature and humidity control, after temperature control is converged, check if humidity setpoint is met
if (!thisController.HumRatCtrlOverride) {
if (Node(thisController.SensedNode).HumRat > (Node(thisController.SensedNode).HumRatMax + thisController.Offset)) {
// Turn on humdity control and restart controller
ControllerConvergedFlag = false;
thisController.HumRatCtrlOverride = true;
IsUpToDateFlag = false;
ManageControllers(PrimaryAirSystem(AirLoopNum).ControllerName(AirLoopControlNum),
PrimaryAirSystem(AirLoopNum).ControllerIndex(AirLoopControlNum),
FirstHVACIteration,
AirLoopNum,
iControllerOpWarmRestart,
ControllerConvergedFlag,
IsUpToDateFlag,
BypassOAController,
AllowWarmRestartFlag);
SimAirLoopComponents(AirLoopNum, FirstHVACIteration);
}
}
}
}
}

} // End of the Convergence Iteration
Expand Down

7 comments on commit 53543cb

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

ChwCoilHumCtrl-7001 (mjwitte) - x86_64-Linux-Ubuntu-18.04-cppcheck-1.82: OK (0 of 0 tests passed, 0 test warnings)

Build Badge

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

ChwCoilHumCtrl-7001 (mjwitte) - i386-Windows-7-VisualStudio-14: OK (3117 of 3117 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

ChwCoilHumCtrl-7001 (mjwitte) - x86_64-Linux-Ubuntu-18.04-gcc-7.3-UnitTestsCoverage-Debug: OK (1839 of 1839 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

ChwCoilHumCtrl-7001 (mjwitte) - x86_64-Linux-Ubuntu-18.04-gcc-7.3: OK (3140 of 3157 tests passed, 2 test warnings)

Messages:

  • 19 tests had: EIO diffs.
  • 14 tests had: ESO big diffs.
  • 6 tests had: MTR small diffs.
  • 17 tests had: Table big diffs.
  • 13 tests had: MTR big diffs.
  • 5 tests had: ESO small diffs.
  • 7 tests had: ERR diffs.
  • 2 tests had: Table small diffs.

Failures:

regression Test Summary

  • Passed: 641
  • Failed: 17

Build Badge Test Badge

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

ChwCoilHumCtrl-7001 (mjwitte) - x86_64-Linux-Ubuntu-18.04-custom_check: OK (3 of 3 tests passed, 0 test warnings)

Build Badge

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

ChwCoilHumCtrl-7001 (mjwitte) - Win64-Windows-7-VisualStudio-14: OK (3100 of 3117 tests passed, 0 test warnings)

Failures:

regression Test Summary

  • Passed: 621
  • Failed: 17

Build Badge Test Badge

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

ChwCoilHumCtrl-7001 (mjwitte) - x86_64-Linux-Ubuntu-18.04-gcc-7.3-IntegrationCoverage-Debug: OK (2480 of 2482 tests passed, 0 test warnings)

Failures:

integration Test Summary

  • Passed: 641
  • Timeout: 2

Build Badge Test Badge Coverage Badge

Please sign in to comment.