Skip to content

Commit

Permalink
Merge pull request #6285 from NREL/PIUFan6152
Browse files Browse the repository at this point in the history
Thermostatic fan control for series fan-powered induction units - and stabilize night cycle manager during warmup
  • Loading branch information
rraustad authored Sep 2, 2017
2 parents 514a399 + 2a6f671 commit 3c779ea
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ \subsection{Night Cycle}\label{night-cycle}

\end{itemize}

If the fan schedule current value is \textgreater{} 0 or the applicability schedule value is \(\le\) ~0 or if the program is in warmup, \emph{AvailStatus = NoAction}.
If the fan schedule current value is \textgreater{} 0 or the applicability schedule value is \(\le\) ~0 , \emph{AvailStatus = NoAction}.

If the program is in warmup,the start time stop time are reset to the current time.

Otherwise:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ \subsection{Fan Powered Induction Series and Parallel Single Duct~ Reheat Air Te

\subsubsection{Overview}\label{overview-1-000}

The input objects AirTerminal:SingleDuct:SeriesPIU:Reheat and \\ AirTerminal:SingleDuct:ParallelPIU:Reheat provide models for fan powered induction terminal units that occur in a variety of configurations. EnergyPlus models 2 types: \emph{series} (sometimes called \emph{constant}) and \emph{parallel} (sometimes called \emph{intermittent}). The series unit provides a constant flow of air to the zone (the fan is always on at a constant flow) with a variable proportion of primary and secondary air. The parallel unit has an intermittent fan: the fan is off at maximum cooling and does not switch on until primary air flow is significantly reduced from the maximum. Once on it provides a constant flow of secondary air. Both units induce air from the zone or plenum (secondary air) and mix it with centrally conditioned supply air (primary air). Both units are variable volume: the supply air flow rate is varied to match zone conditioning requirement.
The input objects AirTerminal:SingleDuct:SeriesPIU:Reheat and \\ AirTerminal:SingleDuct:ParallelPIU:Reheat provide models for fan powered induction terminal units that occur in a variety of configurations. EnergyPlus models 2 types: \emph{series} (sometimes called \emph{constant}) and \emph{parallel} (sometimes called \emph{intermittent}). The series unit provides a constant flow of air to the zone (the fan is always on at a constant flow) with a variable proportion of primary and secondary air. The parallel unit has an intermittent fan: the fan is off at maximum cooling and does not switch on until primary air flow is significantly reduced from the maximum or if reheat is required. Once on it provides a constant flow of secondary air. Both units induce air from the zone or plenum (secondary air) and mix it with centrally conditioned supply air (primary air). Both units are variable volume: the supply air flow rate is varied to match zone conditioning requirement.

\subsubsection{Model}\label{model-1}

Expand Down Expand Up @@ -300,7 +300,7 @@ \subsubsection{Simulation and Control}\label{simulation-and-control-2}
\item
If the unit is scheduled off, the primary and secondary flow rates are set to zero.
\item
If there is no primary air flow (or less than .001 kg/s), the primary air flow is set to zero and the secondary air flow is set to the constant total air flow input by the user.
If there is no primary air flow (or less than .001 kg/s), the primary air flow is set to zero and the secondary air flow is set to the constant total air flow input by the user only if there is a heating load.
\item
If the zone temperature is in the deadband or the zone load is less than 1 watt or the zone needs heating, the primary air flow rate is set to the minimum flow rate specified by the input and the secondary air flow rate is set to the difference between the fixed total air flow rate and the primary air flow rate.
\item
Expand Down Expand Up @@ -354,9 +354,9 @@ \subsubsection{Simulation and Control}\label{simulation-and-control-2}
\item
If the unit is scheduled off, the primary and secondary flow rates are set to zero.
\item
If there is no primary air flow (or less than .001 kg/s), the primary air flow is set to zero and the secondary air flow is set to the max secondary air flow input by the user.
If there is no primary air flow (or less than .001 kg/s), the primary air flow is set to zero and the secondary air flow is set to the max secondary air flow input by the user only if there is a heating load.
\item
If the zone temperature is in the deadband or the zone load is less than 1 watt or the zone needs heating, the primary air flow rate is set to the minimum flow rate specified by the input and the secondary air flow rate is set to max secondary air flow input by the user.
If the zone temperature is in the deadband or the zone load is less than 1 watt or the zone needs heating, the primary air flow rate is set to the minimum flow rate specified by the input. If there is a heating load or reheat is required, the secondary air flow rate is set to max secondary air flow input by the user.
\item
Otherwise, the zone needs cooling and the unit is active.
\begin{itemize}
Expand All @@ -375,7 +375,7 @@ \subsubsection{Simulation and Control}\label{simulation-and-control-2}
{\dot m_{pri}} = ({\dot Q_{z,req}} - {c_{p,air}}\cdot {\dot m_{sec}}\cdot ({T_{in,sec}} + \Delta {T_{fan}} - {T_z}))/({c_{p,air}}\cdot ({T_{in,pri}} - {T_z}))
\end{equation}

The secondary flow rate is set to the user input fixed flow rate. The primary air flow rate is constrained to be between the min and max primary flow rated.
The secondary flow rate is set to the user input fixed flow rate if reheat is required or if the primary air flow fraction is at or below the user-specified fan on fraction. The primary air flow rate is constrained to be between the min and max primary flow rated.
\end{itemize}
\end{itemize}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,8 @@ \subsubsection{Outputs}\label{outputs-6}

\subsection{AirTerminal:SingleDuct:SeriesPIU:Reheat}\label{airterminalsingleductseriespiureheat}

The series powered induction unit is an air system terminal unit that mixes varying amounts of secondary (recirculated) air and primary (conditioned supply) air to produce a fixed flow of air to a zone. The unit contains a small fan that acts to induce the secondary air and a heating coil for heating the mixed secondary and primary air. The fan runs at a constant volume flow rate whenever the unit is on (and the fan's availability schedule is on or it is activated by an availability manager). The fan is downstream of the primary and secondary air inlets. The variable mixing is accomplished by a damper in the unit's primary air supply inlet duct. This damper can move from fully open (100\% primary air. 0\% secondary air) to a minimum stop that is specified in the input description. At full cooling the damper will be fully open. At minimum cooling and for heating the damper will be at the minimum stop and the secondary air flow will be at its maximum.
The series powered induction unit is an air system terminal unit that mixes varying amounts of secondary (recirculated) air and primary (conditioned supply) air to produce a fixed flow of air to a zone. The unit contains a small fan that acts to induce the secondary air and a heating coil for heating the mixed secondary and primary air. The fan runs at a constant volume flow rate whenever the unit is on (and the fan's availability schedule is on or it is activated by an availability manager). The fan is downstream of the primary and secondary air inlets. The variable mixing is accomplished by a damper in the unit's primary air supply inlet duct. This damper can move from fully open (100\% primary air. 0\% secondary air) to a minimum stop that is specified in the input description. At full cooling the damper will be fully open. At minimum cooling and for heating the damper will be at the minimum stop and the secondary air flow will be at its maximum. During night cycle operation, if the availability manager status is CycleOnZoneFansOnly, then the fan will run only if there is a heating load. If the status is CycleOn, then the fan will run according to the normal controls.


The EnergyPlus model of the series PIU terminal unit is composed of three components: a zone mixer, a constant volume fan, and a heating coil (hot water, electric, or gas).

Expand Down Expand Up @@ -853,7 +854,7 @@ \subsubsection{Inputs}\label{inputs-7-000}

\paragraph{Field: Fan Name}\label{field-fan-name-1}

The name of a fan component which composes part of the unit. Note that the fan's maximum flow rate should be the same as the maximum air flow rate of the PIU and the type of fan object must be Fan:SystemModel or Fan:ConstantVolume. The fan's inlet node should be the same as the zone mixer's outlet node. The fan's outlet node should be the same as the heating coil's air inlet node. The secondary fan will run according to the Availability Schedule specified in the fan object, unless it is overridden by an availability manager (ref. AvailabilityManager:NightCycle and others).
The name of a fan component which composes part of the unit. Note that the fan's maximum flow rate should be the same as the maximum air flow rate of the PIU and the type of fan object must be Fan:SystemModel or Fan:ConstantVolume. The fan's inlet node should be the same as the zone mixer's outlet node. The fan's outlet node should be the same as the heating coil's air inlet node. The secondary fan will run only when the Availability Schedule specified in the fan object is >0 or when it is overridden by an availability manager (ref. AvailabilityManager:NightCycle and others).

\paragraph{Field: Reheat Coil Object Type}\label{field-reheat-coil-object-type-3}

Expand Down Expand Up @@ -984,9 +985,7 @@ \subsubsection{Inputs}\label{inputs-8-000}

\paragraph{Field: Fan On Flow Fraction}\label{field-fan-on-flow-fraction}

If Fan On Flow Fraction is > 0, then this is the fraction of the primary air flow at which the fan turns on. In the parallel PIU the fan operation is intermittent. If the primary air flow is above this fraction of the maximum, the fan is off. Otherwise the secondary fan will run according to the Availability Schedule specified in the Fan:ConstantVolume object (see Fan Name below), unless it is overridden by an availability manager (ref. AvailabilityManager:NightCycle and others). The fan will operate whenever the availability status is CycleOn or CycleOnZoneFansOnly.

If Fan On Flow Fraction = 0, then the fan is controlled based on the zone load requirement rather than primary air flow fraction. The fan will operate if there is a heating load or if reheat is required to maintain the zone at the thermostat heating setpoint. When the Availability Schedule specified in the Fan:ConstantVolume object (see Fan Name below) is off, it may be overridden by an availability manager (ref. AvailabilityManager:NightCycle and others). If the availability manager status is CycleOnZoneFansOnly, then the fan will run regardless of zone load. If the status is CycleOn, then the fan will run only if there is a heating load or reheat is required.
This is the fraction of the primary air flow at or below which the secondary fan turns on. In the parallel PIU the fan operation is intermittent. If the primary air flow is above this fraction of the maximum, the fan is off unless reheat is required. The fan will only operate if the Availability Schedule specified in the Fan:ConstantVolume object (see Fan Name below) is >0 or when it is overridden by an availability manager (ref. AvailabilityManager:NightCycle and others). If the availability manager status is CycleOnZoneFansOnly, then the fan will run only if there is a heating load. If the status is CycleOn, then the fan will run according to the normal controls (low flow or reheat required).

\paragraph{Field: Supply Air Inlet Node Name}\label{field-supply-air-inlet-node-name-1}

Expand All @@ -1010,7 +1009,7 @@ \subsubsection{Inputs}\label{inputs-8-000}

\paragraph{Field: Fan Name}\label{field-fan-name-2}

The name of a fan component which composes part of the unit. Note that the fan's maximum flow rate should be the same as the maximum secondary air flow rate of the PIU and the type of fan object must be Fan:SystemModel or Fan:ConstantVolume. The fan's inlet node should be the same as the PIU secondary air inlet node. The fan's outlet node should be the same as one of the zone mixer's inlet nodes. When the primary air flow is below the Fan On Flow Fraction (above), the secondary fan will run according to the Availability Schedule specified in the Fan:ConstantVolume object, unless it is overridden by an availability manager (ref. AvailabilityManager:NightCycle and others).
The name of a fan component which composes part of the unit. Note that the fan's maximum flow rate should be the same as the maximum secondary air flow rate of the PIU and the type of fan object must be Fan:SystemModel or Fan:ConstantVolume. The fan's inlet node should be the same as the PIU secondary air inlet node. The fan's outlet node should be the same as one of the zone mixer's inlet nodes. The secondary fan will run only when the Availability Schedule specified in the Fan:ConstantVolume object is >0 or when it is overridden by an availability manager (ref. AvailabilityManager:NightCycle and others). See description of fan controls under Fan On Flow Fraction above.

\paragraph{Field: Reheat Coil Object Type}\label{field-reheat-coil-object-type-4}

Expand Down
58 changes: 27 additions & 31 deletions src/EnergyPlus/PoweredInductionUnits.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,9 @@ namespace PoweredInductionUnits {
Real64 MinSteamFlow;
Real64 MaxSteamFlow;
Real64 mdot; // local plant fluid flow rate kg/s
// Initialize local fan flags to global system flags
bool PIUTurnFansOn = ( DataHVACGlobals::TurnFansOn || DataHVACGlobals::TurnZoneFansOnlyOn ); // If True, overrides fan schedule and cycles PIU fan on
bool PIUTurnFansOff = DataHVACGlobals::TurnFansOff; // If True, overrides fan schedule and PIUTurnFansOn and cycles PIU fan off

// FLOW

Expand Down Expand Up @@ -1422,7 +1425,13 @@ namespace PoweredInductionUnits {
if ( ! PriOn ) {
// no primary air flow
PriAirMassFlow = 0.0;
SecAirMassFlow = PIU( PIUNum ).MaxTotAirMassFlow;
// PIU fan off if there is no heating load, also reset fan flag if fan should be off
if ( QZnReq <= SmallLoad ) {
SecAirMassFlow = 0.0;
PIUTurnFansOn = false;
} else {
SecAirMassFlow = PIU( PIUNum ).MaxTotAirMassFlow;
}
} else if ( CurDeadBandOrSetback( ZoneNum ) || std::abs( QZnReq ) < SmallLoad ) {
// in deadband or very small load: set primary air flow to the minimum
PriAirMassFlow = PriAirMassFlowMin;
Expand All @@ -1439,9 +1448,9 @@ namespace PoweredInductionUnits {
Node( SecNode ).MassFlowRate = PIU( PIUNum ).MaxTotAirMassFlow;
SimAirMixer( PIU( PIUNum ).MixerName, PIU( PIUNum ).Mixer_Num ); // fire the mixer
if ( PIU( PIUNum ).Fan_Num == DataHVACGlobals::FanType_SystemModelObject ) {
HVACFan::fanObjs[ PIU( PIUNum ).Fan_Index ]->simulate( _,_,_,_ );
HVACFan::fanObjs[ PIU( PIUNum ).Fan_Index ]->simulate( _, PIUTurnFansOn , PIUTurnFansOff ,_ );
} else if ( PIU( PIUNum ).Fan_Num == DataHVACGlobals::FanType_SimpleConstVolume ) {
Fans::SimulateFanComponents( PIU( PIUNum ).FanName, FirstHVACIteration, PIU( PIUNum ).Fan_Index ); // fire the fan
Fans::SimulateFanComponents( PIU( PIUNum ).FanName, FirstHVACIteration, PIU( PIUNum ).Fan_Index, _, PIUTurnFansOn, PIUTurnFansOff ); // fire the fan
}

FanDeltaTemp = Node( HCoilInAirNode ).Temp - Node( SecNode ).Temp;
Expand Down Expand Up @@ -1473,9 +1482,9 @@ namespace PoweredInductionUnits {
SimAirMixer( PIU( PIUNum ).MixerName, PIU( PIUNum ).Mixer_Num );
// fire the fan
if ( PIU( PIUNum ).Fan_Num == DataHVACGlobals::FanType_SystemModelObject ) {
HVACFan::fanObjs[ PIU( PIUNum ).Fan_Index ]->simulate( _,_,_,_ );
HVACFan::fanObjs[ PIU( PIUNum ).Fan_Index ]->simulate( _, PIUTurnFansOn, PIUTurnFansOff, _ );
} else if ( PIU( PIUNum ).Fan_Num == DataHVACGlobals::FanType_SimpleConstVolume ) {
Fans::SimulateFanComponents( PIU( PIUNum ).FanName, FirstHVACIteration, PIU( PIUNum ).Fan_Index ); // fire the fan
Fans::SimulateFanComponents( PIU( PIUNum ).FanName, FirstHVACIteration, PIU( PIUNum ).Fan_Index, _, PIUTurnFansOn, PIUTurnFansOff ); // fire the fan
}
// check if heating coil is off
QActualHeating = QToHeatSetPt - Node( HCoilInAirNode ).MassFlowRate * CpAirZn * ( Node( HCoilInAirNode ).Temp - Node( ZoneNode ).Temp );
Expand Down Expand Up @@ -1643,41 +1652,32 @@ namespace PoweredInductionUnits {
// Set the mass flow rates
if ( UnitOn ) {
// unit is on
// Special controls if FanOnFlowFrac = 0.0
// Calculate if reheat is needed
bool ReheatRequired = false;
if (PIU(PIUNum).FanOnFlowFrac <= 0.0) {
// Calculate if reheat is needed
Real64 qMinPrimary = PriAirMassFlowMin * ( CpAirZn * min( -SmallTempDiff, ( Node( PriNode ).Temp - Node( ZoneNode ).Temp ) ) );
if ( qMinPrimary < QToHeatSetPt ) ReheatRequired = true;
}
Real64 qMinPrimary = PriAirMassFlowMin * ( CpAirZn * min( -SmallTempDiff, ( Node( PriNode ).Temp - Node( ZoneNode ).Temp ) ) );
if ( qMinPrimary < QToHeatSetPt ) ReheatRequired = true;

if ( ! PriOn ) {
// no primary air flow
PriAirMassFlow = 0.0;
// PIU fan off if FanOnFlowFrac is 0.0 and there is no heating load, also reset fan flag if fan should be off
if ( PIU( PIUNum ).FanOnFlowFrac <= 0.0 ) {
if ( QZnReq <= SmallLoad ) {
SecAirMassFlow = 0.0;
PIUTurnFansOn = false;
} else {
SecAirMassFlow = PIU( PIUNum ).MaxSecAirMassFlow;
PIUTurnFansOn = ( DataHVACGlobals::TurnFansOn || DataHVACGlobals::TurnZoneFansOnlyOn );
}
// PIU fan off if there is no heating load, also reset fan flag if fan should be off
if ( QZnReq <= SmallLoad ) {
SecAirMassFlow = 0.0;
PIUTurnFansOn = false;
} else {
SecAirMassFlow = PIU( PIUNum ).MaxSecAirMassFlow;
PIUTurnFansOn = ( DataHVACGlobals::TurnFansOn || DataHVACGlobals::TurnZoneFansOnlyOn );
}
} else if ( CurDeadBandOrSetback( ZoneNum ) || std::abs( QZnReq ) < SmallLoad ) {
// in deadband or very small load: set primary air flow to the minimum
PriAirMassFlow = PriAirMassFlowMin;
// PIU fan off if FanOnFlowFrac is 0.0 and reheat is not needed, also reset fan flag if fan should be off
if ( ( PIU( PIUNum ).FanOnFlowFrac <= 0.0 ) && ReheatRequired ) {
// PIU fan off if reheat is not needed, also reset fan flag if fan should be off
if ( ReheatRequired ) {
SecAirMassFlow = PIU( PIUNum ).MaxSecAirMassFlow;
PIUTurnFansOn = true;
} else if ( ( PIU( PIUNum ).FanOnFlowFrac <= 0.0 ) && !ReheatRequired ) {
} else {
SecAirMassFlow = 0.0;
PIUTurnFansOn = false;
} else {
SecAirMassFlow = PIU( PIUNum ).MaxSecAirMassFlow;
}
} else if ( QZnReq > SmallLoad ) {
// heating: set primary air flow to the minimum
Expand All @@ -1702,12 +1702,8 @@ namespace PoweredInductionUnits {
PriAirMassFlow = QZnReq / ( CpAirZn * min( -SmallTempDiff, ( Node( PriNode ).Temp - Node( ZoneNode ).Temp ) ) );
PriAirMassFlow = min( max( PriAirMassFlow, PriAirMassFlowMin ), PriAirMassFlowMax );
// check for fan on or off
if ( ( PriAirMassFlow > PIU( PIUNum ).FanOnAirMassFlow ) && ( PIU( PIUNum ).FanOnFlowFrac > 0.0 ) ) {
SecAirMassFlow = 0.0; // Fan is off; no secondary air
PIUTurnFansOn = false;
} else if ( ( PIU( PIUNum ).FanOnFlowFrac <= 0.0 ) && !ReheatRequired ) {
// if FanOnFlowFrac is 0, then fan does not run for cooling load unless reheat is required, also reset fan flag if fan should be off
SecAirMassFlow = 0.0; // Fan is off; no secondary air
if ( ( PriAirMassFlow > PIU( PIUNum ).FanOnAirMassFlow ) && !ReheatRequired ) {
SecAirMassFlow = 0.0; // Fan is off unless reheat is required; no secondary air; also reset fan flag
PIUTurnFansOn = false;
} else {
// fan is on; recalc primary air flow
Expand Down
6 changes: 6 additions & 0 deletions src/EnergyPlus/SystemAvailabilityManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2167,6 +2167,12 @@ namespace SystemAvailabilityManager {
static Array1D_bool ZoneCompNCControlType;
int CyclingRunTimeControlType;

// reset start/stop times at beginning of each day during warmup to prevent non-convergence due to rotating start times
if ( WarmupFlag && BeginDayFlag ) {
PriAirSysAvailMgr( PriAirSysNum ).StartTime = SimTimeSteps;
PriAirSysAvailMgr( PriAirSysNum ).StopTime = SimTimeSteps;
}

if ( present( ZoneEquipType ) ) {
StartTime = ZoneComp( ZoneEquipType ).ZoneCompAvailMgrs( CompNum ).StartTime;
StopTime = ZoneComp( ZoneEquipType ).ZoneCompAvailMgrs( CompNum ).StopTime;
Expand Down
Loading

8 comments on commit 3c779ea

@nrel-bot-3
Copy link

Choose a reason for hiding this comment

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

develop (rraustad) - x86_64-MacOS-10.9-clang: OK (2145 of 2145 tests passed, 0 test warnings)

Build Badge Test 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.

develop (rraustad) - i386-Windows-7-VisualStudio-14: OK (2145 of 2145 tests passed, 0 test warnings)

Build Badge Test 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.

develop (rraustad) - Win64-Windows-7-VisualStudio-14: OK (2145 of 2145 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.

develop (rraustad) - x86_64-Linux-Ubuntu-14.04-cppcheck-1.61: OK (0 of 0 tests passed, 0 test warnings)

Build 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.

develop (rraustad) - x86_64-Linux-Ubuntu-14.04-gcc-4.8: OK (2165 of 2165 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.

develop (rraustad) - x86_64-Linux-Ubuntu-14.04-gcc-4.8-UnitTestsCoverage-Debug: OK (1537 of 1537 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.

develop (rraustad) - x86_64-Linux-Ubuntu-14.04-custom_check: OK (0 of 0 tests passed, 0 test warnings)

Build 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.

develop (rraustad) - x86_64-Linux-Ubuntu-14.04-gcc-4.8-IntegrationCoverage-Debug: OK (2148 of 2148 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

Please sign in to comment.