-
Notifications
You must be signed in to change notification settings - Fork 394
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
Correct physics based VRF model to align inlet and outlet air flow rates #7295
Changes from 10 commits
3aa02d6
63442e6
03f4064
ac463cb
a674053
1b8245c
69211ef
ce7d093
b2f4106
5bd6ae1
2ec3bcf
9792e73
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3287,6 +3287,8 @@ namespace HVACVariableRefrigerantFlow { | |
if (errFlag) { | ||
ShowContinueError("...occurs in " + cCurrentModuleObject + " = " + VRFTU(VRFTUNum).Name); | ||
ErrorsFound = true; | ||
} else { | ||
VRFTU(VRFTUNum).fanOutletNode = Fans::Fan(VRFTU(VRFTUNum).FanIndex).OutletNodeNum; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Save fan outlet node for use in TeTc calculations. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems reasonable enough, if you are going to have to query what the fan is doing, you can check the outlet node. |
||
} | ||
|
||
// Set the Design Fan Volume Flow Rate | ||
|
@@ -3350,6 +3352,7 @@ namespace HVACVariableRefrigerantFlow { | |
FanInletNodeNum = HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->inletNodeNum; | ||
FanOutletNodeNum = HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->outletNodeNum; | ||
VRFTU(VRFTUNum).FanAvailSchedPtr = HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->availSchedIndex; | ||
VRFTU(VRFTUNum).fanOutletNode = HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->outletNodeNum; | ||
} | ||
} else { // IF (FanType_Num == FanType_SimpleOnOff .OR. FanType_Num == FanType_SimpleConstVolume)THEN | ||
ShowSevereError(cCurrentModuleObject + " = " + VRFTU(VRFTUNum).Name); | ||
|
@@ -7017,6 +7020,15 @@ namespace HVACVariableRefrigerantFlow { | |
// Algorithm Type: VRF model based on physics, appliable for Fluid Temperature Control | ||
VRFTU(VRFTUNum).ControlVRF_FluidTCtrl(VRFTUNum, QZnReq, FirstHVACIteration, PartLoadRatio, OnOffAirFlowRatio); | ||
VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(VRFTUNum, FirstHVACIteration, PartLoadRatio, SysOutputProvided, OnOffAirFlowRatio, LatOutputProvided); | ||
if (PartLoadRatio == 0.0) { // set coil inlet conditions when coil does not operate. Inlet conditions are set in ControlVRF_FluidTCtrl when PLR=1 | ||
if (VRFTU(VRFTUNum).CoolingCoilPresent) { | ||
VRFTU(VRFTUNum).coilInNodeT = DataLoopNode::Node(DXCoils::DXCoil(VRFTU(VRFTUNum).CoolCoilIndex).AirInNode).Temp; | ||
VRFTU(VRFTUNum).coilInNodeW = DataLoopNode::Node(DXCoils::DXCoil(VRFTU(VRFTUNum).CoolCoilIndex).AirInNode).HumRat; | ||
} else { | ||
VRFTU(VRFTUNum).coilInNodeT = DataLoopNode::Node(DXCoils::DXCoil(VRFTU(VRFTUNum).HeatCoilIndex).AirInNode).Temp; | ||
VRFTU(VRFTUNum).coilInNodeW = DataLoopNode::Node(DXCoils::DXCoil(VRFTU(VRFTUNum).HeatCoilIndex).AirInNode).HumRat; | ||
} | ||
} | ||
// CalcVRF( VRFTUNum, FirstHVACIteration, PartLoadRatio, SysOutputProvided, OnOffAirFlowRatio, LatOutputProvided ); | ||
} else { | ||
// Algorithm Type: VRF model based on system curve | ||
|
@@ -7094,7 +7106,6 @@ namespace HVACVariableRefrigerantFlow { | |
// The RETURNS here will jump back to SimVRF where the CalcVRF routine will simulate with latest PLR | ||
|
||
// do nothing else if TU is scheduled off | ||
//!!LKL Discrepancy < 0 | ||
if (GetCurrentScheduleValue(VRFTU(VRFTUNum).SchedPtr) == 0.0) return; | ||
|
||
// do nothing if TU has no load (TU will be modeled using PLR=0) | ||
|
@@ -8526,7 +8537,7 @@ namespace HVACVariableRefrigerantFlow { | |
for (int i = 1; i <= TerminalUnitList(TUListNum).NumTUInList; i++) { | ||
int VRFTUNum = TerminalUnitList(TUListNum).ZoneTUPtr(i); | ||
// analyze the conditions of each IU | ||
VRFTU(VRFTUNum).CalcVRFIUVariableTeTc(VRFTUNum, EvapTemp(i), CondTemp(i)); | ||
VRFTU(VRFTUNum).CalcVRFIUVariableTeTc(EvapTemp(i), CondTemp(i)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 👍 👍 👍 |
||
|
||
// select the Te/Tc that can satisfy all the zones | ||
IUMinEvapTemp = min(IUMinEvapTemp, EvapTemp(i), this->IUEvapTempHigh); | ||
|
@@ -8543,8 +8554,7 @@ namespace HVACVariableRefrigerantFlow { | |
} | ||
} | ||
|
||
void VRFTerminalUnitEquipment::CalcVRFIUVariableTeTc(int const VRFTUNum, // Index to VRF terminal unit | ||
Real64 &EvapTemp, // evaporating temperature | ||
void VRFTerminalUnitEquipment::CalcVRFIUVariableTeTc(Real64 &EvapTemp, // evaporating temperature | ||
Real64 &CondTemp // condensing temperature | ||
) | ||
{ | ||
|
@@ -8588,12 +8598,8 @@ namespace HVACVariableRefrigerantFlow { | |
// na | ||
|
||
// SUBROUTINE LOCAL VARIABLE DECLARATIONS: | ||
int const Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types | ||
int CoolCoilNum; // index to the VRF Cooling DX coil to be simulated | ||
int FanOutletNode; // index to the outlet node of the fan | ||
int HeatCoilNum; // index to the VRF Heating DX coil to be simulated | ||
int OAMixerNum; // OA mixer index | ||
int OAMixNode; // index to the mix node of OA mixer | ||
int IndexToTUInTUList; // index to TU in specific list for the VRF system | ||
int TUListIndex; // index to TU list for this VRF system | ||
int VRFNum; // index to VRF that the VRF Terminal Unit serves | ||
|
@@ -8619,7 +8625,6 @@ namespace HVACVariableRefrigerantFlow { | |
Real64 RHsat; // Relative humidity of the air at saturated condition(-) | ||
Real64 SH; // Super heating degrees (C) | ||
Real64 SC; // Subcooling degrees (C) | ||
Real64 temp; // for temporary use | ||
Real64 T_coil_in; // Temperature of the air at the coil inlet, after absorbing the heat released by fan (C) | ||
Real64 T_TU_in; // Air temperature at the indoor unit inlet (C) | ||
Real64 Tout; // Air temperature at the indoor unit outlet (C) | ||
|
@@ -8651,46 +8656,11 @@ namespace HVACVariableRefrigerantFlow { | |
C2Tcond = DXCoil(HeatCoilNum).C2Tc; | ||
C3Tcond = DXCoil(HeatCoilNum).C3Tc; | ||
|
||
// Rated air flow rate for the coil | ||
if ((!VRF(VRFNum).HeatRecoveryUsed && CoolingLoad(VRFNum)) || | ||
(VRF(VRFNum).HeatRecoveryUsed && TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList))) { | ||
// VRF terminal unit is on cooling mode | ||
CompOnMassFlow = DXCoil(CoolCoilNum).RatedAirMassFlowRate(Mode); | ||
} else if ((!VRF(VRFNum).HeatRecoveryUsed && HeatingLoad(VRFNum)) || | ||
(VRF(VRFNum).HeatRecoveryUsed && TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList))) { | ||
// VRF terminal unit is on heating mode | ||
CompOnMassFlow = DXCoil(HeatCoilNum).RatedAirMassFlowRate(Mode); | ||
} | ||
|
||
// Set inlet air mass flow rate based on PLR and compressor on/off air flow rates | ||
SetAverageAirFlow(VRFTUNum, 1.0, temp); | ||
VRFInletNode = this->VRFTUInletNodeNum; | ||
T_TU_in = Node(VRFInletNode).Temp; | ||
W_TU_in = Node(VRFInletNode).HumRat; | ||
T_coil_in = T_TU_in; | ||
W_coil_in = W_TU_in; | ||
|
||
// Simulation the OAMixer if there is any | ||
if (this->OAMixerUsed) { | ||
SimOAMixer(this->OAMixerName, false, this->OAMixerIndex); | ||
|
||
OAMixerNum = UtilityRoutines::FindItemInList(this->OAMixerName, OAMixer); | ||
OAMixNode = OAMixer(OAMixerNum).MixNode; | ||
T_coil_in = Node(OAMixNode).Temp; | ||
W_coil_in = Node(OAMixNode).HumRat; | ||
} | ||
// Simulate the blow-through fan if there is any | ||
if (this->FanPlace == BlowThru) { | ||
if (this->fanType_Num == DataHVACGlobals::FanType_SystemModelObject) { | ||
HVACFan::fanObjs[this->FanIndex]->simulate(1.0 / temp, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _); | ||
FanOutletNode = HVACFan::fanObjs[this->FanIndex]->outletNodeNum; | ||
} else { | ||
Fans::SimulateFanComponents("", false, this->FanIndex, FanSpeedRatio, ZoneCompTurnFansOn, ZoneCompTurnFansOff); | ||
FanOutletNode = Fans::Fan(this->FanIndex).OutletNodeNum; | ||
} | ||
T_coil_in = Node(FanOutletNode).Temp; | ||
W_coil_in = Node(FanOutletNode).HumRat; | ||
} | ||
T_coil_in = this->coilInNodeT; | ||
W_coil_in = this->coilInNodeW; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change here is that coil inlet temps are now used so it doesn't matter if blow thru fan or OA mixer is used. Gets rid of a lot of unnecessary code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 👍 👍 👍 👍 👍 👍 👍 👍 👍 👍 |
||
|
||
Garate = CompOnMassFlow; | ||
H_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in); | ||
|
@@ -10076,8 +10046,7 @@ namespace HVACVariableRefrigerantFlow { | |
bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step | ||
Real64 &PartLoadRatio, // unit part load ratio | ||
Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to AVERAGE airflow over timestep | ||
) | ||
{ | ||
) { | ||
|
||
// SUBROUTINE INFORMATION: | ||
// AUTHOR Rongpeng Zhang | ||
|
@@ -10150,7 +10119,6 @@ namespace HVACVariableRefrigerantFlow { | |
// The RETURNS here will jump back to SimVRF where the CalcVRF routine will simulate with latest PLR | ||
|
||
// do nothing else if TU is scheduled off | ||
//!!LKL Discrepancy < 0 | ||
if (GetCurrentScheduleValue(this->SchedPtr) == 0.0) return; | ||
|
||
// Block the following statement: QZnReq==0 doesn't mean QCoilReq==0 due to possible OA mixer operation. zrp_201511 | ||
|
@@ -10186,6 +10154,13 @@ namespace HVACVariableRefrigerantFlow { | |
// Otherwise the coil needs to turn on. Get full load result | ||
PartLoadRatio = 1.0; | ||
this->CalcVRF_FluidTCtrl(VRFTUNum, FirstHVACIteration, PartLoadRatio, FullOutput, OnOffAirFlowRatio); | ||
if (this->CoolingCoilPresent) { | ||
this->coilInNodeT = DataLoopNode::Node(DXCoils::DXCoil(this->CoolCoilIndex).AirInNode).Temp; | ||
this->coilInNodeW = DataLoopNode::Node(DXCoils::DXCoil(this->CoolCoilIndex).AirInNode).HumRat; | ||
} else { | ||
this->coilInNodeT = DataLoopNode::Node(DXCoils::DXCoil(this->HeatCoilIndex).AirInNode).Temp; | ||
this->coilInNodeW = DataLoopNode::Node(DXCoils::DXCoil(this->HeatCoilIndex).AirInNode).HumRat; | ||
} | ||
|
||
PartLoadRatio = 0.0; | ||
|
||
|
@@ -10400,7 +10375,6 @@ namespace HVACVariableRefrigerantFlow { | |
Fans::SimulateFanComponents("", FirstHVACIteration, this->FanIndex, FanSpeedRatio, ZoneCompTurnFansOn, ZoneCompTurnFansOff); | ||
} | ||
} | ||
|
||
if (this->CoolingCoilPresent) { | ||
// above condition for heat pump mode, below condition for heat recovery mode | ||
if ((!VRF(VRFCond).HeatRecoveryUsed && CoolingLoad(VRFCond)) || | ||
|
@@ -10673,8 +10647,6 @@ namespace HVACVariableRefrigerantFlow { | |
// FUNCTION LOCAL VARIABLE DECLARATIONS: | ||
int const Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types | ||
int CoilIndex; // index to coil | ||
int FanOutletNode; // index to the outlet node of the fan | ||
int OAMixerNum; // OA mixer index | ||
int OAMixNode; // index to the mix node of OA mixer | ||
int VRFCond; // index to VRF condenser | ||
int VRFTUNum; // Unit index in VRF terminal unit array | ||
|
@@ -10724,24 +10696,19 @@ namespace HVACVariableRefrigerantFlow { | |
// Simulation the OAMixer if there is any | ||
if (VRFTU(VRFTUNum).OAMixerUsed) { | ||
SimOAMixer(VRFTU(VRFTUNum).OAMixerName, FirstHVACIteration, VRFTU(VRFTUNum).OAMixerIndex); | ||
|
||
OAMixerNum = UtilityRoutines::FindItemInList(VRFTU(VRFTUNum).OAMixerName, | ||
OAMixer); // this not needed, why not use VRFTU( VRFTUNum ).OAMixerIndex var | ||
OAMixNode = OAMixer(OAMixerNum).MixNode; | ||
OAMixNode = OAMixer(VRFTU(VRFTUNum).OAMixerIndex).MixNode; | ||
Tin = Node(OAMixNode).Temp; | ||
Win = Node(OAMixNode).HumRat; | ||
} | ||
// Simulate the blow-through fan if there is any | ||
if (VRFTU(VRFTUNum).FanPlace == BlowThru) { | ||
if (VRFTU(VRFTUNum).fanType_Num == DataHVACGlobals::FanType_SystemModelObject) { | ||
HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->simulate(1.0 / temp, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _); | ||
FanOutletNode = HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->outletNodeNum; | ||
} else { | ||
Fans::SimulateFanComponents("", false, VRFTU(VRFTUNum).FanIndex, FanSpeedRatio, ZoneCompTurnFansOn, ZoneCompTurnFansOff); | ||
FanOutletNode = Fans::Fan(VRFTU(VRFTUNum).FanIndex).OutletNodeNum; | ||
} | ||
Tin = Node(FanOutletNode).Temp; | ||
Win = Node(FanOutletNode).HumRat; | ||
Tin = Node(VRFTU(VRFTUNum).fanOutletNode).Temp; | ||
Win = Node(VRFTU(VRFTUNum).fanOutletNode).HumRat; | ||
} | ||
|
||
// Call the coil control logic to determine the air flow rate to match the given coil load | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -700,6 +700,9 @@ namespace HVACVariableRefrigerantFlow { | |
int ATMixerSecNode; // secondary air inlet node number for the air terminal mixer | ||
int ATMixerOutNode; // outlet air node number for the air terminal mixer | ||
bool firstPass; // used to reset global sizing data | ||
Real64 coilInNodeT; // coil inlet node temp at full flow (C) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new variables to hold data in order to eliminate the problem with flow mismatch from inlet to outlet. |
||
Real64 coilInNodeW; // coil inlet node humidity ratio at full flow (kg/kg) | ||
int fanOutletNode; // fan outlet node index | ||
// Default Constructor | ||
VRFTerminalUnitEquipment() | ||
: VRFTUType_Num(0), SchedPtr(-1), VRFSysNum(0), TUListIndex(0), IndexToTUInTUList(0), ZoneNum(0), VRFTUInletNodeNum(0), | ||
|
@@ -715,7 +718,8 @@ namespace HVACVariableRefrigerantFlow { | |
SensibleCoolingRate(0.0), SensibleHeatingRate(0.0), LatentCoolingRate(0.0), LatentHeatingRate(0.0), TotalCoolingEnergy(0.0), | ||
TotalHeatingEnergy(0.0), SensibleCoolingEnergy(0.0), SensibleHeatingEnergy(0.0), LatentCoolingEnergy(0.0), LatentHeatingEnergy(0.0), | ||
EMSOverridePartLoadFrac(false), EMSValueForPartLoadFrac(0.0), IterLimitExceeded(0), FirstIterfailed(0), ZonePtr(0), HVACSizingIndex(0), | ||
ATMixerExists(false), ATMixerIndex(0), ATMixerType(0), ATMixerPriNode(0), ATMixerSecNode(0), ATMixerOutNode(0), firstPass(true) | ||
ATMixerExists(false), ATMixerIndex(0), ATMixerType(0), ATMixerPriNode(0), ATMixerSecNode(0), ATMixerOutNode(0), firstPass(true), | ||
coilInNodeT(0.0), coilInNodeW(0.0), fanOutletNode(0) | ||
{ | ||
} | ||
|
||
|
@@ -725,8 +729,7 @@ namespace HVACVariableRefrigerantFlow { | |
// Note: the argument VRFTUNum should be removed later in the deeper OO re-factor. Now this argument may be used by other functions that are | ||
// not member functions of this class. | ||
|
||
void CalcVRFIUVariableTeTc(int const VRFTUNum, // Index to VRF terminal unit | ||
Real64 &EvapTemp, // evaporating temperature | ||
void CalcVRFIUVariableTeTc(Real64 &EvapTemp, // evaporating temperature | ||
Real64 &CondTemp // condensing temperature | ||
); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good find.