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

Better humidity control for chilled water coils and for AirloopHVAC:UnitarySystem #7215

Merged
merged 18 commits into from
Mar 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
cb6f108
Temporary fix in GetCoilDesFlowT to protect against array bounds viol…
mjwitte Mar 8, 2019
3adf350
UnitarySystem fix humidity setpoint controls
mjwitte Mar 8, 2019
865c9f0
Merge remote-tracking branch 'remotes/origin/develop' into ChwCoilHum…
mjwitte Mar 9, 2019
53543cb
ChW controller improve temperature and humidity control
mjwitte Mar 10, 2019
7683df8
ChW controller - delete now unused variables
mjwitte Mar 11, 2019
6c08857
Revised fix in GetCoilDesFlowT to protect against array bounds violat…
mjwitte Mar 11, 2019
119c5bc
ChW controller - cleanup and move humctrl check into HVACControllers
mjwitte Mar 11, 2019
9451557
ChW controller - remove unused FirstHVACIteration args
mjwitte Mar 11, 2019
d136c4c
SetActuatedBranchFlowRate - avoid array bounds errors - move early es…
mjwitte Mar 11, 2019
56330bd
GetCoilDesFlowT_NoPeak - new unit test and cleanup
mjwitte Mar 11, 2019
ee06f4e
HVACControllers_CheckTempAndHumRatCtrl unit test
mjwitte Mar 11, 2019
0bd833d
Merge remote-tracking branch 'remotes/origin/develop' into ChwCoilHum…
mjwitte Mar 12, 2019
3f5a7e2
UnitarySystemModel_WaterCoilSPControl_Latent unit test
mjwitte Mar 12, 2019
4471a4e
ChW controller - vary offset only if needed for humidity control
mjwitte Mar 12, 2019
c029acf
Merge remote-tracking branch 'remotes/origin/develop' into ChwCoilHum…
mjwitte Mar 18, 2019
7fda469
UnitarySystem humidity controls - set node conditions in DX calc func…
mjwitte Mar 18, 2019
7883673
UnitarySystem humidity controls - fix unit test
mjwitte Mar 18, 2019
040fa15
UnitarySystem humidity controls - fix another unit test
mjwitte Mar 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/EnergyPlus/DXCoils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9523,6 +9523,11 @@ namespace DXCoils {
DXCoilFanOpMode(DXCoilNum) = FanOpMode;
DXCoil(DXCoilNum).CondInletTemp = CondInletTemp;

// set outlet node conditions
int airOutletNode = DXCoil(DXCoilNum).AirOutNode;
Node(airOutletNode).Temp = DXCoil(DXCoilNum).OutletAirTemp;
Node(airOutletNode).HumRat = DXCoil(DXCoilNum).OutletAirHumRat;

// calc secondary coil if specified
if (DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) {
CalcSecondaryDXCoils(DXCoilNum);
Expand Down Expand Up @@ -10181,6 +10186,12 @@ namespace DXCoils {
DXCoil(DXCoilNum).CondInletTemp = CondInletTemp;
DXCoilTotalCooling(DXCoilNum) = DXCoil(DXCoilNum).TotalCoolingEnergyRate;
DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);

// set outlet node conditions
int airOutletNode = DXCoil(DXCoilNum).AirOutNode;
Node(airOutletNode).Temp = DXCoil(DXCoilNum).OutletAirTemp;
Node(airOutletNode).HumRat = DXCoil(DXCoilNum).OutletAirHumRat;

}

void CalcDXHeatingCoil(int const DXCoilNum, // the number of the DX heating coil to be simulated
Expand Down Expand Up @@ -10643,6 +10654,11 @@ namespace DXCoils {
DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;

// set outlet node conditions
int airOutletNode = DXCoil(DXCoilNum).AirOutNode;
Node(airOutletNode).Temp = DXCoil(DXCoilNum).OutletAirTemp;
Node(airOutletNode).HumRat = DXCoil(DXCoilNum).OutletAirHumRat;

// calc secondary coil if specified
if (DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) {
CalcSecondaryDXCoils(DXCoilNum);
Expand Down Expand Up @@ -11148,6 +11164,11 @@ namespace DXCoils {
DXCoilOutletHumRat(DXCoilNum) = DXCoil(DXCoilNum).OutletAirHumRat;
DXCoil(DXCoilNum).CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure

// set outlet node conditions
int airOutletNode = DXCoil(DXCoilNum).AirOutNode;
Node(airOutletNode).Temp = DXCoil(DXCoilNum).OutletAirTemp;
Node(airOutletNode).HumRat = DXCoil(DXCoilNum).OutletAirHumRat;

// calc secondary coil if specified
if (DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) {
CalcSecondaryDXCoils(DXCoilNum);
Expand Down Expand Up @@ -12659,6 +12680,11 @@ namespace DXCoils {
DXCoilFanOpMode(DXCoilNum) = FanOpMode;
DXCoil(DXCoilNum).CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure

// set outlet node conditions
int airOutletNode = DXCoil(DXCoilNum).AirOutNode;
Node(airOutletNode).Temp = DXCoil(DXCoilNum).OutletAirTemp;
Node(airOutletNode).HumRat = DXCoil(DXCoilNum).OutletAirHumRat;

// calc secondary coil if specified
if (DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) {
CalcSecondaryDXCoils(DXCoilNum);
Expand Down Expand Up @@ -13371,6 +13397,11 @@ namespace DXCoils {
DXCoil(DXCoilNum).MSSpeedRatio = SpeedRatio;
DXCoil(DXCoilNum).MSCycRatio = CycRatio;

// set outlet node conditions
int airOutletNode = DXCoil(DXCoilNum).AirOutNode;
Node(airOutletNode).Temp = DXCoil(DXCoilNum).OutletAirTemp;
Node(airOutletNode).HumRat = DXCoil(DXCoilNum).OutletAirHumRat;

// calc secondary coil if specified
if (DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) {
CalcSecondaryDXCoils(DXCoilNum);
Expand Down
216 changes: 57 additions & 159 deletions src/EnergyPlus/HVACControllers.cc

Large diffs are not rendered by default.

17 changes: 6 additions & 11 deletions 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 Expand Up @@ -316,10 +318,9 @@ namespace HVACControllers {
// Beginning Initialization Section of the Module
//******************************************************************************

void ResetController(int const ControlNum, bool const FirstHVACIteration, bool const DoWarmRestartFlag, bool &IsConvergedFlag);
void ResetController(int const ControlNum, bool const DoWarmRestartFlag, bool &IsConvergedFlag);

void InitController(int const ControlNum,
bool const FirstHVACIteration, // TRUE if first full HVAC iteration in an HVAC timestep
bool &IsConvergedFlag);

void SizeController(int const ControlNum);
Expand Down Expand Up @@ -350,6 +351,8 @@ namespace HVACControllers {

bool CheckMaxActiveController(int const ControlNum);

void CheckTempAndHumRatCtrl(int const ControlNum, bool &IsConvergedFlag);

void SaveSimpleController(int const ControlNum, bool const FirstHVACIteration, bool const IsConvergedFlag);

// End Algorithm Section of the Module
Expand All @@ -363,14 +366,6 @@ namespace HVACControllers {
// End of Update subroutines for the Controller Module
// *****************************************************************************

// Beginning of Reporting subroutines for the Controller Module
// *****************************************************************************

void ReportController(int const ControlNum); // unused1208

// End of Reporting subroutines for the Controller Module
// *****************************************************************************

void ExitCalcController(int const ControlNum, Real64 const NextActuatedValue, int const Mode, bool &IsConvergedFlag, bool &IsUpToDateFlag);

// Beginning of Statistics subroutines for the Controller Module
Expand Down
10 changes: 6 additions & 4 deletions src/EnergyPlus/PlantUtilities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,12 @@ namespace PlantUtilities {
// Set flow on node and branch while honoring constraints on actuated node

auto &a_node(DataLoopNode::Node(ActuatedNode));
if (LoopNum == 0 || LoopSideNum == 0) {
// early in simulation before plant loops are setup and found
a_node.MassFlowRate = CompFlow;
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This must have fixed something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And neither should this be here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh- right - this fixed an array bounds problem. d136c4c
@rraustad Thanks for the review and merge.


auto &loop_side(DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum));

// store original flow
Expand Down Expand Up @@ -495,10 +501,6 @@ namespace PlantUtilities {
DataLoopNode::Node(NodeNum).MassFlowRate = a_node_MasFlowRate;
DataLoopNode::Node(NodeNum).MassFlowRateRequest = a_node_MasFlowRateRequest;
}

} else {
// early in simulation before plant loops are setup and found
a_node.MassFlowRate = CompFlow;
}
}

Expand Down
46 changes: 28 additions & 18 deletions src/EnergyPlus/ReportSizingManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4081,35 +4081,45 @@ namespace ReportSizingManager {
using DataEnvironment::StdRhoAir;

// FUNCTION LOCAL VARIABLE DECLARATIONS:
int DDAtSensPeak;
int TimeStepAtSensPeak;
int DDAtFlowPeak;
int TimeStepAtFlowPeak;
int DDAtSensPeak(0);
int TimeStepAtSensPeak(0);
int DDAtFlowPeak(0);
int TimeStepAtFlowPeak(0);
int CoolCapCtrl; // type of coil capacity control
int PeakLoadType;
int DDAtTotPeak;
int TimeStepAtTotPeak;
int TimeStepAtPeak;
int DDAtTotPeak(0);
int TimeStepAtTotPeak(0);
int TimeStepAtPeak(0);
Real64 ZoneCoolLoadSum(0); // sum of zone cooling loads at the peak [W]
Real64 AvgZoneTemp(0); // average zone temperature [C]
Real64 AvgSupTemp; // average supply temperature for bypass control [C]
Real64 TotFlow; // total flow for bypass control [m3/s]
Real64 MixTemp; // mixed air temperature at the peak [C]
Real64 AvgSupTemp(0.0); // average supply temperature for bypass control [C]
Real64 TotFlow(0.0); // total flow for bypass control [m3/s]
Real64 MixTemp(0.0); // mixed air temperature at the peak [C]

CoolCapCtrl = SysSizInput(SysNum).CoolCapControl;
PeakLoadType = SysSizInput(SysNum).CoolingPeakLoadType;
DDAtSensPeak = SysSizPeakDDNum(SysNum).SensCoolPeakDD;
TimeStepAtSensPeak = SysSizPeakDDNum(SysNum).TimeStepAtSensCoolPk(DDAtSensPeak);
DDAtFlowPeak = SysSizPeakDDNum(SysNum).CoolFlowPeakDD;
TimeStepAtFlowPeak = SysSizPeakDDNum(SysNum).TimeStepAtCoolFlowPk(DDAtFlowPeak);
DDAtTotPeak = SysSizPeakDDNum(SysNum).TotCoolPeakDD;
TimeStepAtTotPeak = SysSizPeakDDNum(SysNum).TimeStepAtTotCoolPk(DDAtTotPeak);
if (DDAtSensPeak > 0) {
TimeStepAtSensPeak = SysSizPeakDDNum(SysNum).TimeStepAtSensCoolPk(DDAtSensPeak);
DDAtFlowPeak = SysSizPeakDDNum(SysNum).CoolFlowPeakDD;
TimeStepAtFlowPeak = SysSizPeakDDNum(SysNum).TimeStepAtCoolFlowPk(DDAtFlowPeak);
DDAtTotPeak = SysSizPeakDDNum(SysNum).TotCoolPeakDD;
TimeStepAtTotPeak = SysSizPeakDDNum(SysNum).TimeStepAtTotCoolPk(DDAtTotPeak);

if (PeakLoadType == TotalCoolingLoad) {
TimeStepAtPeak = TimeStepAtTotPeak;
if (PeakLoadType == TotalCoolingLoad) {
TimeStepAtPeak = TimeStepAtTotPeak;
} else {
TimeStepAtPeak = TimeStepAtSensPeak;
}
} else {
TimeStepAtPeak = TimeStepAtSensPeak;
if ((CoolCapCtrl == VT) || (CoolCapCtrl == Bypass)) {
ShowWarningError("GetCoilDesFlow: AirLoopHVAC=" + SysSizInput(SysNum).AirPriLoopName +
"has no time of peak cooling load for sizing.");
ShowContinueError("Using Central Cooling Capacity Control Method=VAV instead of Bypass or VT.");
CoolCapCtrl = VAV;
}
}

if (CoolCapCtrl == VAV) {
DesExitTemp = FinalSysSizing(SysNum).CoolSupTemp;
DesFlow = FinalSysSizing(SysNum).MassFlowAtCoolPeak / StdRhoAir;
Expand Down
8 changes: 6 additions & 2 deletions src/EnergyPlus/UnitarySystem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10409,7 +10409,7 @@ namespace UnitarySystems {
// and if coolReheat, check hum rat as well
if (((NoLoadTempOut - DesOutTemp) < Acc) && ((NoLoadHumRatOut - DesOutHumRat) < HumRatAcc)) {
PartLoadFrac = 0.0;
} else if (SensibleLoad) { // need to turn on compressor to see if load is met
} else { // need to turn on compressor to see if load is met
PartLoadFrac = 1.0;
CompOn = 1;
m_WSHPRuntimeFrac = 1.0;
Expand Down Expand Up @@ -10574,7 +10574,9 @@ namespace UnitarySystems {
(this->m_TESOpMode == PackagedThermalStorageCoil::OffMode ||
this->m_TESOpMode == PackagedThermalStorageCoil::ChargeOnlyMode)) {
PartLoadFrac = 0.0;
} else {
} else if (!SensibleLoad) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Highlights an issue with all coils types when no sensible load exists and a latent load does. Logic at top of function could skip sensible PLR calcs and go directly to latent calcs. Sensible calcs are inside of if(SensibleLoad || LatentLoad) block.

PartLoadFrac = 0.0;
} else if (SensibleLoad) {

Par[9] = double(AirLoopNum);
Par[10] = 0.0;
Expand Down Expand Up @@ -10869,6 +10871,7 @@ namespace UnitarySystems {
FullOutput = DataLoopNode::Node(InletNode).MassFlowRate *
(Psychrometrics::PsyHFnTdbW(DataLoopNode::Node(OutletNode).Temp, DataLoopNode::Node(OutletNode).HumRat) -
Psychrometrics::PsyHFnTdbW(DataLoopNode::Node(InletNode).Temp, DataLoopNode::Node(OutletNode).HumRat));
FullLoadHumRatOut = DataLoopNode::Node(OutletNode).HumRat;

// Check to see if the system can meet the load with the compressor off
// If NoOutput is lower than (more cooling than required) or very near the ReqOutput, do not run the compressor
Expand Down Expand Up @@ -10909,6 +10912,7 @@ namespace UnitarySystems {
FullOutput = DataLoopNode::Node(InletNode).MassFlowRate *
(Psychrometrics::PsyHFnTdbW(DataLoopNode::Node(OutletNode).Temp, DataLoopNode::Node(InletNode).HumRat) -
Psychrometrics::PsyHFnTdbW(DataLoopNode::Node(InletNode).Temp, DataLoopNode::Node(InletNode).HumRat));
FullLoadHumRatOut = DataLoopNode::Node(OutletNode).HumRat;

// Since we are cooling, we expect FullOutput to be < 0 and FullOutput < NoCoolOutput
// Check that this is the case; IF not set PartLoadFrac = 0.0 (off) and return
Expand Down
7 changes: 7 additions & 0 deletions tst/EnergyPlus/unit/DXCoils.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@ TEST_F(EnergyPlusFixture, DXCoils_Test1)
DXCoilPartLoadRatio.allocate(1);
DXCoilFanOpMode.allocate(1);

DataLoopNode::Node.allocate(1);
DXCoil(CoilIndex).AirOutNode = 1;

Copy link
Contributor

Choose a reason for hiding this comment

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

Wow, previously no Node calls inside the Calc routine, I wouldn't have guessed that but I guess Init sets up node data variables and uses them in Calc. Wonder what the node data variable shows in the Calc routine. Oh well, unit test passes what it's intended to do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Other than the condenser inlet node, CalcDoe2DXCoil doesn't read or write to any nodes. It uses variables like DXCoil(DXCoilNum).InletAirTemp.

Real64 SpeedRatio = 0.0;
Real64 CycRatio = 1.0;
int SpeedNum = 2;
Expand Down Expand Up @@ -426,6 +429,8 @@ TEST_F(EnergyPlusFixture, TestMultiSpeedDefrostCOP)
Coil.DefrostStrategy = Resistive;
Coil.Name = "DX Heating coil";
Coil.NumOfSpeeds = 2;
DataLoopNode::Node.allocate(1);
Coil.AirOutNode = 1;

Coil.MSRatedTotCap.allocate(Coil.NumOfSpeeds);
Coil.MSRatedSHR.allocate(Coil.NumOfSpeeds);
Expand Down Expand Up @@ -796,6 +801,8 @@ TEST_F(EnergyPlusFixture, TestSingleSpeedDefrostCOP)
Coil.DXCoilType = "Coil:Heating:DX:SingleSpeed";
Coil.DXCoilType_Num = CoilDX_HeatingEmpirical;
Coil.SchedPtr = DataGlobals::ScheduleAlwaysOn;
DataLoopNode::Node.allocate(1);
Coil.AirOutNode = 1;

Coil.RatedSHR(1) = 1.0;
Coil.RatedTotCap(1) = 11012.634487601337;
Expand Down
96 changes: 96 additions & 0 deletions tst/EnergyPlus/unit/HVACControllers.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -680,4 +680,100 @@ TEST_F(EnergyPlusFixture, HVACControllers_CoilSystemCoolingWaterOnOutsideAirSyst
SimAirServingZones::CheckWaterCoilIsOnAirLoop(CoilTypeNum, CompType, CompName, WaterCoilOnAirLoop);
EXPECT_TRUE(WaterCoilOnAirLoop);
}
TEST_F(EnergyPlusFixture, HVACControllers_CheckTempAndHumRatCtrl)
{
HVACControllers::ControllerProps.allocate(1);
HVACControllers::RootFinders.allocate(1);
bool isConverged = true;
int const controlNum = 1;
auto &thisController(ControllerProps(1));
thisController.ControlVar = HVACControllers::iTemperatureAndHumidityRatio;
thisController.Offset = 0.0001;
int sensedNode = 1;
thisController.SensedNode = sensedNode;
DataLoopNode::Node.allocate(2);
DataLoopNode::Node(sensedNode).Temp = 21.2;
DataLoopNode::Node(sensedNode).HumRatMax = 0.001;
thisController.ActuatedNode = 2;
thisController.ActuatedNodePlantLoopBranchNum = 0;
thisController.ActuatedNodePlantLoopNum = 0;
thisController.ActuatedNodePlantLoopSide = 0;

// Case 1 - not converged yet, no override yet, return untouched
isConverged = false;
thisController.HumRatCtrlOverride = false;
thisController.SetPointValue = 21.1;
thisController.IsSetPointDefinedFlag = true;
thisController.NumCalcCalls = 5;
DataLoopNode::Node(sensedNode).HumRat = 0.0011;

HVACControllers::CheckTempAndHumRatCtrl(controlNum, isConverged);
EXPECT_FALSE(isConverged);
EXPECT_FALSE(thisController.HumRatCtrlOverride);
EXPECT_NEAR(thisController.SetPointValue, 21.1, 0.0001);
EXPECT_TRUE(thisController.IsSetPointDefinedFlag);
EXPECT_EQ(thisController.NumCalcCalls,5);

// Case 2 - converged, override true, return untouched
isConverged = true;
thisController.HumRatCtrlOverride = true;
thisController.SetPointValue = 21.1;
thisController.IsSetPointDefinedFlag = true;
thisController.NumCalcCalls = 5;
DataLoopNode::Node(sensedNode).HumRat = 0.0011;

HVACControllers::CheckTempAndHumRatCtrl(controlNum, isConverged);
EXPECT_TRUE(isConverged);
EXPECT_TRUE(thisController.HumRatCtrlOverride);
EXPECT_NEAR(thisController.SetPointValue, 21.1, 0.0001);
EXPECT_TRUE(thisController.IsSetPointDefinedFlag);
EXPECT_EQ(thisController.NumCalcCalls, 5);

// Case 3 - converged, override false, humrat<humratMax+Offset, return untouched
isConverged = true;
thisController.HumRatCtrlOverride = false;
thisController.SetPointValue = 21.1;
thisController.IsSetPointDefinedFlag = true;
thisController.NumCalcCalls = 5;
DataLoopNode::Node(sensedNode).HumRat = DataLoopNode::Node(sensedNode).HumRatMax - 0.001;

HVACControllers::CheckTempAndHumRatCtrl(controlNum, isConverged);
EXPECT_TRUE(isConverged);
EXPECT_FALSE(thisController.HumRatCtrlOverride);
EXPECT_NEAR(thisController.SetPointValue, 21.1, 0.0001);
EXPECT_TRUE(thisController.IsSetPointDefinedFlag);
EXPECT_EQ(thisController.NumCalcCalls, 5);

// Case 4 - converged, override false, humrat>humratMax+Offset, return with everything reset
isConverged = true;
thisController.HumRatCtrlOverride = false;
thisController.SetPointValue = 21.1;
thisController.IsSetPointDefinedFlag = true;
thisController.NumCalcCalls = 5;
DataLoopNode::Node(sensedNode).HumRat = DataLoopNode::Node(sensedNode).HumRatMax + 0.002;

HVACControllers::CheckTempAndHumRatCtrl(controlNum, isConverged);
EXPECT_FALSE(isConverged);
EXPECT_TRUE(thisController.HumRatCtrlOverride);
EXPECT_NEAR(thisController.SetPointValue, 0.0, 0.0001);
EXPECT_FALSE(thisController.IsSetPointDefinedFlag);
EXPECT_EQ(thisController.NumCalcCalls, 0);

// Case 5 - converged, override false, humrat>humratMax+Offset, temp only controller, return untouched
isConverged = true;
thisController.HumRatCtrlOverride = false;
thisController.SetPointValue = 21.1;
thisController.IsSetPointDefinedFlag = true;
thisController.NumCalcCalls = 5;
DataLoopNode::Node(sensedNode).HumRat = DataLoopNode::Node(sensedNode).HumRatMax - 0.001;
thisController.ControlVar = HVACControllers::iTemperature;

HVACControllers::CheckTempAndHumRatCtrl(controlNum, isConverged);
EXPECT_TRUE(isConverged);
EXPECT_FALSE(thisController.HumRatCtrlOverride);
EXPECT_NEAR(thisController.SetPointValue, 21.1, 0.0001);
EXPECT_TRUE(thisController.IsSetPointDefinedFlag);
EXPECT_EQ(thisController.NumCalcCalls, 5);

}
} // namespace EnergyPlus
Loading