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

Implementation of On-Off Control Capabilities for the Variable Flow and Electric Low Temperature Radiant Systems #8113

Merged
merged 6 commits into from
Jul 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions idd/Energy+.idd.in
Original file line number Diff line number Diff line change
Expand Up @@ -44069,7 +44069,7 @@ ZoneHVAC:LowTemperatureRadiant:VariableFlow,
\type node
N7 , \field Heating Control Throttling Range
\units deltaC
\minimum 0.5
\minimum 0
Copy link
Member

Choose a reason for hiding this comment

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

Makes sense, users can now have zero range to give on/off control.

\default 0.5
A9 , \field Heating Control Temperature Schedule Name
\type object-list
Expand Down Expand Up @@ -44117,7 +44117,7 @@ ZoneHVAC:LowTemperatureRadiant:VariableFlow,
\type node
N12, \field Cooling Control Throttling Range
\units deltaC
\minimum 0.5
\minimum 0
\default 0.5
A13, \field Cooling Control Temperature Schedule Name
\type object-list
Expand Down
36 changes: 16 additions & 20 deletions src/EnergyPlus/LowTempRadiantSystem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@ namespace LowTempRadiantSystem {
using namespace DataSurfaceLists;

// SUBROUTINE PARAMETER DEFINITIONS:
Real64 const MinThrottlingRange(0.5); // Smallest throttling range allowed in degrees Celsius
static std::string const RoutineName("GetLowTempRadiantSystem: "); // include trailing blank space
static std::string const Off("Off");
static std::string const SimpleOff("SimpleOff");
Expand Down Expand Up @@ -664,11 +663,6 @@ namespace LowTempRadiantSystem {
}

thisRadSys.HotThrottlRange = Numbers(7);
if (thisRadSys.HotThrottlRange < MinThrottlingRange) {
ShowWarningError("ZoneHVAC:LowTemperatureRadiant:VariableFlow: Heating throttling range too small, reset to 0.5");
ShowContinueError("Occurs in Radiant System=" + thisRadSys.Name);
thisRadSys.HotThrottlRange = MinThrottlingRange;
}
Copy link
Member

Choose a reason for hiding this comment

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

Yay gone!


thisRadSys.HotSetptSched = Alphas(9);
thisRadSys.HotSetptSchedPtr = GetScheduleIndex(Alphas(9));
Expand Down Expand Up @@ -760,11 +754,6 @@ namespace LowTempRadiantSystem {
}

thisRadSys.ColdThrottlRange = Numbers(12);
if (thisRadSys.ColdThrottlRange < MinThrottlingRange) {
ShowWarningError("ZoneHVAC:LowTemperatureRadiant:VariableFlow: Cooling throttling range too small, reset to 0.5");
ShowContinueError("Occurs in Radiant System=" + thisRadSys.Name);
thisRadSys.ColdThrottlRange = MinThrottlingRange;
}

thisRadSys.ColdSetptSched = Alphas(13);
thisRadSys.ColdSetptSchedPtr = GetScheduleIndex(Alphas(13));
Expand Down Expand Up @@ -1225,11 +1214,6 @@ namespace LowTempRadiantSystem {
thisElecSys.ControlType = thisElecSys.processRadiantSystemControlInput(Alphas(6),cAlphaFields(6));

thisElecSys.ThrottlRange = Numbers(4);
if (thisElecSys.ThrottlRange < MinThrottlingRange) {
ShowWarningError(cNumericFields(4) + " out of range, reset to 0.5");
ShowContinueError("Occurs in " + CurrentModuleObject + " = " + Alphas(1));
thisElecSys.ThrottlRange = MinThrottlingRange;
}

thisElecSys.SetptSched = Alphas(7);
thisElecSys.SetptSchedPtr = GetScheduleIndex(Alphas(7));
Expand Down Expand Up @@ -3107,12 +3091,12 @@ namespace LowTempRadiantSystem {
OperatingMode = HeatingMode;
ControlNode = this->HotWaterInNode;
MaxWaterFlow = this->WaterFlowMaxHeat;
MassFlowFrac = (OffTempHeat - ControlTemp) / this->HotThrottlRange;
MassFlowFrac = this->calculateOperationalFraction(OffTempHeat, ControlTemp, this->HotThrottlRange);
} else if (ControlTemp > OffTempCool && this->CoolingSystem) { // Cooling mode
OperatingMode = CoolingMode;
ControlNode = this->ColdWaterInNode;
MaxWaterFlow = this->WaterFlowMaxCool;
MassFlowFrac = (ControlTemp - OffTempCool) / this->ColdThrottlRange;
MassFlowFrac = this->calculateOperationalFraction(OffTempCool, ControlTemp, this->ColdThrottlRange);
} else { // ControlTemp is between OffTempHeat and OffTempCool--unit should not run
MassFlowFrac = 0.0;
}
Expand Down Expand Up @@ -4771,8 +4755,7 @@ namespace LowTempRadiantSystem {

OperatingMode = HeatingMode;

HeatFrac = (OffTemp - ControlTemp) / this->ThrottlRange;
if (HeatFrac < 0.0) HeatFrac = 0.0;
HeatFrac = this->calculateOperationalFraction(OffTemp, ControlTemp, this->ThrottlRange);
Copy link
Member

Choose a reason for hiding this comment

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

Code reuse! w00t!

if (HeatFrac > 1.0) HeatFrac = 1.0;

// Set the heat source for the low temperature electric radiant system
Expand Down Expand Up @@ -5087,6 +5070,19 @@ namespace LowTempRadiantSystem {
}
}

Real64 RadiantSystemBaseData::calculateOperationalFraction(Real64 const offTemperature, Real64 const controlTemperature, Real64 const throttlingRange)
Copy link
Member

Choose a reason for hiding this comment

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

Hooray for a base class method!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's just say I had a great teacher! I was definitely following examples from the previous radiant work. Glad to be doing things in a way that heads E+ in the right direction.

{
Real64 temperatureDifference = std::abs(offTemperature - controlTemperature);
if (temperatureDifference <= 0.0) {
return 0.0; // No temperature difference--turn things off (set to zero); technically shouldn't happen
} else if (throttlingRange < 0.001) {
return 1.0; // Throttling range is essentially zero and there is a temperature difference--turn it full on
} else {
return temperatureDifference/throttlingRange; // Temperature difference is non-zero and less than the throttling range--calculate the operation fraction
Copy link
Member

Choose a reason for hiding this comment

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

There should be a space before and after the division operator.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will fix this when we resolve the minimum throttling range issue.

}
}


Real64 HydronicSystemBaseData::calculateHXEffectivenessTerm(Real64 const Temperature, // Temperature of water entering the radiant system, in C
Real64 const WaterMassFlow, // Mass flow rate of water in the radiant system, in kg/s
Real64 const FlowFraction, // Mass flow rate fraction for this surface in the radiant system
Expand Down
6 changes: 4 additions & 2 deletions src/EnergyPlus/LowTempRadiantSystem.hh
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,11 @@ namespace LowTempRadiantSystem {
);

Real64 setRadiantSystemControlTemperature();


Real64 calculateOperationalFraction(Real64 const offTemperature, Real64 const controlTemperature, Real64 const throttlingRange);

virtual void calculateLowTemperatureRadiantSystem(ZoneTempPredictorCorrectorData &dataZoneTempPredictorCorrector, Real64 &LoadMet) = 0;

Copy link
Member

Choose a reason for hiding this comment

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

Your editor left some trailing white space on this line, no worries for now, but I'd check to see if you can tell it to remove them upon saving the file.

void updateLowTemperatureRadiantSystemSurfaces();

virtual void updateLowTemperatureRadiantSystem() = 0;
Expand Down
2 changes: 1 addition & 1 deletion testfiles/RadLoTempElecCtrlOpt2.idf
Original file line number Diff line number Diff line change
Expand Up @@ -2216,7 +2216,7 @@
, !- Heating Design Capacity Per Floor Area {W/m2}
1.9637972000759794, !- Fraction of Autosized Heating Design Capacity
SurfaceInteriorTemperature, !- Temperature Control Type
2.0, !- Heating Throttling Range {deltaC}
0.0, !- Heating Throttling Range {deltaC}
Radiant Heating Setpoints 3; !- Heating Setpoint Temperature Schedule Name

AirLoopHVAC:ZoneSplitter,
Expand Down
8 changes: 4 additions & 4 deletions testfiles/RadLoTempHydrHeatCool.idf
Original file line number Diff line number Diff line change
Expand Up @@ -2097,7 +2097,7 @@
0.00008, !- Maximum Hot Water Flow {m3/s}
East Zone Radiant Water Inlet Node, !- Heating Water Inlet Node Name
East Zone Radiant Water Outlet Node, !- Heating Water Outlet Node Name
2.0, !- Heating Control Throttling Range {deltaC}
0.4, !- Heating Control Throttling Range {deltaC}
Radiant Heating Setpoints, !- Heating Control Temperature Schedule Name
CoolingDesignCapacity, !- Cooling Design Capacity Method
Autosize, !- Cooling Design Capacity {W}
Expand All @@ -2106,7 +2106,7 @@
0.0012, !- Maximum Cold Water Flow {m3/s}
Zone 2 Cooling Water Inlet Node, !- Cooling Water Inlet Node Name
Zone 2 Cooling Water Outlet Node, !- Cooling Water Outlet Node Name
2.0, !- Cooling Control Throttling Range {deltaC}
0.4, !- Cooling Control Throttling Range {deltaC}
Radiant Cooling Setpoints, !- Cooling Control Temperature Schedule Name
VariableOff, !- Condensation Control Type
0.0, !- Condensation Control Dewpoint Offset {C}
Expand All @@ -2128,7 +2128,7 @@
0.00010, !- Maximum Hot Water Flow {m3/s}
North Zone Radiant Water Inlet Node, !- Heating Water Inlet Node Name
North Zone Radiant Water Outlet Node, !- Heating Water Outlet Node Name
2.0, !- Heating Control Throttling Range {deltaC}
0.0, !- Heating Control Throttling Range {deltaC}
Radiant Heating Setpoints, !- Heating Control Temperature Schedule Name
CoolingDesignCapacity, !- Cooling Design Capacity Method
Autosize, !- Cooling Design Capacity {W}
Expand All @@ -2137,7 +2137,7 @@
0.0015, !- Maximum Cold Water Flow {m3/s}
Zone 3 Cooling Water Inlet Node, !- Cooling Water Inlet Node Name
Zone 3 Cooling Water Outlet Node, !- Cooling Water Outlet Node Name
2.0, !- Cooling Control Throttling Range {deltaC}
0.0, !- Cooling Control Throttling Range {deltaC}
Radiant Cooling Setpoints, !- Cooling Control Temperature Schedule Name
Off, !- Condensation Control Type
0.0, !- Condensation Control Dewpoint Offset {C}
Expand Down
69 changes: 69 additions & 0 deletions tst/EnergyPlus/unit/LowTempRadiantSystem.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2132,3 +2132,72 @@ TEST_F(LowTempRadiantSystemTest, setRadiantSystemControlTemperatureTest)
EXPECT_NEAR(expectedResult, actualResult, acceptibleError);

}

TEST_F(LowTempRadiantSystemTest, calculateOperationalFractionTest)
{
Real64 offTemperature;
Real64 controlTemperature;
Real64 throttlingRange;
Real64 functionResult;
Real64 expectedResult;

HydrRadSys.allocate(1);
auto &thisRadSys (HydrRadSys(1));

// Test 1: Temperature Difference is 0-->answer should be 0.0
offTemperature = 15.0;
controlTemperature = 15.0;
throttlingRange = 1.0;
expectedResult = 0.0;
functionResult = thisRadSys.calculateOperationalFraction(offTemperature, controlTemperature, throttlingRange);
EXPECT_NEAR(expectedResult, functionResult, 0.001);

// Test 2a: Temperature Difference is not zero and positive, throttling range is zero-->answer should be 1.0
offTemperature = 16.0;
controlTemperature = 15.0;
throttlingRange = 0.0;
expectedResult = 1.0;
functionResult = thisRadSys.calculateOperationalFraction(offTemperature, controlTemperature, throttlingRange);
EXPECT_NEAR(expectedResult, functionResult, 0.001);

// Test 2b: Temperature Difference is not zero and negtive, throttling range is zero-->answer should be 1.0
offTemperature = 14.0;
controlTemperature = 15.0;
throttlingRange = 0.0;
expectedResult = 1.0;
functionResult = thisRadSys.calculateOperationalFraction(offTemperature, controlTemperature, throttlingRange);
EXPECT_NEAR(expectedResult, functionResult, 0.001);

// Test 3a: Temperature Difference is not zero and positive, throttling range is non-zero but less than temperature difference
offTemperature = 16.0;
controlTemperature = 15.0;
throttlingRange = 0.5;
expectedResult = 2.0;
functionResult = thisRadSys.calculateOperationalFraction(offTemperature, controlTemperature, throttlingRange);
EXPECT_NEAR(expectedResult, functionResult, 0.001);

// Test 3b: Temperature Difference is not zero and negative, throttling range is non-zero but less than temperature difference
offTemperature = 16.0;
controlTemperature = 15.0;
throttlingRange = 0.5;
expectedResult = 2.0;
functionResult = thisRadSys.calculateOperationalFraction(offTemperature, controlTemperature, throttlingRange);
EXPECT_NEAR(expectedResult, functionResult, 0.001);

// Test 4a: Temperature Difference is not zero and positive, throttling range is non-zero but greater than temperature difference
offTemperature = 16.0;
controlTemperature = 15.0;
throttlingRange = 2.0;
expectedResult = 0.5;
functionResult = thisRadSys.calculateOperationalFraction(offTemperature, controlTemperature, throttlingRange);
EXPECT_NEAR(expectedResult, functionResult, 0.001);

// Test 4b: Temperature Difference is not zero and negative, throttling range is non-zero but greater than temperature difference
offTemperature = 14.0;
controlTemperature = 15.0;
throttlingRange = 2.0;
expectedResult = 0.5;
functionResult = thisRadSys.calculateOperationalFraction(offTemperature, controlTemperature, throttlingRange);
EXPECT_NEAR(expectedResult, functionResult, 0.001);

}