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

Variable speed coils can have higher flow rate than Packaged Terminal unit and fan #5723

Merged
merged 17 commits into from
Aug 18, 2017
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
42 changes: 41 additions & 1 deletion src/EnergyPlus/HVACManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
//#include <CoolTower.hh>
#include <DataAirflowNetwork.hh>
#include <DataAirLoop.hh>
#include <DataBranchAirLoopPlant.hh>
#include <DataContaminantBalance.hh>
#include <DataConvergParams.hh>
#include <DataEnvironment.hh>
Expand All @@ -92,6 +93,7 @@
#include <DisplayRoutines.hh>
//#include <EarthTube.hh>
#include <EMSManager.hh>
#include <Fans.hh>
#include <General.hh>
#include <HVACStandAloneERV.hh>
#include <IceThermalStorage.hh>
Expand All @@ -106,6 +108,7 @@
#include <PlantUtilities.hh>
#include <PollutionModule.hh>
#include <Psychrometrics.hh>
#include <Pumps.hh>
#include <RefrigeratedCase.hh>
#include <ScheduleManager.hh>
#include <SetPointManager.hh>
Expand Down Expand Up @@ -515,6 +518,8 @@ namespace HVACManager {

ManageEMS( emsCallFromEndSystemTimestepBeforeHVACReporting, anyEMSRan ); // EMS calling point

CheckMassBalances();
Copy link
Contributor

Choose a reason for hiding this comment

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

So this is staying?

Copy link
Member Author

Choose a reason for hiding this comment

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

It shouldn't add any significant time to the simulation, and we should always be checking for mass conservation problems. There bay be a better time to check these. Ideas?


// This is where output processor data is updated for System Timestep reporting
if ( ! WarmupFlag ) {
if ( DoOutputReporting ) {
Expand Down Expand Up @@ -855,7 +860,7 @@ namespace HVACManager {
++HVACManageIteration; // Increment the iteration counter

if ( anyEMSRan && HVACManageIteration <= 2 ) {
// the calling point emsCallFromHVACIterationLoop is only effective for air loops if this while loop runs at least twice
// the calling point emsCallFromHVACIterationLoop is only effective for air loops if this while loop runs at least twice
SimAirLoopsFlag = true;
}

Expand Down Expand Up @@ -2725,6 +2730,41 @@ namespace HVACManager {

}

void
CheckMassBalances()
{
using namespace Fans;
using namespace Pumps;
using General::RoundSigDigits;
using DataHVACGlobals::SmallMassFlow; // Air
using DataBranchAirLoopPlant::MassFlowTolerance; // Liquid

for (int FanNum = 1; FanNum <= NumFans; ++FanNum) {

if (abs(Node( Fan( FanNum ).InletNodeNum ).MassFlowRate - Fan( FanNum ).InletAirMassFlowRate) > SmallMassFlow) {
ShowFatalError(Fan(FanNum).FanType + ", Name: " + Fan(FanNum).FanName + ": Fan inlet mass flow rate (" + RoundSigDigits(Fan( FanNum ).InletAirMassFlowRate, 4) + ") does not match inlet node mass flow rate (" + RoundSigDigits(Node( Fan( FanNum ).InletNodeNum ).MassFlowRate, 4) + ").");
}

if (abs(Node( Fan( FanNum ).OutletNodeNum ).MassFlowRate - Fan( FanNum ).OutletAirMassFlowRate) > SmallMassFlow) {
ShowFatalError(Fan(FanNum).FanType + ", Name: " + Fan(FanNum).FanName + ": Fan outlet mass flow rate (" + RoundSigDigits(Fan( FanNum ).OutletAirMassFlowRate, 4) + ") does not match outlet node mass flow rate (" + RoundSigDigits(Node( Fan( FanNum ).OutletNodeNum ).MassFlowRate, 4) + ").");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I see no need for these. Either outlet = inlet or it doesn't.


if (abs(Node( Fan( FanNum ).InletNodeNum ).MassFlowRate - Node( Fan( FanNum ).OutletNodeNum ).MassFlowRate) > SmallMassFlow) {
ShowFatalError(Fan(FanNum).FanType + ", Name: " + Fan(FanNum).FanName + ": Fan outlet mass flow rate (" + RoundSigDigits(Node( Fan( FanNum ).OutletNodeNum ).MassFlowRate, 4) + ") does not match fan inlet node mass flow rate (" + RoundSigDigits(Node( Fan( FanNum ).InletNodeNum ).MassFlowRate, 4) + ").");
}

}

for (int PumpNum = 1; PumpNum <= NumPumps; ++PumpNum) {
if (abs(Node( PumpEquip( PumpNum ).OutletNodeNum ).MassFlowRate - Node( PumpEquip( PumpNum ).InletNodeNum ).MassFlowRate) > MassFlowTolerance) {
ShowFatalError(cPumpTypes(PumpEquip( PumpNum ).PumpType) + ", Name: " + PumpEquip( PumpNum ).Name + ": Pump outlet mass flow rate (" + RoundSigDigits(Node( PumpEquip( PumpNum ).OutletNodeNum ).MassFlowRate, 9) + ") does not match pump inlet node mass flow rate (" + RoundSigDigits(Node( PumpEquip( PumpNum ).InletNodeNum ).MassFlowRate, 9) + ").");
}
}


}


} // HVACManager

} // EnergyPlus
3 changes: 3 additions & 0 deletions src/EnergyPlus/HVACManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ namespace HVACManager {
void
SimHVAC();

void
CheckMassBalances();

void
SimSelectedEquipment(
bool & SimAirLoops, // True when the air loops need to be (re)simulated
Expand Down
19 changes: 9 additions & 10 deletions src/EnergyPlus/PackagedTerminalHeatPump.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2851,7 +2851,6 @@ namespace PackagedTerminalHeatPump {
int i; // Loop index
int Iter; // speed iteration count
int PTObjectIndex;
Real64 MulSpeedFlowScale; // variable speed air flow scaling factor
int CtrlZoneNum; // the controlled zone index (index of ZoneEquipConfig)

InNode = PTUnit( PTUnitNum ).AirInNode;
Expand Down Expand Up @@ -2980,16 +2979,19 @@ namespace PackagedTerminalHeatPump {
MySizeFlag( PTUnitNum ) = false;
}

RhoAir = StdRhoAir;
Copy link
Member Author

Choose a reason for hiding this comment

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

@rraustad I also noticed that the mass flow rate through this object uses standard air assumptions. It does not use psychrometric functions on the timestep basis to determine the density of air. This doesn't seem quite right to me. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Standard practice to use StdRhoAir to initialize mass flow rate.

Copy link
Member Author

Choose a reason for hiding this comment

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

@rraustad It looks like the initial mass flow rates for each speed (calculated at StdRhoAir) are calculated once and used in each timestep regardless of the actual psychrometric state of the air in the simulation. Or is there a correction happening elsewhere?

Copy link
Contributor

Choose a reason for hiding this comment

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

@nealkruis Correct on the standard mass flow rates, no adjustments.. That's the current method for all fans/flows as I understand it.

PTUnit( PTUnitNum ).MaxCoolAirMassFlow = RhoAir * PTUnit( PTUnitNum ).MaxCoolAirVolFlow;
PTUnit( PTUnitNum ).MaxHeatAirMassFlow = RhoAir * PTUnit( PTUnitNum ).MaxHeatAirVolFlow;

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand these new lines without being deleted somewhere else. I'll have to pull the branch to inspect further.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see these new lines. I see these at line 3173 and 3175, I think where they've always been. What's going on here?

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, now I see why this if needed. The problem I see is I only want to execute these lines once. So I am moving this all up into the sizing IF above. It also makes me wonder why we initialize Mdot again on next begin environment. We've always done that, but I don't know why.

if ( PTUnit( PTUnitNum ).useVSCoilModel && PTUnit( PTUnitNum ).NumOfSpeedCooling == 0 && ! MySizeFlag( PTUnitNum ) ) {

SimVariableSpeedCoils( "", PTUnit( PTUnitNum ).DXCoolCoilIndexNum, 0, PTUnit( PTUnitNum ).MaxONOFFCyclesperHour, PTUnit( PTUnitNum ).HPTimeConstant, PTUnit( PTUnitNum ).FanDelayTime, 0, 0.0, 1, 0.0, 0.0, 0.0, 0.0 ); //conduct the sizing operation in the VS WSHP
Copy link
Contributor

@rraustad rraustad Jul 18, 2016

Choose a reason for hiding this comment

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

This ratio was originally used to scale the rated air flow rate to the "nominal" design air flow rate using VarSpeedCoil.NormSpedLevel . This ratio has been removed below and I don't think this is correct now (assumes nominal speed is always equal to max speed). From the IO Ref:

1.40.33.1.7 Field: Nominal Speed Level
This numeric field defines the nominal speed level, at which the rated capacity, rated air and
water volumetric flow rates are correlated.

PTUnit( PTUnitNum ).NumOfSpeedCooling = VarSpeedCoil( PTUnit( PTUnitNum ).DXCoolCoilIndexNum ).NumOfSpeeds;

MulSpeedFlowScale = VarSpeedCoil( PTUnit( PTUnitNum ).DXCoolCoilIndexNum ).RatedAirVolFlowRate / VarSpeedCoil( PTUnit( PTUnitNum ).DXCoolCoilIndexNum ).MSRatedAirVolFlowRate( VarSpeedCoil( PTUnit( PTUnitNum ).DXCoolCoilIndexNum ).NormSpedLevel );
for ( Iter = 1; Iter <= PTUnit( PTUnitNum ).NumOfSpeedCooling; ++Iter ) {
PTUnit( PTUnitNum ).CoolVolumeFlowRate( Iter ) = VarSpeedCoil( PTUnit( PTUnitNum ).DXCoolCoilIndexNum ).MSRatedAirVolFlowRate( Iter ) * MulSpeedFlowScale;
PTUnit( PTUnitNum ).CoolMassFlowRate( Iter ) = VarSpeedCoil( PTUnit( PTUnitNum ).DXCoolCoilIndexNum ).MSRatedAirMassFlowRate( Iter ) * MulSpeedFlowScale;
PTUnit( PTUnitNum ).MSCoolingSpeedRatio( Iter ) = VarSpeedCoil( PTUnit( PTUnitNum ).DXCoolCoilIndexNum ).MSRatedAirVolFlowRate( Iter ) / VarSpeedCoil( PTUnit( PTUnitNum ).DXCoolCoilIndexNum ).MSRatedAirVolFlowRate( PTUnit( PTUnitNum ).NumOfSpeedCooling );
PTUnit( PTUnitNum ).CoolVolumeFlowRate( Iter ) = PTUnit( PTUnitNum ).MaxCoolAirVolFlow * PTUnit( PTUnitNum ).MSCoolingSpeedRatio( Iter );
Copy link
Member Author

Choose a reason for hiding this comment

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

@rraustad this is the change I ended up making. I believe this is in line with the changes you had in mind, but you might want to look them over to be sure.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is what I was thinking, but it does scare me a bit. Off design flow rates only work up to a point.

PTUnit( PTUnitNum ).CoolMassFlowRate( Iter ) = PTUnit( PTUnitNum ).MaxCoolAirMassFlow * PTUnit( PTUnitNum ).MSCoolingSpeedRatio( Iter );
}

if ( PTUnit( PTUnitNum ).DXHeatCoilType_Num == Coil_HeatingWaterToAirHPVSEquationFit || PTUnit( PTUnitNum ).DXHeatCoilType_Num == Coil_HeatingAirToAirVariableSpeed ) {
Expand All @@ -2998,11 +3000,10 @@ namespace PackagedTerminalHeatPump {

PTUnit( PTUnitNum ).NumOfSpeedHeating = VarSpeedCoil( PTUnit( PTUnitNum ).DXHeatCoilIndex ).NumOfSpeeds;

MulSpeedFlowScale = VarSpeedCoil( PTUnit( PTUnitNum ).DXHeatCoilIndex ).RatedAirVolFlowRate / VarSpeedCoil( PTUnit( PTUnitNum ).DXHeatCoilIndex ).MSRatedAirVolFlowRate( VarSpeedCoil( PTUnit( PTUnitNum ).DXHeatCoilIndex ).NormSpedLevel );
for ( Iter = 1; Iter <= PTUnit( PTUnitNum ).NumOfSpeedHeating; ++Iter ) {
PTUnit( PTUnitNum ).HeatVolumeFlowRate( Iter ) = VarSpeedCoil( PTUnit( PTUnitNum ).DXHeatCoilIndex ).MSRatedAirVolFlowRate( Iter ) * MulSpeedFlowScale;
PTUnit( PTUnitNum ).HeatMassFlowRate( Iter ) = VarSpeedCoil( PTUnit( PTUnitNum ).DXHeatCoilIndex ).MSRatedAirMassFlowRate( Iter ) * MulSpeedFlowScale;
PTUnit( PTUnitNum ).MSHeatingSpeedRatio( Iter ) = VarSpeedCoil( PTUnit( PTUnitNum ).DXHeatCoilIndex ).MSRatedAirVolFlowRate( Iter ) / VarSpeedCoil( PTUnit( PTUnitNum ).DXHeatCoilIndex ).MSRatedAirVolFlowRate( PTUnit( PTUnitNum ).NumOfSpeedHeating );
PTUnit( PTUnitNum ).HeatVolumeFlowRate( Iter ) = PTUnit( PTUnitNum ).MaxHeatAirVolFlow * PTUnit( PTUnitNum ).MSHeatingSpeedRatio( Iter );
PTUnit( PTUnitNum ).HeatMassFlowRate( Iter ) = PTUnit( PTUnitNum ).MaxHeatAirMassFlow * PTUnit( PTUnitNum ).MSHeatingSpeedRatio( Iter );
}
}
// intialize idle flow
Expand Down Expand Up @@ -3120,7 +3121,6 @@ namespace PackagedTerminalHeatPump {
ShowContinueError( " Occurs in " + CurrentModuleObject + " = " + PTUnit( PTUnitNum ).Name );
PTUnit( PTUnitNum ).IdleVolumeAirRate = PTUnit( PTUnitNum ).FanVolFlow;
}
RhoAir = StdRhoAir;
// set the mass flow rates from the reset volume flow rates
for ( i = 1; i <= NumOfSpeedCooling; ++i ) {
PTUnit( PTUnitNum ).CoolMassFlowRate( i ) = RhoAir * PTUnit( PTUnitNum ).CoolVolumeFlowRate( i );
Expand Down Expand Up @@ -6510,8 +6510,7 @@ namespace PackagedTerminalHeatPump {
CompOnMassFlow = SpeedRatio * PTUnit( PTUnitNum ).CoolMassFlowRate( SpeedNum ) + ( 1.0 - SpeedRatio ) * PTUnit( PTUnitNum ).CoolMassFlowRate( SpeedNum - 1 );
CompOnFlowRatio = SpeedRatio * PTUnit( PTUnitNum ).MSCoolingSpeedRatio( SpeedNum ) + ( 1.0 - SpeedRatio ) * PTUnit( PTUnitNum ).MSCoolingSpeedRatio( SpeedNum - 1 );
MSHPMassFlowRateLow = PTUnit( PTUnitNum ).CoolMassFlowRate( SpeedNum - 1 );
MSHPMassFlowRateHigh = PTUnit( PTUnitNum ).CoolMassFlowRate( SpeedNum );
}
MSHPMassFlowRateHigh = PTUnit( PTUnitNum ).CoolMassFlowRate( SpeedNum ); }
}
}

Expand Down
54 changes: 27 additions & 27 deletions src/EnergyPlus/SimAirServingZones.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1906,7 +1906,7 @@ namespace SimAirServingZones {
FoundCentralHeatCoil = true;
}
} // end of component loop
} // end of Branch loop
} // end of Branch loop
PrimaryAirSystem( AirLoopNum ).CentralHeatCoilExists = FoundCentralHeatCoil;
} // end of AirLoop loop

Expand Down Expand Up @@ -6028,7 +6028,7 @@ namespace SimAirServingZones {

// Specify the heating supply air Temp/HumRat for different system configurations
for ( AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum ) {

NumZonesHeated = AirToZoneNodeInfo( AirLoopNum ).NumZonesHeated;

if ( NumZonesHeated > 0 ) { // IF there are centrally heated zones
Expand Down Expand Up @@ -6361,7 +6361,7 @@ namespace SimAirServingZones {

Real64
GetHeatingSATempForSizing(
int const IndexAirLoop // air loop index
int const IndexAirLoop // air loop index
)
{

Expand All @@ -6372,8 +6372,8 @@ namespace SimAirServingZones {
// RE-ENGINEERED na

// PURPOSE OF THIS SUBROUTINE:
// This subroutine get the proper reheat coil inlet temperature for sizing, depending on
// the system configurations:
// This subroutine get the proper reheat coil inlet temperature for sizing, depending on
// the system configurations:
// (1) Central heating coils exist
// (2) No central heating coils, but preheating coils or OA heat-exchangers exist
// (3) No central heating coils; No preheating coils or OA heat-exchangers
Expand All @@ -6397,7 +6397,7 @@ namespace SimAirServingZones {
Real64 ReheatCoilInHumRatForSizing; // Humidity ratio of the reheat coil inlet air [kg/kg]
Real64 ReheatCoilInEnthalpyForSizing; // Enthalpy of the reheat coil inlet air [J/kg]
Real64 OutAirFrac;

// SUBROUTINE ARGUMENT DEFINITIONS:

// SUBROUTINE PARAMETER DEFINITIONS:
Expand All @@ -6410,12 +6410,12 @@ namespace SimAirServingZones {
// na

// SUBROUTINE LOCAL VARIABLE DECLARATIONS:

if ( PrimaryAirSystem( IndexAirLoop ).CentralHeatCoilExists ){
//Case: Central heating coils exist

ReheatCoilInTempForSizing = CalcSysSizing( IndexAirLoop ).HeatSupTemp;

} else if ( ( PrimaryAirSystem( IndexAirLoop ).NumOAHeatCoils > 0 ) || ( PrimaryAirSystem( IndexAirLoop ).NumOAHXs ) ) {
//Case: No central heating coils, but preheating coils or OA heat-exchangers exist

Expand All @@ -6428,26 +6428,26 @@ namespace SimAirServingZones {

// Mixed air humidity ratio and enthalpy
ReheatCoilInHumRatForSizing = OutAirFrac * FinalSysSizing( IndexAirLoop ).PreheatHumRat + ( 1 - OutAirFrac ) * FinalSysSizing( IndexAirLoop ).HeatRetHumRat;
ReheatCoilInEnthalpyForSizing = OutAirFrac * PsyHFnTdbW( FinalSysSizing( IndexAirLoop ).PreheatTemp, FinalSysSizing( IndexAirLoop ).PreheatHumRat )
ReheatCoilInEnthalpyForSizing = OutAirFrac * PsyHFnTdbW( FinalSysSizing( IndexAirLoop ).PreheatTemp, FinalSysSizing( IndexAirLoop ).PreheatHumRat )
+ ( 1 - OutAirFrac ) * PsyHFnTdbW( FinalSysSizing( IndexAirLoop ).HeatRetTemp, FinalSysSizing( IndexAirLoop ).HeatRetHumRat );

// Mixed air dry bulb temperature
ReheatCoilInTempForSizing = PsyTdbFnHW( ReheatCoilInEnthalpyForSizing, ReheatCoilInHumRatForSizing );

} else {
//Case: No central heating coils; No preheating coils or OA heat-exchangers

ReheatCoilInTempForSizing = FinalSysSizing( IndexAirLoop ).HeatMixTemp;

}

return ReheatCoilInTempForSizing;

}

Real64
GetHeatingSATempHumRatForSizing(
int const IndexAirLoop // air loop index
int const IndexAirLoop // air loop index
)
{

Expand All @@ -6458,8 +6458,8 @@ namespace SimAirServingZones {
// RE-ENGINEERED na

// PURPOSE OF THIS SUBROUTINE:
// This subroutine get the proper reheat coil inlet humidity ratio for sizing, depending on
// the system configurations:
// This subroutine get the proper reheat coil inlet humidity ratio for sizing, depending on
// the system configurations:
// (1) Central heating coils exist
// (2) No central heating coils, but preheating coils or OA heat-exchangers exist
// (3) No central heating coils; No preheating coils or OA heat-exchangers
Expand All @@ -6473,13 +6473,13 @@ namespace SimAirServingZones {
// Using/Aliasing
using namespace DataSizing;
using DataAirSystems::PrimaryAirSystem;

// USE ZoneAirLoopEquipmentManager, ONLY: GetZoneAirLoopEquipment

// Locals
Real64 ReheatCoilInHumRatForSizing;
Real64 OutAirFrac;

// SUBROUTINE ARGUMENT DEFINITIONS:

// SUBROUTINE PARAMETER DEFINITIONS:
Expand All @@ -6492,12 +6492,12 @@ namespace SimAirServingZones {
// na

// SUBROUTINE LOCAL VARIABLE DECLARATIONS:

if ( PrimaryAirSystem( IndexAirLoop ).CentralHeatCoilExists ) {
//Case: Central heating coils exist

ReheatCoilInHumRatForSizing = CalcSysSizing( IndexAirLoop ).HeatSupHumRat;

} else if ( ( PrimaryAirSystem( IndexAirLoop ).NumOAHeatCoils > 0 ) || ( PrimaryAirSystem( IndexAirLoop ).NumOAHXs ) ) {
//Case: No central heating coils, but preheating coils or OA heat-exchangers exist

Expand All @@ -6509,18 +6509,18 @@ namespace SimAirServingZones {
}

ReheatCoilInHumRatForSizing = OutAirFrac * FinalSysSizing( IndexAirLoop ).PreheatHumRat + ( 1 - OutAirFrac ) * FinalSysSizing( IndexAirLoop ).HeatRetHumRat;

} else {
//Case: No central heating coils; No preheating coils or OA heat-exchangers

ReheatCoilInHumRatForSizing = FinalSysSizing( IndexAirLoop ).HeatMixHumRat;

}

return ReheatCoilInHumRatForSizing;

}


// End Algorithm Section of the Module
// *****************************************************************************
Expand Down