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

Fix VRFFluidCtrl cooling cycling issue by moving cycling ratio calc in compressor spd calc #10353

Merged
merged 38 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ba0d9f4
move cycling ratio calculation inside compressor spd calc
yujiex Jan 4, 2024
5d582f0
move cycling into compressor speed calculation
Jan 23, 2024
fa3e488
change outdoor unit evap temperature threshold
Jan 23, 2024
452e53b
overwrite indoor Te withoutdoor adjusted Te
Jan 24, 2024
7bb2e4b
Merge remote-tracking branch 'origin/vrfFluidCtrlFixCoolingCycling' i…
Jan 25, 2024
d23a27a
Merge remote-tracking branch 'origin/develop' into vrfFluidCtrlFixCoo…
Jan 31, 2024
25ffe67
overwrite IU Te, coil RTF update
Feb 7, 2024
6539294
Only overwrite Coil RTF when in cooling mode
Feb 7, 2024
3601caa
ncomp calc need to multiply cycling ratio
Feb 26, 2024
00d8f25
Merge remote-tracking branch 'origin/develop' into vrfFluidCtrlFixCoo…
Mar 6, 2024
68fb801
update Te and RTF only happens in the FluidTCtrl model
Mar 6, 2024
96f9e2c
test idf for different min speed level, will remove later
Mar 7, 2024
ecb2ae0
account for cycling ratio in condenser heat release
Mar 7, 2024
7acd424
test case for VRFOU_CalcCompC low load cycling
Mar 7, 2024
84141c6
OUCondHeatRelease = Ncomp + Cap_Eva1 * CyclingRatio;
Mar 8, 2024
a8cef58
Revert "test idf for different min speed level, will remove later"
Mar 8, 2024
7a38358
remove name tag in the comments
Mar 8, 2024
636853b
fix unit test
Mar 9, 2024
257253d
move cycling ratio after the two goto labels
Mar 9, 2024
d5095be
move IU Te and RTF updates into CalcVRFCondenser_FluidTCtrl
Mar 11, 2024
a07d452
make tolerance constexpr
Mar 11, 2024
88136a1
split -1 and -2 cases in SolveRoot in CalcCompC
Mar 11, 2024
0e0ae71
use Cap_Eva0 / Cap_Eva1 to compute CyclingRatio
Mar 11, 2024
5920cac
add Cap_Eva1 >= Cap_Eva0 check and fix unit test
Mar 12, 2024
b2e0cfe
pull develop and merge conflict
dareumnam Jun 13, 2024
1b66089
Merge remote-tracking branch 'origin/develop' into vrfFluidCtrlFixCoo…
Jun 25, 2024
3e0fb35
Merge remote-tracking branch 'origin/develop' into vrfFluidCtrlFixCoo…
Jun 25, 2024
8ba4828
Merge branch 'vrfFluidCtrlFixCoolingCycling' of https://github.com/NR…
Jun 25, 2024
d3fb4a8
Merge remote-tracking branch 'origin/develop' into vrfFluidCtrlFixCoo…
Jun 27, 2024
820765a
remove temporary testfiles
Jul 22, 2024
6253ece
Merge remote-tracking branch 'origin/develop' into vrfFluidCtrlFixCoo…
Jul 22, 2024
f4c425b
Merge remote-tracking branch 'origin/develop' into vrfFluidCtrlFixCoo…
Jul 24, 2024
1c35238
change default value of MaxHeat(Cool)ingCapacity to MaxCap
Sep 4, 2024
acb84a0
Revert "change default value of MaxHeat(Cool)ingCapacity to MaxCap"
Sep 4, 2024
7f84730
Merge remote-tracking branch 'origin/develop' into vrfFluidCtrlFixCoo…
Sep 5, 2024
08eb126
fix unit test
Sep 5, 2024
eb4bc0e
Merge develop; resolve conflicts
Myoldmopar Sep 10, 2024
5907d73
Merge remote-tracking branch 'origin/develop' into vrfFluidCtrlFixCoo…
Myoldmopar Sep 10, 2024
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
151 changes: 91 additions & 60 deletions src/EnergyPlus/HVACVariableRefrigerantFlow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ 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);
state.dataHVACVarRefFlow->VRF(VRFCondenser).CalcVRFCondenser_FluidTCtrl(state, FirstHVACIteration);
} else {
// Algorithm Type: VRF model based on system curve
CalcVRFCondenser(state, VRFCondenser);
Expand Down Expand Up @@ -11010,7 +11010,7 @@ void VRFTerminalUnitEquipment::CalcVRFIUVariableTeTc(EnergyPlusData &state,
}
}

void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state)
void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state, const bool FirstHVACIteration)
{

// SUBROUTINE INFORMATION:
Expand Down Expand Up @@ -11141,7 +11141,7 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state)
Real64 Pipe_DeltP_h; // Piping Loss Algorithm Parameter: Pipe pressure drop (h) [Pa]
Real64 Pipe_Q_c; // Piping Loss Algorithm Parameter: Heat loss (c) [W]
Real64 Pipe_Q_h; // Piping Loss Algorithm Parameter: Heat loss (h) [W]
Real64 Q_c_TU_PL; // Cooling load to be met at heating mode, including the piping loss(W)
Real64 Q_c_TU_PL; // Cooling load to be met at cooling mode, including the piping loss(W)
Real64 Q_h_TU_PL; // Heating load to be met at heating mode, including the piping loss (W)
Real64 Q_h_OU; // outdoor unit condenser heat release (cooling mode) [W]
Real64 Q_c_OU; // outdoor unit evaporator heat extract (heating mode) [W]
Expand Down Expand Up @@ -11419,56 +11419,40 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state)
C_cap_operation = this->VRFOU_CapModFactor(
state, h_comp_in, h_IU_evap_in, max(min(Psuction, RefPHigh), RefPLow), Tsuction + SH_Comp, Tsuction + 8, CapMinTc - 5);

if (Q_c_TU_PL * C_cap_operation < CompEvaporatingCAPSpdMin) {
// Required cooling load is less than the min cooling capacity, on-off strategy

this->VRFOperationSimPath = 11;

CyclingRatio = Q_c_TU_PL * C_cap_operation / CompEvaporatingCAPSpdMin;
double CyclingRatioFrac = 0.85 + 0.15 * CyclingRatio;
double HPRTF = CyclingRatio / CyclingRatioFrac;
Ncomp = CompEvaporatingPWRSpdMin * HPRTF; //
CompSpdActual = this->CompressorSpeed(1); //
this->CondensingTemp = CapMinTc; //

} else {
// Required cooling load is greater than or equal to the min cooling capacity
// Iteration_Ncomp: Perform iterations to calculate Ncomp (Label10)
Counter = 1;
Ncomp = TU_CoolingLoad / this->CoolingCOP;
Ncomp_new = Ncomp;
Label10:;
Q_h_OU = Q_c_TU_PL + Ncomp_new; // Ncomp_new may be updated during Iteration_Ncomp Label10

// *VRF OU TeTc calculations
m_air = this->OUAirFlowRate * RhoAir;
SC_OU = this->SC;
this->VRFOU_TeTc(state, HXOpMode::CondMode, Q_h_OU, SC_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->CondensingTemp);
this->CondensingTemp = min(CapMaxTc, this->CondensingTemp);
this->SC = SC_OU;

// *VEF OU Compressor Simulation at cooling mode: Specify the compressor speed and power consumption
this->VRFOU_CalcCompC(state,
TU_CoolingLoad,
Tsuction,
this->CondensingTemp,
Psuction,
T_comp_in,
h_comp_in,
h_IU_evap_in,
Pipe_Q_c,
CapMaxTc,
Q_h_OU,
CompSpdActual,
Ncomp,
CyclingRatio);

// Iteration_Ncomp: Perform iterations to calculate Ncomp (Label10)
Counter = 1;
Ncomp = TU_CoolingLoad / this->CoolingCOP;
if ((std::abs(Ncomp - Ncomp_new) > (Tolerance * Ncomp_new)) && (Counter < 30)) {
Ncomp_new = Ncomp;
Label10:;
Q_h_OU = Q_c_TU_PL + Ncomp_new; // Ncomp_new may be updated during Iteration_Ncomp Label10

// *VRF OU TeTc calculations
m_air = this->OUAirFlowRate * RhoAir;
SC_OU = this->SC;
this->VRFOU_TeTc(
state, HXOpMode::CondMode, Q_h_OU, SC_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->CondensingTemp);
this->CondensingTemp = min(CapMaxTc, this->CondensingTemp);
this->SC = SC_OU;

// *VEF OU Compressor Simulation at cooling mode: Specify the compressor speed and power consumption
this->VRFOU_CalcCompC(state,
TU_CoolingLoad,
Tsuction,
this->CondensingTemp,
Psuction,
T_comp_in,
h_comp_in,
h_IU_evap_in,
Pipe_Q_c,
CapMaxTc,
Q_h_OU,
CompSpdActual,
Ncomp);

if ((std::abs(Ncomp - Ncomp_new) > (Tolerance * Ncomp_new)) && (Counter < 30)) {
Ncomp_new = Ncomp;
Counter = Counter + 1;
goto Label10;
}
Counter = Counter + 1;
goto Label10;
}

// Update h_IU_evap_in in iterations Label12
Expand All @@ -11490,6 +11474,8 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state)
}

// Key outputs of this subroutine
Ncomp *= CyclingRatio;
Q_h_OU *= CyclingRatio;
Copy link
Contributor

Choose a reason for hiding this comment

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

Ncomp is power. Ncomp should multiply by RTF.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

RTF was calculated later in the function. Should I follow this code and compute RTF here so that RTF is accessible here? Also I'm not sure why it is written like this instead of VRFRTF = min(1.0, CyclingRatio)

    VRFRTF = 0.0;
    // VRF Cooling and Heating Electric Power (output variables)
    if (this->OperatingMode == ModeCoolingOnly) {
        PartLoadFraction = 1.0;
        VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));

        this->ElecCoolingPower = state.dataHVACVarRefFlow->VRF(VRFCond).Ncomp + this->OUFanPower;
        this->ElecHeatingPower = 0;

    } else if (this->OperatingMode == ModeHeatingOnly) {
        PartLoadFraction = 1.0;
        VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));

        this->ElecCoolingPower = 0;
        this->ElecHeatingPower = this->Ncomp + this->OUFanPower;

    } else if (this->OperatingMode == ModeCoolingAndHeating) {
        PartLoadFraction = 1.0;
        VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));

        this->ElecCoolingPower = (this->Ncomp + this->OUFanPower) * this->IUEvapHeatRate / (this->IUCondHeatRate + this->IUEvapHeatRate);
        this->ElecHeatingPower = (this->Ncomp + this->OUFanPower) * this->IUCondHeatRate / (this->IUCondHeatRate + this->IUEvapHeatRate);

    } else {
        this->ElecCoolingPower = 0;
        this->ElecHeatingPower = 0;
    }
    this->VRFCondRTF = VRFRTF;

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know why it's written like this either. This is in the heat recovery code so maybe it is assumed the compressor runs the entire time step. Don't use this code without modifying PartLoadFraction = 1.0;. PLF needs to be calculated from the performance curve as a function of CyclingRatio as PartLoadFraction = max(0.7, CurveValue(state, vrf.CoolPLFFPLR, CyclingRatio));.

RTF = PLR/PLF. For VRF CyclingRatio is PLR so RTF = CyclingRatio/PLF.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In the component or physics-based VRF model, the OU doesn't have a curve for part load fraction. The available curves are the following

  • Outdoor Unit Evaporating Temperature Function of Superheating Curve Name
  • Outdoor Unit Condensing Temperature Function of Subcooling Curve Name
  • Defrost Energy Input Ratio Modifier Function of Temperature Curve Name
  • Loading Index i Evaporative Capacity Multiplier Function of Temperature Curve Name
  • Loading Index i Compressor Power Multiplier Function of Temperature Curve Name

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, so there is no cycling/start-up losses in this model. Using CyclingRatio is OK here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

right.

this->CompActSpeed = max(CompSpdActual, 0.0);
this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; // 0.95 is the efficiency of the compressor inverter, can come from IDF //@minor
this->OUFanPower = this->RatedOUFanPower; //@ * pow_3( CondFlowRatio )
Expand Down Expand Up @@ -11975,7 +11961,7 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state)

this->HeatingCapacity = 0.0; // Include the piping loss
this->PipingCorrectionHeating = 1.0; // 1 means no piping loss
state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) = MaxCap; // yujie: default value is MaxCap = 1e+20, not 0
state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) = MaxCap; // default value is MaxCap = 1e+20, not 0

this->CoolingCapacity = 0.0; // Include the piping loss
this->PipingCorrectionCooling = 1.0;
Expand Down Expand Up @@ -12348,6 +12334,25 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state)

// Calculate the IU Te/Tc for the next time step
this->CalcVRFIUTeTc_FluidTCtrl(state);
// update coil and IU evaporating temperature, also keep coil RTF updated with the condenser side cycling ratio, for the FluidTCtrl model
for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; ++VRFTUNum) {
auto const &thisTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
auto &coolingCoil = state.dataDXCoils->DXCoil(thisTU.CoolCoilIndex);
if (this->adjustedTe && (!FirstHVACIteration)) {
coolingCoil.EvaporatingTemp = this->EvaporatingTemp;
this->IUEvaporatingTemp = this->EvaporatingTemp;
}

int PLF;
if (coolingCoil.PLFFPLR(1) > 0 && this->VRFCondCyclingRatio < 1.0) {
PLF = Curve::CurveValue(state, coolingCoil.PLFFPLR(1), this->VRFCondCyclingRatio); // Calculate part-load factor
} else {
PLF = 1.0;
}
if (coolingCoil.TotalCoolingEnergyRate > 0.0) {
coolingCoil.CoolingCoilRuntimeFraction = this->VRFCondCyclingRatio / PLF;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see CoolingCoilRuntimeFraction getting set to 0 anywhere. So if TotalCoolingEnergyRate = 0, then CoolingCoilRuntimeFraction will be used from the last time step the compressor operated. I would set CoolingCoilRuntimeFraction = 0.0 in Init.

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 is set to 0 in this function: CalcVRFCoolingCoil_FluidTCtrl

    // Initialize coil air side parameters
    CondInletTemp = 0.0;
    CondInletHumRat = 0.0;
    AirMassFlow = thisDXCoil.InletAirMassFlowRate;
    InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
    InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
    InletAirHumRat = thisDXCoil.InletAirHumRat;
    state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
    thisDXCoil.CoolingCoilRuntimeFraction = 0.0;

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I see. This is updating the coil model RTF, from the parent object. We should not do that. So why did you have to update the coil RTF? VRFCondCyclingRatio is already passed to SimDXCoil so the coil RTF should already be accurate, if that call is passing the updated cycling ratio.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The condenser side cycling ratio is updated in CalcVRFCondenser_FluidTCtrl. This took place after SimDXCoil, so the coil RTF is updated here to keep up with the updated condenser side cycling ratio

}
}

void VRFTerminalUnitEquipment::ControlVRF_FluidTCtrl(EnergyPlusData &state,
Expand Down Expand Up @@ -13847,14 +13852,16 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state,
Real64 MaxOutdoorUnitTc, // The maximum temperature that Tc can be at heating mode [C]
Real64 &OUCondHeatRelease, // Condenser heat release (cooling mode) [W]
Real64 &CompSpdActual, // Actual compressor running speed [rps]
Real64 &Ncomp // Compressor power [W]
Real64 &Ncomp, // Compressor power [W]
Real64 &CyclingRatio // Cycling Ratio [W]
)
{

// SUBROUTINE INFORMATION:
// AUTHOR Xiufeng Pang
// DATE WRITTEN Feb 2014
// MODIFIED Rongpeng Zhang, Jan 2016
// MODIFIED Yujie Xu, Sep 2023
// RE-ENGINEERED na

// PURPOSE OF THIS SUBROUTINE:
Expand Down Expand Up @@ -13910,7 +13917,8 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state,
Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
Real64 T_discharge_new; // Condensing temperature, for temporary use in iterations [C]
Real64 Tfs; // Temperature of the air at the coil surface [C]]
Real64 Tolerance(0.05); // Tolerance for condensing temperature calculation [C}
Real64 constexpr Tolerance(0.05); // Tolerance for condensing temperature calculation [C]
Real64 constexpr TeTol(0.5); // Tolerance for the difference between Te and SmallLoadTe
Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]

Expand Down Expand Up @@ -13939,6 +13947,7 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state,
C_cap_operation = this->VRFOU_CapModFactor(
state, Pipe_h_comp_in, Pipe_h_IU_in, max(min(P_suction, RefPHigh), RefPLow), T_suction + Modifi_SH, T_suction + 8, T_discharge - 5);

this->adjustedTe = false;
for (CounterCompSpdTemp = 1; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
// Iteration to find the VRF speed that can meet the required load, Iteration DoName1

Expand Down Expand Up @@ -13987,14 +13996,26 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state,
MinRefriPe = this->refrig->getSatPressure(state, -15, RoutineName);
MinOutdoorUnitPe = max(P_discharge - this->CompMaxDeltaP, MinRefriPe);
MinOutdoorUnitTe = this->refrig->getSatTemperature(state, max(min(MinOutdoorUnitPe, RefPHigh), RefPLow), RoutineName);
// Te can't be smaller than user input lower bound
MinOutdoorUnitTe = max(this->IUEvapTempLow, MinOutdoorUnitTe);

auto f = [&state, T_discharge_new, CondHeat, CAPFT](Real64 const T_suc) {
return CompResidual_FluidTCtrl(state, T_discharge_new, CondHeat, CAPFT, T_suc);
};

General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, SmallLoadTe, f, MinOutdoorUnitTe,
T_suction); // SmallLoadTe is the updated Te'
if (SolFla < 0) SmallLoadTe = 6; // MinOutdoorUnitTe; //SmallLoadTe( Te'_new ) is constant during iterations
Copy link
Contributor

Choose a reason for hiding this comment

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

This is poor logic for a SolveRoot failure. -1 means iteration limit exceeded and -2 means it can't find a solution. Using SolFla < 0 captures both and assumes there is a small load. Maybe this works, maybe it doesn't, I don't know. This is a separate issue, if this is actually an issue.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I will separate out SolFla=-1 and SolFla=-2 case. When it is -1 I will throw an error message of not reaching convergence. When it is -2, it would be the case where the load is small.

In the -2 case, f(MinOutdoorUnitTe) and f(T_suction) can't be both positive as f(T_suction) > 0 would mean

Q_evap_req * C_cap_operation / this->RatedEvapCapacity > CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction)

, which is

Q_evap_req * C_cap_operation > this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction)

If this is the case, it shouldn't have been in if (Q_evap_req * C_cap_operation <= CompEvaporatingCAPSpd(CounterCompSpdTemp)) {

T_suction); // SmallLoadTe is the updated Te'
if (SolFla == -1) {
// show error not converging
ShowWarningMessage(state, format("{}: low load Te adjustment failed for {}", RoutineName, this->Name));
ShowContinueErrorTimeStamp(state, "");
ShowContinueError(state, format(" Iteration limit [{}] exceeded in calculating OU evaporating temperature", MaxIter));
} else if (SolFla == -2) {
// demand < capacity at both endpoints of the Te range, assuming f(x) is roughly monotonic than this is the low load case
assert(f(T_suction) < 0);
// TeTol is added to prevent the final updated Te to go out of bounds
SmallLoadTe = 6 + TeTol; // MinOutdoorUnitTe; //SmallLoadTe( Te'_new ) is constant during iterations
}

// Get an updated Te corresponding to the updated Te'
// VRFOU_TeModification( VRFCond, this->EvaporatingTemp, SmallLoadTe, Pipe_h_IU_in, OutdoorDryBulb, Pipe_Te_assumed,
Expand All @@ -14006,6 +14027,7 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state,
NumIteTe = 1;
MaxNumIteTe = (this->EvaporatingTemp - SmallLoadTe) / 0.1 + 1; // upper bound and lower bound of Te iterations
Pipe_Te_assumed = this->EvaporatingTemp - 0.1;
this->adjustedTe = true;

Label11:;
Pipe_m_ref = 0; // Total Ref Flow Rate( kg/s )
Expand Down Expand Up @@ -14072,14 +14094,14 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state,

T_suction = this->refrig->getSatTemperature(state, max(min(Pipe_Pe_assumed - Pipe_DeltP, RefPHigh), RefPLow), RoutineName);

if ((std::abs(T_suction - SmallLoadTe) > 0.5) && (Pipe_Te_assumed < this->EvaporatingTemp) && (Pipe_Te_assumed > SmallLoadTe) &&
if ((std::abs(T_suction - SmallLoadTe) > TeTol) && (Pipe_Te_assumed < this->EvaporatingTemp) && (Pipe_Te_assumed > SmallLoadTe) &&
(NumIteTe < MaxNumIteTe)) {
Pipe_Te_assumed = Pipe_Te_assumed - 0.1;
NumIteTe = NumIteTe + 1;
goto Label11;
}

if (std::abs(T_suction - SmallLoadTe) > 0.5) {
if (std::abs(T_suction - SmallLoadTe) > TeTol) {
NumIteTe = 999;
T_suction = SmallLoadTe;
Pipe_SH_merged = 3.0;
Expand Down Expand Up @@ -14131,12 +14153,21 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state,
goto Label13;
}

if (CapDiff > (Tolerance * Cap_Eva0)) NumIteCcap = 999;
// when it gets here, either NumIteCcap = 30 or CapDiff > (Tolerance * Cap_Eva0)
if (CapDiff > (Tolerance * Cap_Eva0) && (Cap_Eva1 - Cap_Eva0) >= 0.0) {
NumIteCcap = 999;
CyclingRatio = Cap_Eva0 / Cap_Eva1;
} else {
CyclingRatio = 1.0;
}

Ncomp = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
OUCondHeatRelease = Ncomp + Cap_Eva1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Condenser heat rejection = power + evap capacity. How does this calculation relate to lines 11706 and 11707? Is OUCondHeatRelease the same as Q_h_OU at line 11707? And where is Q_c_OU *= cyclingRatio? I am getting confused as to which variables account for cycling and which don't. Does OUCondHeatRelease = Ncomp + Cap_Eva1; account for cycling?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ncomp should probably account for cycling
OUCondHeatRelease was computed as the following in the CounterCompSpdTemp > NumOfCompSpdInput case

OUCondHeatRelease = Ncomp + CompEvaporatingCAPSpd(NumOfCompSpdInput);

So I basically followed this in the low-load approach. Originally I have the Ncomp and OUCondHeatRelease multiply by CyclingRatio (or maybe it should be RTF) in CalcCompH() function, but since the flow of the code is like

        Ncomp = TU_CoolingLoad / this->CoolingCOP;
        Ncomp_new = Ncomp;
    Label10:;
        Q_h_OU = Q_c_TU_PL + Ncomp_new; // Ncomp_new may be updated during Iteration_Ncomp Label10

        ...

        // *VEF OU Compressor Simulation at cooling mode: Specify the compressor speed and power consumption
        this->VRFOU_CalcCompC(state,
                              TU_CoolingLoad,
                              Tsuction,
                              this->CondensingTemp,
                              Psuction,
                              T_comp_in,
                              h_comp_in,
                              h_IU_evap_in,
                              Pipe_Q_c,
                              CapMaxTc,
                              Q_h_OU,
                              CompSpdActual,
                              Ncomp,
                              CyclingRatio);

        if ((std::abs(Ncomp - Ncomp_new) > (Tolerance * Ncomp_new)) && (Counter < 30)) {
            Ncomp_new = Ncomp;
            Counter = Counter + 1;
            goto Label10;
        }

As the initial value of Ncomp (Ncomp = TU_CoolingLoad / this->CoolingCOP) does not have CyclingRatio in it, and the compressor is indeed going to cycling, then the cycling ratio will get multiplied multiple times, once each label10 loop. So I moved them to after the loop is completed.

OUCondHeatRelease = Ncomp + Cap_Eva1 = Ncomp + Cap_Eva0 / CyclingRatio;
OUCondHeatRelease * CyclingRatio = Ncomp * CyclingRatio + Cap_Eva0 = Ncomp * CyclingRatio + TU_load + Pipe_Q

Copy link
Contributor

Choose a reason for hiding this comment

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

The plots you make of a transition from CyclingRatio = 1 to CyclingRatio < 1 (later in a day when the cooling load is decreasing) will show if these equations are correct. Maybe start there to determine how these equations need to be organized.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The plot is in this comment #10353 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

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

It doesn't seem like the cycling ratio is double-counted. If we want to make sure, maybe we could double-check the output result against the hand calculation result at a certain fixed timestep.


this->CondensingTemp = T_discharge; // OU Tc' is updated due to OUCondHeatRelease updates, which is caused by IU Te' updates
// during low load conditions
this->EvaporatingTemp = T_suction;
this->IUEvaporatingTemp = T_suction;

break; // EXIT DoName1

Expand Down Expand Up @@ -14212,7 +14243,7 @@ void VRFCondenserEquipment::VRFOU_CalcCompH(
Real64 RefTSat; // Saturated temperature of the refrigerant [C]
Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
Real64 Tolerance(0.05); // Tolerance for condensing temperature calculation [C}
Real64 constexpr Tolerance(0.05); // Tolerance for condensing temperature calculation [C}
Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]

Expand Down
8 changes: 5 additions & 3 deletions src/EnergyPlus/HVACVariableRefrigerantFlow.hh
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ namespace HVACVariableRefrigerantFlow {
Real64 VRFOperationSimPath; // simulation path indicating the VRF operation mode [--]
bool checkPlantCondTypeOneTime;
int CondenserCapErrIdx; // recurring condenser capacity error index
bool adjustedTe;

// Default Constructor
VRFCondenserEquipment()
Expand Down Expand Up @@ -427,7 +428,7 @@ namespace HVACVariableRefrigerantFlow {
RatedHeatCapacity(0.0), RatedCompPower(14000.0), RatedCompPowerPerCapcity(0.35), RatedOUFanPower(0.0), RatedOUFanPowerPerCapcity(0.0),
RateBFOUEvap(0.45581), RateBFOUCond(0.21900), RefPipDiaSuc(0.0), RefPipDiaDis(0.0), RefPipLen(0.0), RefPipEquLen(0.0), RefPipHei(0.0),
RefPipInsThi(0.0), RefPipInsCon(0.0), SH(0.0), SC(0.0), SCHE(0.0), SHLow(0.0), SCLow(0.0), SHHigh(0.0), SCHigh(0.0),
VRFOperationSimPath(0.0), checkPlantCondTypeOneTime(true), CondenserCapErrIdx(0)
VRFOperationSimPath(0.0), checkPlantCondTypeOneTime(true), CondenserCapErrIdx(0), adjustedTe(false)
{
}

Expand All @@ -449,7 +450,7 @@ namespace HVACVariableRefrigerantFlow {

void SizeVRFCondenser(EnergyPlusData &state);

void CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state);
void CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state, const bool FirstHVACIteration);

void CalcVRFIUTeTc_FluidTCtrl(EnergyPlusData &state);

Expand Down Expand Up @@ -526,7 +527,8 @@ namespace HVACVariableRefrigerantFlow {
Real64 MaxOutdoorUnitTc, // The maximum temperature that Tc can be at heating mode [C]
Real64 &OUCondHeatRelease, // Condenser heat release (cooling mode) [W]
Real64 &CompSpdActual, // Actual compressor running speed [rps]
Real64 &Ncomp // Compressor power [W]
Real64 &Ncomp, // Compressor power [W]
Real64 &CyclingRatio // Cycling Ratio [W]
);

void
Expand Down
2 changes: 1 addition & 1 deletion src/EnergyPlus/HeatBalanceSurfaceManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ void InitSurfaceHeatBalance(EnergyPlusData &state)
}
}

// yujie: variable thermal solar absorptance overrides
// variable thermal solar absorptance overrides
UpdateVariableAbsorptances(state);

// Do the Begin Environment initializations
Expand Down
2 changes: 1 addition & 1 deletion src/EnergyPlus/HeatRecovery.cc
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ namespace HeatRecovery {
thisExchanger.EconoLockOut = static_cast<bool>(toggle);
}

// yujie: read new curves here
// read new curves here
thisExchanger.HeatEffectSensibleCurveIndex =
Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(11)); // convert curve name to number
thisExchanger.HeatEffectLatentCurveIndex =
Expand Down
Loading
Loading