Skip to content
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

VRF FluidTCtrl heat pump total heating rate doesn't match zone VRF air terminal total heating rate #10625

Open
2 of 3 tasks
yujiex opened this issue Jul 26, 2024 · 24 comments · May be fixed by #10627
Open
2 of 3 tasks
Assignees
Labels
Defect Includes code to repair a defect in EnergyPlus Documentation Related primarily on the LaTeX-based EnergyPlus documentation

Comments

@yujiex
Copy link
Collaborator

yujiex commented Jul 26, 2024

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.")

image

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):

  • Platform (Operating system, version)
  • Version of EnergyPlus (if using an intermediate build, include SHA)
  • Unmethours link or helpdesk ticket number

Checklist

Add to this list or remove from it as applicable. This is a simple templated set of guidelines.

  • Defect file added (list location of defect file here)
  • Ticket added to EnergyPlus Defect Complexity (Github Project)
  • Pull request created (the pull request will have additional tasks related to reviewing changes that fix this defect)
@yujiex yujiex self-assigned this Jul 26, 2024
@mjwitte
Copy link
Contributor

mjwitte commented Jul 26, 2024

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.

@yujiex
Copy link
Collaborator Author

yujiex commented Jul 26, 2024

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

image

@mjwitte
Copy link
Contributor

mjwitte commented Jul 26, 2024

"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?

@yujiex
Copy link
Collaborator Author

yujiex commented Jul 26, 2024

"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

  • piping loss: LimitTUCapacity function uses TotalTUHeatingCapacity, which is TotalCondHeatingCapacity multiplied by piping correction factor. TotalCondHeatingCapacity equals heat pump heating rate
        TotalTUHeatingCapacity = TotalCondHeatingCapacity * this->PipingCorrectionHeating;
  • difference in solving for fan speed ratio and in calculating coil heating rate: inside 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

@yujiex yujiex added Defect Includes code to repair a defect in EnergyPlus Documentation Related primarily on the LaTeX-based EnergyPlus documentation labels Jul 27, 2024
@yujiex
Copy link
Collaborator Author

yujiex commented Aug 9, 2024

In the corresponding (PR)[https://github.com//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.

image

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
image

Here we can see the piping correction is computed when the system is at the highest capacity (rated capacity)
image

The reported piping correction is recomputed using the updated TotalTUHeatingCapacity value.
image

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;

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

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?

@yujiex
Copy link
Collaborator Author

yujiex commented Aug 9, 2024

@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//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)

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

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

@yujiex
Copy link
Collaborator Author

yujiex commented Aug 9, 2024

The difference is very small (1e-11 level) when the TU capacity is not limited (filter by colume K = L being false)

image

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

I'm not sure what K = L means. I asked because I did not see piping losses being used in the LimitTUCapacity calculations.

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

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.

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

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));

@yujiex
Copy link
Collaborator Author

yujiex commented Aug 9, 2024

MaxHeatingCapacity should have included piping loss. For a simple 1-TU-1-OU configuration, I believe the MaxHeatingCapacity would just be the TotalTUHeatingCapacity.

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

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

@yujiex
Copy link
Collaborator Author

yujiex commented Aug 9, 2024

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?

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

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

@yujiex
Copy link
Collaborator Author

yujiex commented Aug 9, 2024

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.

image

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

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.

@yujiex
Copy link
Collaborator Author

yujiex commented Aug 9, 2024

Just tried it, this is the output. Still very different

image

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

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.

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

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);
        }
    }
}

@yujiex
Copy link
Collaborator Author

yujiex commented Aug 9, 2024

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

image

eplusout.csv

@rraustad
Copy link
Contributor

rraustad commented Aug 9, 2024

It looks like the TU coil capacity is limited for those 3 rows (i.e., K = L).

@yujiex
Copy link
Collaborator Author

yujiex commented Aug 10, 2024

looks like there might still be something related to the TU coil capacity being limited

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Defect Includes code to repair a defect in EnergyPlus Documentation Related primarily on the LaTeX-based EnergyPlus documentation
Projects
None yet
3 participants