Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f5c5103
update doc: HP total heating rate = sum coil heating rate
Jul 26, 2024
03d9070
change FanSpdRatio calculation to use enthalpy difference
Jul 29, 2024
098e584
Fix non-matching HP heating rate and coil total heating rate
Aug 15, 2024
a75d23a
latex label add suffix, revert FanSpdRatioMin change
Aug 16, 2024
6379fdc
Doc update, HP heating rate is coil + piping loss
Aug 16, 2024
f306890
Merge remote-tracking branch 'origin/develop' into fixDocVRFheatpumpH…
Aug 26, 2024
94e3c1f
change to directly use limited TU_HeatingLoad
Aug 29, 2024
ac4911c
revert test idf back to autosize heating cooling air flow TU1
Sep 3, 2024
c9fb07f
Merge remote-tracking branch 'origin/develop' into fixDocVRFheatpumpH…
Sep 3, 2024
94fbca7
Merge remote-tracking branch 'origin/develop' into fixDocVRFheatpumpH…
Oct 8, 2024
3ba669a
Revert "change to directly use limited TU_HeatingLoad"
Oct 9, 2024
303a572
Revert "Fix non-matching HP heating rate and coil total heating rate"
Oct 9, 2024
0ca1aa3
put back check on whether endpoints both positive or negative
Oct 9, 2024
fbcb90c
remov piping loss in coil heating calculation for now
Oct 9, 2024
bc5d7c9
Wrongly removed a line, add back
Oct 9, 2024
6161f8d
add back piping correction to heating coil heating rate
Oct 9, 2024
e1db7ed
revert back the FanSpdRatioMin bound as in develop
Oct 10, 2024
65f2c96
Merge remote-tracking branch 'origin/develop' into fixDocVRFheatpumpH…
Feb 26, 2025
411d96a
Merge remote-tracking branch 'origin/develop' into fixDocVRFheatpumpH…
Feb 26, 2025
4075b7f
revert changes in TotalTUHeatingCapacity,coil pipe correction
Feb 27, 2025
939896c
remove 100W lower bound on coil demand in FanSpdResidualHeat
Feb 27, 2025
0958045
update coil heating rate with latest HP capacity, piping correction
Feb 27, 2025
04a44d2
Merge remote-tracking branch 'origin/develop' into fixDocVRFheatpumpH…
Feb 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions src/EnergyPlus/DXCoils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17326,12 +17326,20 @@ void ControlVRFIUCoil(EnergyPlusData &state,
if (QCoilSenHeatingLoad > QinSenMin1) {
// Modulate fan speed to meet room sensible load; SC is not updated
FanSpdRatioMax = 1.0;
auto f = [QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
return FanSpdResidualHeat(FanSpdRto, QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF);
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);
};
General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
// this will likely cause problems eventually, -1 and -2 mean different things
if (SolFla < 0) Ratio1 = FanSpdRatioMax; // over capacity
if (SolFla < 0) {
if (f(FanSpdRatioMin) <= 0) { // capacity <= demand
Ratio1 = FanSpdRatioMax; // over capacity
} else { // capacity > demand even for the minimum fan speed
Ratio1 = FanSpdRatioMin;
}
}
FanSpdRatio = Ratio1;
CoilOnOffRatio = 1.0;

Expand Down Expand Up @@ -17612,6 +17620,28 @@ Real64 FanSpdResidualHeat(Real64 FanSpdRto, Real64 QCoilSenHeatingLoad, Real64 T
return (TotCap - ZnSenLoad) / ZnSenLoad;
}

Real64 FanSpdResidualHeatUsingH(Real64 FanSpdRto, Real64 QCoilSenHeatingLoad, Real64 RatedAirMassFlowRate, Real64 Tout, Real64 Tin, Real64 Win)
{

// FUNCTION INFORMATION:
// AUTHOR Yujie Xu (yujiex)
// DATE WRITTEN Jul 2024
//
// PURPOSE OF THIS FUNCTION:
// Calculates residual function (desired zone heating load - actual heating coil capacity)
// This is used to modify the fan speed to adjust the coil heating capacity to match
// the zone heating load. This one uses Hin and Hout difference rather than Tin and Tout difference
// like in FanSpdResidualHeat
//
Real64 ZnSenLoad = QCoilSenHeatingLoad;
// +-100 W minimum zone load?
// not sure why this is needed, inherited from FanSpdResidualHeat
// 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;
}

void SetMSHPDXCoilHeatRecoveryFlag(EnergyPlusData &state, int const DXCoilNum)
{

Expand Down
2 changes: 2 additions & 0 deletions src/EnergyPlus/DXCoils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,8 @@ namespace DXCoils {

Real64 FanSpdResidualHeat(Real64 FanSpdRto, Real64 QCoilSenHeatingLoad, Real64 Ts_1, Real64 Tin, Real64 Garate, Real64 BF);

Real64 FanSpdResidualHeatUsingH(Real64 FanSpdRto, Real64 QCoilSenHeatingLoad, Real64 RatedAirMassFlowRate, Real64 Tout, Real64 Tin, Real64 Win);

void SetMSHPDXCoilHeatRecoveryFlag(EnergyPlusData &state, int const DXCoilNum); // must match coil names for the coil type

void SetDXCoilAirLoopNumber(EnergyPlusData &state, std::string const &CoilName, int const AirLoopNum); // must match coil names for the coil type
Expand Down
39 changes: 39 additions & 0 deletions src/EnergyPlus/HVACVariableRefrigerantFlow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,45 @@ void SimulateVRF(EnergyPlusData &state,
if (state.dataHVACVarRefFlow->VRF(VRFCondenser).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
// Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
state.dataHVACVarRefFlow->VRF(VRFCondenser).CalcVRFCondenser_FluidTCtrl(state, FirstHVACIteration);

// update heating coil heating rate with the new OU output and piping correction factor
for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; ++VRFTUNum) {
auto const &thisTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
if (state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCondenser) < Constant::MaxCap) {
auto &heatingCoil = state.dataDXCoils->DXCoil(thisTU.HeatCoilIndex);
Real64 FanSpdRatio;
Real64 OutletAirHumRat;
Real64 OutletAirTemp;
Real64 OutletAirEnthalpy;
Real64 ActualSH;
Real64 ActualSC;
Real64 AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
if (heatingCoil.PartLoadRatio == 0.0) {
AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
}
DXCoils::ControlVRFIUCoil(state,
thisTU.HeatCoilIndex,
state.dataHVACVarRefFlow->VRF(VRFCondenser).TotalHeatingCapacity *
state.dataHVACVarRefFlow->VRF(VRFCondenser).PipingCorrectionHeating,
heatingCoil.InletAirTemp,
heatingCoil.InletAirHumRat,
heatingCoil.CondensingTemp,
AirMassFlowMin,
FanSpdRatio,
OutletAirHumRat,
OutletAirTemp,
OutletAirEnthalpy,
ActualSH,
ActualSC);
Real64 AirMassFlow = FanSpdRatio * heatingCoil.RatedAirMassFlowRate(1); // heating mode
// fixme: temporary remove multiply of coil PLR
heatingCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - heatingCoil.InletAirEnthalpy);
Copy link
Collaborator

@rraustad rraustad Feb 28, 2025

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?

Copy link
Collaborator Author

@yujiex yujiex Feb 28, 2025

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.

image

Copy link
Collaborator

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?

Copy link
Collaborator Author

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;

Copy link
Collaborator

@rraustad rraustad Feb 28, 2025

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?

Copy link
Collaborator

@rraustad rraustad Mar 5, 2025

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;

Copy link
Collaborator

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.

Copy link
Collaborator

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,

Copy link
Collaborator

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?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it did correct for piping loss, but the piping correction factor was computed using the rated capacity, not the actual capacity, so that piping correction is also not right at the time of limitTUCapacity

This issue also happens for cooling mode
image

if (heatingCoil.PartLoadRatio > 0.0) {
heatingCoil.TotalHeatingEnergyRate *= heatingCoil.PartLoadRatio;
}
}
}

} else {
// Algorithm Type: VRF model based on system curve
CalcVRFCondenser(state, VRFCondenser);
Expand Down
Loading