Open yujiex opened 3 months ago
If I remember correctly, for most other zone equipment, the air terminal (or similar) output for cooling and heating is relative to the zone, so it would be net including fan heat effects. Perhaps it's just a documentation issue? Compare with the fancoil outputs to see how they are set up.
If I remember correctly, for most other zone equipment, the air terminal (or similar) output for cooling and heating is relative to the zone, so it would be net including fan heat effects. Perhaps it's just a documentation issue? Compare with the fancoil outputs to see how they are set up.
Sorry I forgot the fan heat gain in the comparison with the air terminal. I just updated it. Now the air terminal exactly matches the coil + supp heating coil heating rate + fan heat gain. The problem now is the sum of all air terminals (only 1 here) doesn't match the heat pump total heating rate (the orange line). @mjwitte
"VRF Heat Pump Total Heating Rate" should match the total of the VRF heating coil heating rates. It's close, but the heat pump value is slightly larger than the coil output. Are there any line losses in this model that might explain the difference?
"VRF Heat Pump Total Heating Rate" should match the total of the VRF heating coil heating rates. It's close, but the heat pump value is slightly larger than the coil output. Are there any line losses in this model that might explain the difference?
I see. The documentation should probably be updated.
I checked why the coil heating rate and heat pump heating rate is different, there are two factors
LimitTUCapacity function
uses TotalTUHeatingCapacity
, which is TotalCondHeatingCapacity
multiplied by piping correction factor. TotalCondHeatingCapacity
equals heat pump heating rate
TotalTUHeatingCapacity = TotalCondHeatingCapacity * this->PipingCorrectionHeating;
ControlVRFIUCoil
, the following chunk solves the fan speed ratio by matching this to coil demand: FanSpdRto Garate 1005.0 (Tout - Tin). However the final coil heating rate is calculated as
`thisDXCoil.TotalHeatingEnergyRate = AirMassFlow (OutletAirEnthalpy - InletAirEnthalpy) PartLoadRatio;There are some differences in
FanSpdRto Garate 1005.0 (Tout - Tin)and
AirMassFlow (OutletAirEnthalpy - InletAirEnthalpy) PartLoadRatio` auto f = [QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
return FanSpdResidualHeat(FanSpdRto, QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF);
};
The following are some relevant code chunks regarding how the piping loss gets involved in the coil heating rate calculation.
// state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) is computed here
LimitTUCapacity(state,
VRFCond,
NumTUInList,
TotalTUHeatingCapacity,
state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond),
TotalTUCoolingCapacity,
state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond));
...
SimDXCoil(state,
"",
HVAC::CompressorOp::Off,
FirstHVACIteration,
this->HeatCoilIndex,
fanOp,
PartLoadRatio,
OnOffAirFlowRatio,
_,
state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
...
// from the above, the MaxCap here in CalcVRFHeatingCoil_FluidTCtrl is state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond)
void SimDXCoil(EnergyPlusData &state,...,MaxCap,...) {
CalcVRFHeatingCoil_FluidTCtrl(state, compressorOp, DXCoilNum, PartLoadRatio, fanOp, _, MaxCap);
}
void CalcVRFHeatingCoil_FluidTCtrl() {
...
if (present(MaxHeatCap)) {
TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
TotCap = min(MaxHeatCap, TotCap);
} else {
TotCapAdj = TotCap * HeatingCapacityMultiplier;
}
QCoilReq = PartLoadRatio * TotCap;
...
ControlVRFIUCoil(state,
DXCoilNum,
QCoilReq,
thisDXCoil.InletAirTemp,
thisDXCoil.InletAirHumRat,
thisDXCoil.CondensingTemp,
AirMassFlowMin,
FanSpdRatio,
OutletAirHumRat,
OutletAirTemp,
OutletAirEnthalpy,
ActualSH,
ActualSC);
AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
...
thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy) * PartLoadRatio;
}
@mjwitte
In the corresponding (PR)[https://github.com/NREL/EnergyPlus/pull/10627], in addition to the documentation update, I have changed the fan speed ratio solver to use enthalpy difference instead of temperature difference. This addresses the second factor in the comment above that contributed to the difference between heating coil heating rate and heat pump heating rate.
With this, I would anticipate the VRF HEAT PUMP:VRF Heat Pump Total Heating Rate
output multiplied by the VRF HEAT PUMP:VRF Heat Pump Indoor Unit Piping Correction for Heating
to match the output TU1 VRF DX HEATING COIL:Heating Coil Heating Rate
output. However, they still don't quite match. The following the result table with some summary stats.
This is because the reported piping correction is different from the ones used in the calculation.
The following is the heating coil heating rate calculation
Here we can see the piping correction is computed when the system is at the highest capacity (rated capacity)
The reported piping correction is recomputed using the updated TotalTUHeatingCapacity
value.
The following are some relevant code snippets
thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy) * PartLoadRatio;
// OutletAirEnthalpy and FanSpdRatio are calculated here
ControlVRFIUCoil(state,
DXCoilNum,
QCoilReq,
thisDXCoil.InletAirTemp,
thisDXCoil.InletAirHumRat,
thisDXCoil.CondensingTemp,
AirMassFlowMin,
FanSpdRatio,
OutletAirHumRat,
OutletAirTemp,
OutletAirEnthalpy,
ActualSH,
ActualSC);
AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
// In normal operation thisDXCoil.TotalHeatingEnergyRate should match the demand, QCoilReq. We'll just look at how QCoilReq is determined
// QCoilReq is computed here
QCoilReq = PartLoadRatio * TotCap;
// TotCap is either the rated capacity, or limited by MaxHeatCap
TotCap = thisDXCoil.RatedTotCap(Mode);
if (present(MaxHeatCap)) {
TotCap = min(MaxHeatCap, TotCap);
}
// MaxHeatCap is computed in this function, and stored here. The important input is `TotalTUHeatingCapacity`.
// For the simple case here where there's 1 TU and 1 OU, then `TotalTUHeatingCapacity` would be the coil capacity limit
if (TU_HeatingLoad > TotalTUHeatingCapacity) {
LimitTUCapacity(state,
VRFCond,
NumTUInList,
TotalTUHeatingCapacity,
state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond),
TotalTUCoolingCapacity,
state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond));
}
...
TotalCondHeatingCapacity = this->HeatingCapacity;
TotalTUHeatingCapacity = TotalCondHeatingCapacity * this->PipingCorrectionHeating;
I would think that "VRF Heat Pump Total Heating Rate" (a refrigerant side measure) would equal the sum of the TUs "VRF heating coil heating rates" (an air-side measure equal to refrigerant side heat transfer) and include piping losses. This data gets within 10 W so there is something not quite lining up. Is that a result of the component model converging?
@rraustad from the above analysis of a few timestamps at the beginning of the simulation, it seems to me the difference after unifying the second bullet point in (this comment)[https://github.com/NREL/EnergyPlus/issues/10625#issuecomment-2253477353]), is because of the piping correction used in the calculation of QCoilReq (equal to coil heating rate during these few time steps) is at the rated condition (rated capacity / (rated capacity + piping loss)) while the reported piping correction uses the actual condition (total coil heating rate / (total coil heating rate + piping loss)
Does this difference happen only when the TU capacity is being limited? Or all the time? See output "VRF Heat Pump Maximum Capacity Cooling (Heating) Rate".
The difference is very small (1e-11 level) when the TU capacity is not limited (filter by colume K = L being false)
I'm not sure what K = L means. I asked because I did not see piping losses being used in the LimitTUCapacity calculations.
OK, I see. If I compare column P with G I see they match when the TU coil capacity is not limited. I would look at including piping losses in the calculations for LimitTUCapacity.
It looks like piping losses are accounted for. So now I'm not sure why this is happening only when the TU capacity is limited. does MaxHeatingCapacity include piping losses?
TotalTUCoolingCapacity = TotalCondCoolingCapacity * this->PipingCorrectionCooling;
TotalTUHeatingCapacity = TotalCondHeatingCapacity * this->PipingCorrectionHeating;
LimitTUCapacity(state,
VRFCond,
NumTUInList,
TotalTUHeatingCapacity,
state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond),
TotalTUCoolingCapacity,
state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond));
MaxHeatingCapacity should have included piping loss. For a simple 1-TU-1-OU configuration, I believe the MaxHeatingCapacity would just be the TotalTUHeatingCapacity
.
I think if you adjust MaxHeating/CoolingCapacity by piping losses the difference will be resolved. I guess you would do that inside the LimitTUCapacity function since this variable is an output report.
this->HeatingCapacity =
this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, Tsuction) +
this->RatedCompPower * CurveValue(state,
this->OUCoolingPWRFT(NumOfCompSpdInput),
Tdischarge,
Tsuction); // Include the piping loss, at the highest compressor speed
this->PipingCorrectionHeating = TU_HeatingLoad_actual / (TU_HeatingLoad_actual + Pipe_Q_h);
state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) =
this->HeatingCapacity; // for report, maximum condensing capacity the system can provide
I'm not sure I understand. So state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond)
is calculated in LimitTUCapacity
. TotalTUHeatingCapacity
has considered piping loss, so state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond)
should have considered piping loss as well.
if (TU_HeatingLoad > TotalTUHeatingCapacity) {
LimitTUCapacity(state,
VRFCond,
NumTUInList,
TotalTUHeatingCapacity,
state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond),
TotalTUCoolingCapacity,
state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond));
}
and it is used in coil calculation as the capacity limit
SimDXCoil(state,
"",
HVAC::CompressorOp::On,
FirstHVACIteration,
this->HeatCoilIndex,
fanOp,
PartLoadRatio,
_,
_,
state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
Or do you mean I should use un-adjust it and use the state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond)) / this->PipingCorrectionHeating
in SimDXCoil?
All I know is something is wrong when the model limits TU coil capacity. It seems odd to pass the system limit, MaxHeatingCapacity(VRFCond), to the coil. I would think a coil capacity limit should be passed to the coil. For a 1 TU example file these are the same but for a 5 TU example file a single coil would likely never exceed the total system capacity (unless only 1 coil was operating).
This MaxHeatingCapacity(VRFCond)
is TU limit, and there's 1 coil for the TU, so acting like a coil limit too? This is the diagram from the engineering reference.
OK, so maybe MaxHeatingCapacity(VRFCond) is the coil limit. Try multiplying by the piping losses to see if that fixes this. If not then I am not sure where else to look.
Just tried it, this is the output. Still very different
Is it just coincidence that the diff in column O is about the same as column L (1- column M) ? 6561.52 (1 - 0.98269556) = 113.3 vs column O at 111.9.
This is a side note, but I recall something @Nigusse fixed about using COP in calculations in cooling (1 + ) vs heating (1 - ) here:
if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) {
if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
RemainingCapacity = StartingCapacity * (1 + 1 / state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCOP);
if (AltCapacity > RemainingCapacity) {
LimitCoilCapacity(NumTUInList, RemainingCapacity, AltArray, AltLimit);
}
}
if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
RemainingCapacity = StartingCapacity / (1 + 1 / state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCOP);
if (AltCapacity > RemainingCapacity) {
LimitCoilCapacity(NumTUInList, RemainingCapacity, AltArray, AltLimit);
}
}
}
Is it just coincidence that the diff in column O is about the same as column L (1- column M) ? 6561.52 (1 - 0.98269556) = 113.3 vs column O at 111.9.
actually Column K * Column M now is very close to column G now, except for three large values. btw my runperiod is 1/1 to 1/10
It looks like the TU coil capacity is limited for those 3 rows (i.e., K = L).
looks like there might still be something related to the TU coil capacity being limited
Issue overview
In PR 10331, we fixed the mismatch between heating coil heating rate + supplemental heating rate and the air terminal heating rate. Now that this is fixed, however, the "Zone VRF Air Terminal Total Heating Rate" and "VRF Heat Pump Total Heating Rate" starts to show mismatches. Currently, "VRF Heat Pump Total Heating Rate" is very close to the coil heating rate itself, and is smaller than "Zone VRF Air Terminal Total Heating Rate". According to the documentation, "VRF Heat Pump Total Heating Rate" should match the sum of "Zone VRF Air Terminal Total Heating Rate" ("This value should match the sum of the individual zone terminal unit output variables for Zone VRF Air Terminal Total Heating Rate.")
Defect file
The following zip file contains the idf and epw defect file.zip This is the eplusout.csv output eplusout_7000W capacity.xlsx
Details
Some additional details for this issue (if relevant):
Checklist
Add to this list or remove from it as applicable. This is a simple templated set of guidelines.