-
Notifications
You must be signed in to change notification settings - Fork 457
Fix VRF Heat Pump Total Heating Rate not match the sum of coil heating rate (with piping loss) #10627
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
base: develop
Are you sure you want to change the base?
Conversation
previously it says HP total heating rate is the sum of air terminal heating rate (which includes supplemental heating coil heating rate). This is wrong for both the curve-based model and FluidTCtrl model. FluidTCtrl model doesn't have an entry to this output field, so one is added.
coil heating rate calculation is like the following AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy) * PartLoadRatio In the computation of fan speed ratio, the coil heating capacity is FanSpdRto * Garate * 1005.0 * (Tout - Tin) The difference between 1005.0 * (Tout - Tin) and (OutletAirEnthalpy - InletAirEnthalpy) can cause mismatches between coil heating rate and heating demand Here we change the fan speed ratio caculation to also use the enthalpy difference way to compute its heating capacity to match the demand
| \paragraph{VRF Heat Pump Total Heating Rate {[}W{]}}\label{vrf-heat-pump-total-heating-rate-w} | ||
|
|
||
| This output field is the operating total heating capacity of the variable refrigerant flow heat pump in Watts. The capacity includes any degradation due to defrost mode. This value is calculated for each HVAC system time step being simulated, and the results are averaged for the time step being reported. This value should match the sum of the individual zone terminal unit output variables for Zone VRF Air Terminal Total Heating Rate. | ||
| This output field is the operating total heating capacity of the variable refrigerant flow heat pump in Watts. The capacity includes any degradation due to defrost mode. This value is calculated for each HVAC system time step being simulated, and the results are averaged for the time step being reported. This value should match the sum of the individual zone terminal unit heating coil output variables for Heating Coil Heating Rate. |
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.
It thought this should say "sum of the individual zone terminal unit heating coil output variables for Heating Coil Heating Rate less any piping loss."
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.
It might just be the total of heating coil heating rate rather than total coil heating rate - piping loss.
in CalcVRFCondenser, vrf.TotalHeatingCapacity (VRF Heat Pump Total Heating Rate output variable) is computed like this
vrf.TotalHeatingCapacity = TotalCondHeatingCapacity * HeatingPLR * CyclingRatio;
And in HeatingPLR is like this
if (TotalCondHeatingCapacity > 0.0) {
HeatingPLR = min(1.0, (TUHeatingLoad / vrf.PipingCorrectionHeating) / TotalCondHeatingCapacity);
} else {
HeatingPLR = 0.0;
}
For normal cases where TotalCondHeatingCapacity > 0.0,
vrf.TotalHeatingCapacity would just be
TotalCondHeatingCapacity * ((TUHeatingLoad / vrf.PipingCorrectionHeating) / TotalCondHeatingCapacity) * CyclingRatio
= TUHeatingLoad / vrf.PipingCorrectionHeating * CyclingRatio
TUHeatingLoad / vrf.PipingCorrectionHeating would be coil heating rate plus the piping loss.
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.
Right, I meant coil heating rates plus piping loss is the output from the outdoor unit.
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.
I see. Sorry I misunderstood earlier. I will modify the description.
|
|
||
| Note: refer to the rdd file after a simulation for exact output variable names | ||
|
|
||
| \paragraph{VRF Heat Pump Total Heating Rate {[}W{]}}\label{vrf-heat-pump-total-heating-rate-w} |
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.
This needs a unique label (there are duplicate label warnings when file changes are viewed in github).
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 catch. I'll add a suffix to it
src/EnergyPlus/DXCoils.cc
Outdated
| Garate = state.dataDXCoils->DXCoil(CoilIndex).RatedAirMassFlowRate(1); | ||
| // why always limit the minimum fan speed ratio to 0.65? | ||
| FanSpdRatioMin = min(max(OAMassFlow / Garate, 0.65), 1.0); // ensure that coil flow rate is higher than OA flow rate | ||
| FanSpdRatioMin = min(max(OAMassFlow / Garate, 0.0), 1.0); // ensure that coil flow rate is higher than OA flow rate |
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.
This seems like a big change, unrelated to the heating rate outputs. Does this branch include some changes from another branch?
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.
I might have left it in by accident. Just reverted it.
| if (std::abs(ZnSenLoad) < 100.0) ZnSenLoad = sign(100.0, ZnSenLoad); | ||
| Real64 Wout = Win; | ||
| Real64 TotCap = FanSpdRto * RatedAirMassFlowRate * (PsyHFnTdbW(Tout, Wout) - PsyHFnTdbW(Tin, Win)); | ||
| return (TotCap - ZnSenLoad) / ZnSenLoad; |
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.
Do you really need to iterate on this? There's only 1 unknown.., FanSpdRto.
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.
I guess not. I will change it to directly calculate FanSpdRto
| Tout = Tin + (Ts_1 - Tin) * (1 - BF); | ||
| Real64 RatedAirMassFlowRate = state.dataDXCoils->DXCoil(CoilIndex).RatedAirMassFlowRate[0]; | ||
| auto f = [QCoilSenHeatingLoad, RatedAirMassFlowRate, Tout, Tin, Win](Real64 FanSpdRto) { | ||
| return FanSpdResidualHeatUsingH(FanSpdRto, QCoilSenHeatingLoad, RatedAirMassFlowRate, Tout, Tin, Win); |
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.
I am not saying to change this but it just seems odd to me when meeting a load to modulate the fan based on suction temperature (which meets the load using air flow) instead of modulating the compressor at some known fan speed. I guess this is an artifact of using VS fan. I would hope in the case of a VS fan that the refrigerant suction T is relatively constant.
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.
It seems that modulating the compressor is at the next step after the calculation of the TU's are finished. In this function, I don't think refrigerant suction temperature changes
| } | ||
| if (this->TUHeatingLoad / this->PipingCorrectionHeating > TotalCondHeatingCapacity) { | ||
| this->TotalHeatingCapacity = this->HeatingCapacityPrev * HeatingPLR * this->PipingCorrectionHeatingPrev; | ||
| } |
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.
TotalHeatingCapacity should match the sum of the TU capacity + piping losses. So isn't it just that? TotalHeatingCapacity = Q_h_TU_PL = TU_HeatingLoad + Pipe_Q_h?
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.
yes, it is matching this.
| autosize, !- Cooling Outdoor Air Flow Rate {m3/s} | ||
| autosize, !- Heating Outdoor Air Flow Rate {m3/s} | ||
| 0, !- Cooling Outdoor Air Flow Rate {m3/s} | ||
| 0, !- Heating Outdoor Air Flow Rate {m3/s} |
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.
Does including OA flow cause a difference between the sum of TU heating capacity + piping losses and condenser total heating capacity?
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.
it does cause some more difference
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.
@rraustad Here is the output file when the heating cooling air flow rate is autosize
eplusout_when heating cooling air flow rate autosize.xlsx
The following is a snapshot sorted with column O in descending order
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.
If L x M = 9083.83288 * 0.98793126 = 8974.2, which closely matches column K at 8973.19993, then why is the TU heating coil "allowed" to provide more than that "max" heating rate? Is the TU heating coil capacity getting limited by the MaxHeatingCapacity variable? I recall discussing that function LimitTUCapacity should include piping losses.
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.
Coil capacity should have been limited. Maybe there's some lingering issues there. I will check on that.
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.
@rraustad I've changed to just using TU_HeatingLoad for this->TotalHeatingCapacity. Now the total "Heating Coil Heating Rate" and the "VRF Heat Pump Total Heating Rate" equals (regardless of whether the "Heating/Cooling Outdoor Air Flow Rate" is autosize or 0). The following are the outputs for these two cases.
eplusout_0 heating cooling air flow.csv
eplusout_autosize heating cooling air flow.csv
The coil capacity is indeed limited. I set the OU evaporative capacity to 5000W (coil capacity is 10023W). Coil heating rate is less than OU capacity at max speed.
|
| \paragraph{VRF Heat Pump Total Heating Rate {[}W{]}}\label{vrf-heat-pump-total-heating-rate-w} | ||
|
|
||
| This output field is the operating total heating capacity of the variable refrigerant flow heat pump in Watts. The capacity includes any degradation due to defrost mode. This value is calculated for each HVAC system time step being simulated, and the results are averaged for the time step being reported. This value should match the sum of the individual zone terminal unit output variables for Zone VRF Air Terminal Total Heating Rate. | ||
| This output field is the operating total heating capacity of the variable refrigerant flow heat pump in Watts. The capacity includes any degradation due to defrost mode. This value is calculated for each HVAC system time step being simulated, and the results are averaged for the time step being reported. This value should match the sum of the individual zone terminal unit heating coil output variables for Heating Coil Heating Rate plus any piping loss. |
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.
This does seem like the correct definition for the VRF heating capacity.
| this->TotalCoolingCapacity = TotalCondCoolingCapacity * CoolingPLR; | ||
| this->TotalHeatingCapacity = TotalCondHeatingCapacity * HeatingPLR; | ||
| // adjustment for matching HP heating rate and coil heating rate | ||
| this->TotalHeatingCapacity = TU_HeatingLoad; |
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.
This is not actually correct. The TU_HeatingLoad is the target (coil load + piping loss) that the model will iterate on to find a solution. The TotalHeatingCapacity is the result. With a tolerance on the iterations these 2 variables should not match. They should be very close (like within 0.001%), but not match. How far off TotalHeatingCapacity is from TU_HeatingLoad tells you how well the model did to calculate the final result. To equate these at the end will hide any issues with the model. TU_HeatingLoad should match exactly with the coil loads + piping loss. TotalHeatingCapacity should represent the refrigerant side heating capacity. Since this model has refrigerant properties could TotalHeatingCapacity = Mdot deltaH on the refrigerant side? Then you would know how well the model did to meet the load.
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.
I see.
I think the piping correction is not consistent in the IU and OU calculation, which might have partly caused the discrepancy. See comment here: #10625 (comment)
There might be other places contributing to it as well. I've been playing around with adjusting stuff but so far I've not been able to figure out how to effectively resolve the discrepancy.
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.
Maybe just revert this one change and revisit how different these 2 results are. TotalHeatingCapacity versus TU_HeatingLoad. Maybe also add another report for refrigerant side capacity?
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.
I will do that
|
Thank you both for the comments this afternoon. I'm going to mark, for now, that this is not going into 24.2. If things get resolved and we agree, we can certainly go ahead and drop it in. But I'm going to change it to focus on other things. |
Hi @Myoldmopar, the current one still can't fix the issue of heat pump heating rate not matching the heating coil heating rate. I think the major thing is in the piping loss correction. But I still can't figure out how it should be fixed. So maybe we can merge in the documentation change first? Do I create a new PR with documentation changes in the new PR? |
|
@yujiex it has been 7 days since this pull request was last updated. |
1 similar comment
|
@yujiex it has been 7 days since this pull request was last updated. |
|
@Myoldmopar I put the documentation update in a new PR (#10957). Maybe we can merge that one in first? I will continue investigating the remaining issues in this PR. |
|
|
@mjwitte and @rraustad I modified the code to update the coil heating rate after the latest piping correction and heat pump capacity is computed. The 100W capacity limit is removed as there was not such a limit on the OU side: if OU was less than 100W or when the piping correction is very low, there will be some coil and OU mismatch. Some details are added in the PR description to explain the fixes. Please see if they make sense. Thanks. |
|
|
@yujiex this looks very close now with very little difference (1E-11) between the TU heating rate and the HP heating rate adjusted for piping losses. Are you finished with this branch? |
@rraustad Mostly finished. I will need to look into the regression diffs in more detail but the list of files that has diffs are reasonable. |
| ActualSC); | ||
| Real64 AirMassFlow = FanSpdRatio * heatingCoil.RatedAirMassFlowRate(1); // heating mode | ||
| // fixme: temporary remove multiply of coil PLR | ||
| heatingCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - heatingCoil.InletAirEnthalpy); |
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.
Why is the parent writing to the child? The parent should call the child and the child should calculate it's own operation. Isn't the child heating coil TotalHeatingEnergyRate here already equal to AirMassFlow * (OutletAirEnthalpy - heatingCoil.InletAirEnthalpy)? i.e., wasn't TotalHeatingEnergyRate set in the child on the call above?
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.
The coil TotalHeatingEnergyRate was set when the demand QCoilReq was calculated with the old piping loss (calculated with rated values) and OU capacity. The following shows the section in the PR description with details on this. 0.986 piping loss used the rated capacity of 7000W in the calculation. So the above is added to recalculate the coil heating rate with the updated piping loss.
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.
When the parent changes the child's TotalHeatingEnergyRate, should the heating coil outlet air condition also change?
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.
oh probably that too. I'll add these to save the updated outlet values
heatingCoil.OutletAirTemp = OutletAirTemp;
heatingCoil.OutletAirHumRat = OutletAirHumRat;
heatingCoil.OutletAirEnthalpy = OutletAirEnthalpy;
heatingCoil.ActualSH = ActualSH;
heatingCoil.ActualSC = ActualSC;
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.
And if the heating coil outlet condition changes, then doesn't the fan speed need to change to meet the same load? And if the fan speed changes doesn't the fan heat also change? This is a good example of why the parent shouldn't update child component performance. Couldn't you just send the piping loss adjusted QCoilReq over to the heating coil?
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.
I don't see piping losses used in LimitCoilCapacity to calculate the limit, if piping losses were used there would that correct the problem?
RemainingCapacity = TotalCapacity * PipingLosses;
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.
When the TU capacity is limited the OU will be running at full load. I think you are saying you don't know the operating full load capacity yet. I think that's OK and the next iteration will include the correct piping losses that were calculated at the end of the previous iteration. I think there will be, within a time step's iteration sequence, a FirstHVACIteration = true, FirstHVACIteration = false, and then a final FirstHVACIteration = false (although I am not positive about this last one happening all the time). So the piping losses should be correct on the second iteration and the final iteration should have the correct answer? I do still think PipingLosses needs to be included in LimitCoilCapacity.
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.
I just checked the calls into LimitCoilCapacity and what is passed in as TotalCapacity is already corrected for piping losses. That makes me wonder what is actually happening for this issue.
TotalTUCoolingCapacity = TotalCondCoolingCapacity * this->PipingCorrectionCooling;
if (TU_CoolingLoad > TotalTUCoolingCapacity) {
LimitTUCapacity(state,
VRFCond,
NumTUInList,
TotalTUCoolingCapacity,
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.
Does this issue only happen in heating mode?
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.
|
@yujiex @Myoldmopar it has been 28 days since this pull request was last updated. |
|
@yujiex @Myoldmopar it has been 29 days since this pull request was last updated. |
|
@yujiex @Myoldmopar it has been 35 days since this pull request was last updated. |
|
@yujiex @Myoldmopar it has been 28 days since this pull request was last updated. |
|
@yujiex @Myoldmopar it has been 28 days since this pull request was last updated. |
|
@yujiex @Myoldmopar it has been 28 days since this pull request was last updated. |
2 similar comments
|
@yujiex @Myoldmopar it has been 28 days since this pull request was last updated. |
|
@yujiex @Myoldmopar it has been 28 days since this pull request was last updated. |






Pull request overview
Details on the fix of heat pump heating rate not matching total heating coil heating rate
The issue of heat pump heating rate not matching total heating coil heating rate, is caused by three factors
FanSpdResidualHeatuses temperature difference (TotCap = FanSpdRto * Garate * 1005.0 * (Tout - Tin)) rather enthalpy difference (TotCap = FanSpdRto * RatedAirMassFlowRate * (PsyHFnTdbW(Tout, Wout) - PsyHFnTdbW(Tin, Win))). This is different from the coil heating rate calculation, causing some mismatches. So a functionFanSpdResidualHeatUsingHis used to compute the capacity instead.after using
FanSpdResidualHeatUsingHin the coil heating rate calculation, the mismatch reduction is as followsthis->HeatingCapacity,this->PipingCorrectionHeating,HeatingPLRare involved in the calculation of VRF heat pump heating rate,this->TotalHeatingCapacity. In each time step,this->HeatingCapacityandthis->PipingCorrectionHeatingis evaluated twice. The coil heating rate calculation uses the values from the first round while the output of heat pump heating rate and piping correction factor uses the values from the second round. By re-evaluating coil heating rate using the updated OU capacity and heating rate, and removing the 100W lower bound on coil heating rate calculation, the difference between the coil heating rate and heat pump heating rate reduced to below 1E-10The following is relevant debugging prints
before fixing
eplusout_develop.csv
after fixing
eplusout_recalcCoilHeat.csv
Regression diffs
Regression diffs happen in four files
Meter diffs happen in
VariableRefrigerantFlow_FluidTCtrl_5Zone.idfandVariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf. It happens in the following fields. It's reasonable as heating coil heating rate is updated in this PR. The magnitude of the maximum percent difference is around 1e-5 to 1e-6.Table diffs happen in
Table diffs are in Coil Total Capacity at Rating Conditions and Coil Sensible Capacity at Rating Conditions for three heating coils, as well as Heating:EnergyTransfer, General:Heating:EnergyTransfer, HeatingCoils:EnergyTransfer, Heating:EnergyTransfer:Zone*. These are also expected as coil heating rate is updated.
ESO output happens in all four files
Take the US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf as example, the Heating Coil Heating Rate is different (0.005 relative diff) as expected. Zone heating demand is relative stable (1e-7 relative diff), the supplemental heating coil heating rate also differs as a result of the heating coil heating rate change. The diffs in cooling rate and related fields are very small (1e-12 relative diff). Heat Pump Terminal Unit Heating Load Rate (0.003 relative diff).
regression diff unfinished
NOTE: ENHANCEMENTS MUST FOLLOW A SUBMISSION PROCESS INCLUDING A FEATURE PROPOSAL AND DESIGN DOCUMENT PRIOR TO SUBMITTING CODE
Pull Request Author
Add to this list or remove from it as applicable. This is a simple templated set of guidelines.
Reviewer
This will not be exhaustively relevant to every PR.