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

PTAC hot water heating coil undersized for ventilation load #6079

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e7c1cca
Correct child component sizing
rraustad Mar 23, 2017
7ded76a
Merge branch 'develop' of https://github.com/NREL/EnergyPlus into #60…
rraustad Mar 23, 2017
fe0f88e
Add tentative method to save actual design data for reporting
rraustad Mar 23, 2017
84b035d
Revert attempt to align design sizing with child components
rraustad Mar 23, 2017
a8b658f
Merge branch 'develop' of https://github.com/NREL/EnergyPlus into #60…
rraustad Mar 23, 2017
a609699
Merge remote-tracking branch 'refs/remotes/origin/develop' into #6028…
EnergyArchmage Apr 21, 2017
7729a39
MicroCogeneration.idf, increase stratified tank volume
EnergyArchmage Apr 28, 2017
08e69b8
Merge remote-tracking branch 'remotes/origin/develop' into #6028-PTAC…
mjwitte May 25, 2017
8642695
Merge remote-tracking branch 'remotes/origin/develop' into #6028-PTAC…
mjwitte Jul 20, 2017
2e52533
Water coils sized on zone load + vent load
rraustad Jul 22, 2017
0428801
Zone load + Ventilation load is used to size water coils
rraustad Jul 23, 2017
1c17519
Include global heating sizing factor in ventilation calc and use Tzon…
rraustad Aug 3, 2017
02faf2d
Merge branch 'develop' of https://github.com/NREL/EnergyPlus into #60…
rraustad Aug 3, 2017
7c26f0d
Calculate mixed air temp for sizing zone water coils
rraustad Aug 5, 2017
be9e39f
Final changes
rraustad Aug 6, 2017
a7c38d0
Update unit test, correct coil inlet air temp calculation
rraustad Aug 6, 2017
e3b346e
Merge branch 'develop' of https://github.com/NREL/EnergyPlus into #60…
rraustad Aug 20, 2017
a00ab1a
Merge remote-tracking branch 'remotes/origin/develop' into #6028-PTAC…
mjwitte Aug 24, 2017
a6e1d7e
Update humrat calculation for water coil sizing in HeatingWaterDesCoi…
rraustad Aug 24, 2017
780ff25
Leave well enough alone
rraustad Aug 25, 2017
4a9fe52
Merge branch 'develop' of https://github.com/NREL/EnergyPlus into #60…
rraustad Aug 25, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/EnergyPlus/PackagedTerminalHeatPump.cc
Expand Up @@ -4186,6 +4186,15 @@ namespace PackagedTerminalHeatPump {
if ( CurZoneEqNum > 0 ) {
ZoneEqSizing( CurZoneEqNum ).OAVolFlow = max( PTUnit( PTUnitNum ).CoolOutAirVolFlow, PTUnit( PTUnitNum ).HeatOutAirVolFlow );
ZoneEqSizing( CurZoneEqNum ).AirVolFlow = max( PTUnit( PTUnitNum ).MaxCoolAirVolFlow, PTUnit( PTUnitNum ).MaxHeatAirVolFlow );
// save air flow rates for child object sizing
if( PTUnit( PTUnitNum ).MaxCoolAirVolFlow > 0.0 ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The bools SystemAirFlow, CoolingAirFlow, and HeatingAirFlow are true whenever the values are calculated, but what is really needed is to know which one needs to be used. So instead of a test like "PTUnit( PTUnitNum ).MaxCoolAirVolFlow > 0.0," I would look for conditions like "PTUnit( PTUnitNum ).MaxCoolAirVolFlow > PTUnit( PTUnitNum ).MaxHeatAirVolFlow." I just find it a bit confusing that both CoolingAirFlow and HeatingAirFlow can be true at the same time. just a minor comment since this is already the way it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The PTAC and PTHP have inputs for cooling, heating and OA flow rates. So this was set up to allow cooling and heating flow rates to be sized differently (e.g., scalable sizing).

ZoneEqSizing( CurZoneEqNum ).CoolingAirFlow = true;
ZoneEqSizing( CurZoneEqNum ).CoolingAirVolFlow = PTUnit( PTUnitNum ).MaxCoolAirVolFlow;
}
if( PTUnit( PTUnitNum ).MaxHeatAirVolFlow > 0.0 ) {
ZoneEqSizing( CurZoneEqNum ).HeatingAirFlow = true;
ZoneEqSizing( CurZoneEqNum ).HeatingAirVolFlow = PTUnit( PTUnitNum ).MaxHeatAirVolFlow;
}
}

if ( ErrorsFound ) {
Expand Down
34 changes: 28 additions & 6 deletions src/EnergyPlus/ReportSizingManager.cc
Expand Up @@ -584,8 +584,7 @@ namespace ReportSizingManager {
AutosizeDes = max( FinalZoneSizing( CurZoneEqNum ).DesCoolVolFlow, FinalZoneSizing( CurZoneEqNum ).DesHeatVolFlow );
}
}
}
}
}}
} else if ( SizingType == CoolingAirflowSizing || SizingType == HeatingAirflowSizing ) {
{ auto const SELECT_CASE_var( ZoneEqSizing( CurZoneEqNum ).SizingMethod( SizingType ) );
if ( ( SELECT_CASE_var == SupplyAirFlowRate ) || ( SELECT_CASE_var == None ) || ( SELECT_CASE_var == FlowPerFloorArea ) ) {
Expand Down Expand Up @@ -722,10 +721,16 @@ namespace ReportSizingManager {
} else if ( ZoneEqUnitHeater || ZoneEqVentedSlab ) { // for unit ventilator the cp value is calculated at 5.05(InitConvTemp) for the child and 60.0C for the unit ventilator //|| ZoneEqUnitVent
AutosizeDes = ZoneEqSizing( CurZoneEqNum ).MaxHWVolFlow;
} else {
if ( ZoneEqSizing( CurZoneEqNum ).SystemAirFlow ) {
DesMassFlow = ZoneEqSizing( CurZoneEqNum ).AirVolFlow * StdRhoAir;
} else if ( ZoneEqSizing( CurZoneEqNum ).HeatingAirFlow ) {
DesMassFlow = ZoneEqSizing( CurZoneEqNum ).HeatingAirVolFlow * StdRhoAir;
} else {
DesMassFlow = FinalZoneSizing( CurZoneEqNum ).DesHeatMassFlow;
}
CoilInTemp = FinalZoneSizing( CurZoneEqNum ).DesHeatCoilInTemp;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These new sections get the parent air flow rate and then calculate the OA fraction so a "revised" variable can be calculated based on the zone temp/humrat and OA temp/humrat.

CoilOutTemp = FinalZoneSizing( CurZoneEqNum ).HeatDesTemp;
CoilOutHumRat = FinalZoneSizing( CurZoneEqNum ).HeatDesHumRat;
DesMassFlow = FinalZoneSizing( CurZoneEqNum ).DesHeatMassFlow;
DesCoilLoad = PsyCpAirFnWTdb( CoilOutHumRat, 0.5 * ( CoilInTemp + CoilOutTemp ) ) * DesMassFlow * ( CoilOutTemp - CoilInTemp );
if ( DesCoilLoad >= SmallLoad ) {
Cp = GetSpecificHeatGlycol( PlantLoop( DataWaterLoopNum ).FluidName, DataGlobals::HWInitConvTemp, PlantLoop( DataWaterLoopNum ).FluidIndex, CallingRoutine );
Expand Down Expand Up @@ -1094,10 +1099,16 @@ namespace ReportSizingManager {
NominalCapacityDes = DesMassFlow * DataWaterCoilSizHeatDeltaT * Cp * rho;
// if coil is part of a zonal unit, calc coil load to get hot water flow rate
} else {
if ( ZoneEqSizing( CurZoneEqNum ).SystemAirFlow ) {
DesMassFlow = ZoneEqSizing( CurZoneEqNum ).AirVolFlow * StdRhoAir;
} else if ( ZoneEqSizing( CurZoneEqNum ).HeatingAirFlow ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The logic flow here seems a little suspect. I would expect an if - else-if block to be such that only one would be satisfied at a given time, but here both ZoneEqSizing( CurZoneEqNum ).SystemAirFlow and ZoneEqSizing( CurZoneEqNum ).HeatingAirFlow are often true at the same time, like it is in the unit test now. So it will flow to the if and skip the else-if even though it is also satisfied. That may be what you want but it seems hard to follow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I look at this as priority order when more than 1 is true.

DesMassFlow = ZoneEqSizing( CurZoneEqNum ).HeatingAirVolFlow * StdRhoAir;
} else {
DesMassFlow = FinalZoneSizing( CurZoneEqNum ).DesHeatMassFlow;
}
CoilInTemp = FinalZoneSizing( CurZoneEqNum ).DesHeatCoilInTemp;
CoilOutTemp = FinalZoneSizing( CurZoneEqNum ).HeatDesTemp;
CoilOutHumRat = FinalZoneSizing( CurZoneEqNum ).HeatDesHumRat;
DesMassFlow = FinalZoneSizing( CurZoneEqNum ).DesHeatMassFlow;
NominalCapacityDes = PsyCpAirFnWTdb( CoilOutHumRat, 0.5 * ( CoilInTemp + CoilOutTemp ) ) * DesMassFlow * ( CoilOutTemp - CoilInTemp );
}
AutosizeDes = NominalCapacityDes * DataHeatSizeRatio;
Expand All @@ -1123,7 +1134,13 @@ namespace ReportSizingManager {
rho = GetDensityGlycol( PlantLoop( DataWaterLoopNum ).FluidName, DataGlobals::CWInitConvTemp, PlantLoop( DataWaterLoopNum ).FluidIndex, CallingRoutine );
AutosizeDes = DataWaterFlowUsedForSizing * DataWaterCoilSizHeatDeltaT * Cp * rho;
} else {
DesMassFlow = FinalZoneSizing( CurZoneEqNum ).DesHeatMassFlow;
if ( ZoneEqSizing( CurZoneEqNum ).SystemAirFlow ) {
DesMassFlow = ZoneEqSizing( CurZoneEqNum ).AirVolFlow * StdRhoAir;
} else if ( ZoneEqSizing( CurZoneEqNum ).HeatingAirFlow ) {
DesMassFlow = ZoneEqSizing( CurZoneEqNum ).HeatingAirVolFlow * StdRhoAir;
} else {
DesMassFlow = FinalZoneSizing( CurZoneEqNum ).DesHeatMassFlow;
}
CoilInTemp = FinalZoneSizing( CurZoneEqNum ).DesHeatCoilInTemp;
CoilInHumRat = FinalZoneSizing( CurZoneEqNum ).DesHeatCoilInHumRat;
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't CoilInHumRat also need to be calculated as a combination of OA and Zone conditions?
Also, more general comment, not following why essentially the same code needs to be inserted in this function multiple times. This is the 4th or 5th place now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, don't we need similar changes for cooling coil sizing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't think that humrat would severely affect heating coil sizing, but yes, it should use the same method (and I was just trying the get this to work and ran out of steam). These changes evolved to a point where I think now I understand why the sizing data (T and w) isn't applicable when a zone coil is used in a parent object operating at a higher flow rate. So I think this type of change would be pervasive throughout sizing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same code 4 or 5 times... anytime coil inlet T needs to be calculated, the new method should be used.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just seems like that could all happen in one block of code. It's fine for now, but at some future point, this could possibly be refactored to consolidate similar calcs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

CoilInHumRat only needed to be changed 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.

  • CoolingWaterDesAirInletTempSizing already uses this method for ZoneEqFanCoil except it needs to use the parent flow rate if applicable and the else needs to be fixed.
  • CoolingWaterDesAirInletHumRatSizing already uses this method for ZoneEqFanCoil except it needs to use the parent flow rate if applicable and the else needs to be fixed.
  • CoolingCapacitySizing needs these changes

I think that's it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It looks like there's a place in HeatingCapacitySizing (non-water coils) that could use this change, but without a defect file I'm scared to change it. I'm going to add a warning there to see if any example files use that line of code.

CoilOutTemp = FinalZoneSizing( CurZoneEqNum ).HeatDesTemp;
Expand All @@ -1144,6 +1161,10 @@ namespace ReportSizingManager {
AutosizeDes = StdRhoAir * TermUnitSizing( CurZoneEqNum ).AirVolFlow * TermUnitSizing( CurZoneEqNum ).ReheatAirFlowMult;
} else if ( ZoneEqFanCoil ) {
AutosizeDes = StdRhoAir * FinalZoneSizing( CurZoneEqNum ).DesHeatVolFlow;
} else if ( ZoneEqSizing( CurZoneEqNum ).SystemAirFlow ) {
AutosizeDes = ZoneEqSizing( CurZoneEqNum ).AirVolFlow * StdRhoAir;
} else if ( ZoneEqSizing( CurZoneEqNum ).HeatingAirFlow ) {
AutosizeDes = ZoneEqSizing( CurZoneEqNum ).HeatingAirVolFlow * StdRhoAir;
} else {
AutosizeDes = FinalZoneSizing( CurZoneEqNum ).DesHeatMassFlow;
}
Expand Down Expand Up @@ -2138,6 +2159,7 @@ namespace ReportSizingManager {
} else {
AutosizeUser = SizingResult;
}

if ( DataScalableSizingON ) {
if ( SizingType == CoolingAirflowSizing || SizingType == HeatingAirflowSizing || SizingType == SystemAirflowSizing ) {
{ auto const SELECT_CASE_var( ZoneEqSizing( CurZoneEqNum ).SizingMethod( SizingType ) );
Expand All @@ -2159,7 +2181,7 @@ namespace ReportSizingManager {
{ auto const SELECT_CASE_var( ZoneEqSizing( CurZoneEqNum ).SizingMethod( SizingType ) );
if ( SELECT_CASE_var == HeatingDesignCapacity || SELECT_CASE_var == CoolingDesignCapacity ) {
ScalableSM = "User-Specified ";
if ( SizingResult == AutoSize ) ScalableSM = "Design Size ";
if ( SizingResult == AutoSize ) ScalableSM = "Design Size "; // how can the SizingResult == AutoSize here ?? It's set a few lines up.
} else if ( SELECT_CASE_var == CapacityPerFloorArea ) {
ScalableSM = "User-Specified (scaled by capacity / area) ";
} else if ( SELECT_CASE_var == FractionOfAutosizedHeatingCapacity || SELECT_CASE_var == FractionOfAutosizedCoolingCapacity ) {
Expand Down
14 changes: 12 additions & 2 deletions tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc
Expand Up @@ -66,6 +66,7 @@ using namespace EnergyPlus;
using namespace EnergyPlus::DataEnvironment;
using namespace EnergyPlus::DataPlant;
using namespace EnergyPlus::DataZoneEquipment;
using namespace EnergyPlus::DataSizing;
using namespace EnergyPlus::Fans;
using namespace EnergyPlus::HeatBalanceManager;
using namespace EnergyPlus::PackagedTerminalHeatPump;
Expand Down Expand Up @@ -456,7 +457,7 @@ namespace EnergyPlus {

// This VS coil is rather quirky. It sizes the capacity based on zone sizing air flow rate.
// Then uses that capacity to back calculate the air flow needed to keep the reference air flow per capacity ratio constant.
// For this reason, the parent object would size to an air flow that was different than the chile.
// For this reason, the parent object would size to an air flow that was different than the child.

// identify coil
EXPECT_EQ ( VariableSpeedCoils::VarSpeedCoil( 1 ).Name, "LOBBY_ZN_1_FLR_2 WSHP COOLING MODE" );
Expand All @@ -465,7 +466,7 @@ namespace EnergyPlus {
EXPECT_EQ( VariableSpeedCoils::VarSpeedCoil( 1 ).RatedAirVolFlowRate, PTUnit( 1 ).MaxCoolAirVolFlow );
EXPECT_EQ( VariableSpeedCoils::VarSpeedCoil( 1 ).MSRatedAirVolFlowRate( 9 ), PTUnit( 1 ).MaxCoolAirVolFlow );

// expect the ratio of air flow to capacity to equal to the reference air flow and capacity specified in coil input
// expect the ratio of air flow to capacity to be equal to the reference air flow and capacity ratio specified in coil input
Real64 refAirflowCapacityRatio = 0.891980668 / 16092.825525; // speed 9 reference cooling data
Real64 sizingAirflowCapacityRatio = VariableSpeedCoils::VarSpeedCoil( 1 ).MSRatedAirVolFlowRate( 9 ) / VariableSpeedCoils::VarSpeedCoil( 1 ).MSRatedTotCap( 9 );
EXPECT_EQ( refAirflowCapacityRatio, sizingAirflowCapacityRatio );
Expand Down Expand Up @@ -493,5 +494,14 @@ namespace EnergyPlus {
EXPECT_EQ( Fan( 1 ).MaxAirFlowRate, max( VariableSpeedCoils::VarSpeedCoil( 1 ).RatedAirVolFlowRate, VariableSpeedCoils::VarSpeedCoil( 2 ).RatedAirVolFlowRate ) );
EXPECT_EQ( Fan( 1 ).MaxAirFlowRate, max( PTUnit( 1 ).MaxCoolAirVolFlow, PTUnit( 1 ).MaxHeatAirVolFlow ) );

// #6028 child components not sizing correctly on air flow rate
// VS coils set SystemAirFlow to true and AirVolFlow to a value, all PTUnits set CoolingAirFlow and HeatingAirFlow, and CoolingAirVolFlow and HeatingAirVolFlow
EXPECT_TRUE( ZoneEqSizing( 1 ).SystemAirFlow );
EXPECT_TRUE( ZoneEqSizing( 1 ).CoolingAirFlow );
EXPECT_TRUE( ZoneEqSizing( 1 ).HeatingAirFlow );
EXPECT_EQ( ZoneEqSizing( 1 ).CoolingAirVolFlow, PTUnit( 1 ).MaxCoolAirVolFlow );
EXPECT_EQ( ZoneEqSizing( 1 ).HeatingAirVolFlow, PTUnit( 1 ).MaxHeatAirVolFlow );
EXPECT_EQ( Fan( 1 ).MaxAirFlowRate, ZoneEqSizing( 1 ).AirVolFlow );
EXPECT_EQ( Fan( 1 ).MaxAirFlowRate, max( ZoneEqSizing( 1 ).CoolingAirVolFlow, ZoneEqSizing( 1 ).HeatingAirVolFlow ) );
}
}