Fix heating and cooling runtime fraction for AirLoopHVAC:UnitarySystem for airflow network simulations#11491
Fix heating and cooling runtime fraction for AirLoopHVAC:UnitarySystem for airflow network simulations#11491
AirLoopHVAC:UnitarySystem for airflow network simulations#11491Conversation
lymereJ
left a comment
There was a problem hiding this comment.
Code walk-through:
| // Report the current output | ||
| this->reportUnitarySystem(state, AirLoopNum); | ||
|
|
||
| // Get the actual maximum RTF for AFN simulations |
There was a problem hiding this comment.
Similar changes as for #11367. We save the RTFs at the system level instead of at the coil level and make the determination here, that way we can also include the supplemental heating coil.
| int CompIndex = this->m_HeatingCoilIndex; | ||
| HVAC::FanOp fanOp = this->m_FanOpMode; | ||
| Real64 DesOutTemp = this->m_DesiredOutletTemp; | ||
|
|
There was a problem hiding this comment.
These were only applied when the system is controller to a setpoint. The propose changes apply to both load-based and setpoint control.
| latOut); | ||
|
|
||
| // Check that the runtime fraction is less than one so the impact of cycling fan is correctly accounted for in the AFN | ||
| EXPECT_TRUE(state->dataAirLoop->AirLoopAFNInfo(1).AFNLoopHeatingCoilMaxRTF < 1); |
There was a problem hiding this comment.
New unit test to make sure that the correct RTF is retrieved. This verification fails on develop.
|
| if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP && | ||
| this->m_sysType != SysType::PackagedWSHP && AirLoopNum > 0) { | ||
| refAFNLoopHeatingCoilMaxRTF = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF; | ||
| refAFNLoopCoolingCoilMaxRTF = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF; |
There was a problem hiding this comment.
Can't you just move these last 2 lines down inside of the block below?
There was a problem hiding this comment.
I don't think so because I think this needs to happen before controlUnitarySystemtoSP or controlUnitarySystemtoLoad are called.
There was a problem hiding this comment.
I see. Because these same AFN variables are set in the child. In this parent there can be 2 heating coils so the larger RTF should be used and calling the control functions will set AFNLoopHeatingCoilMaxRTF to the RTF of the last coil called.
mitchute
left a comment
There was a problem hiding this comment.
A couple more questions for consideration.
| case HVAC::CoilType::HeatingSteam: | ||
| case HVAC::CoilType::HeatingWater: | ||
| case HVAC::CoilType::UserDefined: { | ||
| suppHeatingCoilRTF = 1.0; |
There was a problem hiding this comment.
Why are these types hard coded to RTF = 1 here?
Why not
suppHeatingCoilRTF = this->m_SuppHeatPartLoadFracThere was a problem hiding this comment.
Yup, good catch, I did not propagate the changes from the heating coil to the supplemental coil.
There was a problem hiding this comment.
That might work. Here's how those coil types use PLR to modulate fluid flow. So it really depends on how AFN uses these global RTF variables to solve the network. The fan would provide an RTF for airflow and these coils would provide an RTF for temp? pressure drop? not sure. I suspect it's a guess either way unless someone dissects AFN to see how these RTF variables are used.
this->m_SuppHeatPartLoadFrac = PartLoadFrac;
this->m_SuppHeatingCycRatio = CycRatio;
this->m_SuppHeatingSpeedRatio = SpeedRatio;
if (this->m_suppHeatCoilType == HVAC::CoilType::HeatingWater || this->m_suppHeatCoilType == HVAC::CoilType::HeatingSteam) {
mdot = PartLoadFrac * this->m_MaxSuppCoilFluidFlow;
PlantUtilities::SetComponentFlowRate(
state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
}
There was a problem hiding this comment.
It looks to me as if this is an indicator of air flow so I am not at all sure why AFN is looking at a coil RTF. What difference would it make on infiltration if a compressor cycled on and off? A fan yes, but a coil? I'm still not sure how/why these coil RTF variables are used.
LoopOnOffFanRunTimeFraction(AirLoopNum) = max(m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF,
m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopOnOffFanRTF,
m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF);
if (AirflowNetworkNodeData(i).AirLoopNum == AirLoopNum) {
RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
}
AirflowNetworkReportData(i).MultiZoneInfiSenGainW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneInfiSenGainJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneInfiSenLossW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneInfiSenLossJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneInfiLatGainW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneInfiLatGainJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneInfiLatLossW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneInfiLatLossJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneVentSenGainW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneVentSenGainJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneVentSenLossW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneVentSenLossJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneVentLatGainW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneVentLatGainJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneVentLatLossW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneVentLatLossJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneMixSenGainW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneMixSenGainJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneMixSenLossW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneMixSenLossJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneMixLatGainW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneMixLatGainJ *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneMixLatLossW *= RepOnOffFanRunTimeFraction;
AirflowNetworkReportData(i).MultiZoneMixLatLossJ *= RepOnOffFanRunTimeFraction;
There was a problem hiding this comment.
I think that it is used to determine the impact of cycling fan operation on the AFN (infiltration, duct leakage, conduction, etc.). For this particular issue, the fact that the runtime fraction was not picked up correctly resulted in these adjustment to not be applicable:
There was a problem hiding this comment.
It looks to me as if this is an indicator of air flow so I am not at all sure why AFN is looking at a coil RTF. What difference would it make on infiltration if a compressor cycled on and off? A fan yes, but a coil?
I agree, fan RTF sounds like a better indicator but it looks like we take the max of coils and fan RTF:
EnergyPlus/src/EnergyPlus/AirflowNetwork/src/Solver.cpp
Lines 9797 to 9799 in 10d33a8
| case HVAC::CoilType::CoolingWater: | ||
| case HVAC::CoilType::CoolingWaterDetailed: | ||
| case HVAC::CoilType::UserDefined: | ||
| case HVAC::CoilType::CoolingDXHXAssisted: |
There was a problem hiding this comment.
Does this need to pick the RTF off of the child coil data structs? Something like this?
case HVAC::CoilType::CoolingDXHXAssisted: {
if (this->m_CoolingCoilIndex > 0) {
auto const &hxCoil = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex);
if (hxCoil.CoolingCoilIndex > 0) {
switch (hxCoil.coolCoilType) {
case HVAC::CoilType::CoolingDX: {
coolingCoilRTF = state.dataCoilCoolingDX->coilCoolingDXs[hxCoil.CoolingCoilIndex].coolingCoilRuntimeFraction;
} break;
case HVAC::CoilType::CoolingDXSingleSpeed: {
coolingCoilRTF = state.dataDXCoils->DXCoil(hxCoil.CoolingCoilIndex).CoolingCoilRuntimeFraction;
} break;
case HVAC::CoilType::CoolingDXVariableSpeed: {
coolingCoilRTF = state.dataVariableSpeedCoils->VarSpeedCoil(hxCoil.CoolingCoilIndex).RunFrac;
} break;
default: {
coolingCoilRTF = this->m_CoolingPartLoadFrac;
} break;
}
}
}There was a problem hiding this comment.
The snippet above isn't tight enough - I'm specifically referring to the CoolingDXHXAssisted branch.
There was a problem hiding this comment.
Yes, that seems like a better approach. I'll push changes.
There was a problem hiding this comment.
@jasondegraw can you give us a lesson in fan RTF vs coil RTF in how AFN uses these vars in the solver? Why does AFN need to know a coil RTF?



Pull request overview
AirLoopHVAC:UnitarySystemin AFN simulation with distribution losses #11490Pull Request Author
Reviewer