diff --git a/.github/workflows/test_pull_requests.yml b/.github/workflows/test_pull_requests.yml index ebf34993c02..39e494f6764 100644 --- a/.github/workflows/test_pull_requests.yml +++ b/.github/workflows/test_pull_requests.yml @@ -277,7 +277,7 @@ jobs: # - uses: lhotari/action-upterm@v1 - name: Fail on Regressions from Forked Repository - if: always() && matrix.run_regressions && steps.regressions.outcome == 'failure' && github.event.pull_request.head.repo.full_name != 'NREL/EnergyPlus' + if: always() && matrix.run_regressions && steps.regressions.outcome == 'failure' && github.event.pull_request.head.repo.full_name != 'NatLabRockies/EnergyPlus' run: | echo "::error::Regressions detected in pull request from forked repository, check job summary for details and to download regression results" exit 1 diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 97c04ebb849..dc7a0238adc 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -14206,41 +14206,86 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state, 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 == -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) { - this->LowLoadTeError++; - if (LowLoadTeError < 5) { - ShowWarningMessage(state, - format("{}: no Te solution was found for {} f({})={} and f({})={} are the same sign", - RoutineName, - this->Name, - MinOutdoorUnitTe, - f(MinOutdoorUnitTe), - T_suction, - f(T_suction))); - ShowContinueErrorTimeStamp(state, ""); - } - ShowRecurringWarningErrorAtEnd(state, - "Low load calculation Te solution not found as end points have the same sign", - this->LowLoadTeErrorIndex, - SolFla, - SolFla); - if (f(T_suction) < 0) { - // demand < capacity at both endpoints of the Te range, assuming f(x) is roughly monotonic than this is the low load case - // TeTol is added to prevent the final updated Te to go out of bounds - SmallLoadTe = MinOutdoorUnitTe + TeTol; // MinOutdoorUnitTe; //SmallLoadTe( Te'_new ) is constant during iterations + Real64 f_xmin = f(MinOutdoorUnitTe); + Real64 f_xmax = f(T_suction); + if (f_xmin < 0 && f_xmax < 0) { + SmallLoadTe = MinOutdoorUnitTe; + } else if (f_xmin > 0 && f_xmax > 0) { + if (f_xmin > f_xmax) { + SmallLoadTe = T_suction; } else { - // demand > capacity at both endpoints of the Te range, take the end point x where f(x) is closer to zero - if (f(MinOutdoorUnitTe) > f(T_suction)) { // f(T_suction > 0, not equal as SolFla will not be -2 - SmallLoadTe = T_suction; - } else { + SmallLoadTe = MinOutdoorUnitTe; + } + } else { + General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, SmallLoadTe, f, MinOutdoorUnitTe, T_suction); // SmallLoadTe is the updated Te' + if (SolFla == -1) { + // show error not converging + if (LowLoadTeIterError == 0) { + 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)); + } + ShowRecurringWarningErrorAtEnd(state, + "Low load calculation Te solution iteration limit exceeded error continues.", + this->LowLoadTeIterError, + SmallLoadTe, + SmallLoadTe); + } else if (SolFla == -2) { + if (f_xmax < 0) { + // demand < capacity at both endpoints of the Te range, assuming f(x) is roughly monotonic then this is the low load + // case TeTol is added to prevent the final updated Te to go out of bounds SmallLoadTe = MinOutdoorUnitTe; + this->LowLoadTeError2Neg++; + if (LowLoadTeError2Neg < 5) { + ShowWarningMessage(state, + format("{}: no Te solution was found for {}, as load < capacity for the whole range of Te", + RoutineName, + this->Name)); + ShowContinueErrorTimeStamp(state, ""); + } + ShowRecurringWarningErrorAtEnd( + state, + "Low load calculation Te solution not found as load is smaller than min-speed capacity for the whole range", + this->LowLoadTeError2NegIndex, + SmallLoadTe, + SmallLoadTe); + } else { + // demand > capacity at both endpoints of the Te range, take the end point x where f(x) is closer to zero + if (f_xmin > f_xmax) { // f(T_suction > 0, not equal as SolFla would not have been -2 + SmallLoadTe = T_suction; + this->LowLoadTeError2PosTsuc++; + if (LowLoadTeError2PosTsuc < 5) { + ShowWarningMessage(state, + format("{}: no Te solution was found for {}, as load > capacity for the full range of Te", + RoutineName, + this->Name)); + ShowContinueErrorTimeStamp(state, ""); + } + ShowRecurringWarningErrorAtEnd( + state, + "Low load calculation Te solution not found as load is larger than min-speed capacity for " + "the whole range\nTake T_suction as the updated Te", + this->LowLoadTeError2PosTsucIndex, + SmallLoadTe, + SmallLoadTe); + } else { + SmallLoadTe = MinOutdoorUnitTe; + this->LowLoadTeError2PosOUTe++; + if (LowLoadTeError2PosOUTe < 5) { + ShowWarningMessage(state, + format("{}: no Te solution was found for {}, as load > capacity for the full range of Te", + RoutineName, + this->Name)); + ShowContinueErrorTimeStamp(state, ""); + } + ShowRecurringWarningErrorAtEnd( + state, + "Low load calculation Te solution not found as load is larger than min-speed capacity for " + "the whole range\nTake MinOutdoorUnitTe as the updated Te", + this->LowLoadTeError2PosOUTeIndex, + SmallLoadTe, + SmallLoadTe); + } } } } @@ -14251,7 +14296,7 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state, { // Initialization of Iteration_Te (Label11) // i.e., find a new Te (Pipe_Te_assumed) that can generate a new T_suction equaling to SmallLoadTe. - // This requires the re-calculate of piping loss. + // This requires the re-calculation of piping loss. NumIteTe = 1; MaxNumIteTe = (this->EvaporatingTemp - SmallLoadTe) / 0.1 + 1; // upper bound and lower bound of Te iterations Pipe_Te_assumed = this->EvaporatingTemp - 0.1; diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.hh b/src/EnergyPlus/HVACVariableRefrigerantFlow.hh index 1d98dd20799..48d9e630b21 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.hh +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.hh @@ -314,8 +314,14 @@ namespace HVACVariableRefrigerantFlow { int CoolCapFTErrorIndex = 0; // warning message index int HeatEIRFPLRErrorIndex = 0; // warning message index int CoolEIRFPLRErrorIndex = 0; // warning message index - int LowLoadTeError = 0; - int LowLoadTeErrorIndex = 0; // warning message index + int LowLoadTeIterError = 0; + int LowLoadTeError2Neg = 0; + int LowLoadTeError2NegIndex = 0; // warning message index + int LowLoadTeError2PosTsuc = 0; + int LowLoadTeError2PosTsucIndex = 0; // warning message index + int LowLoadTeError2PosOUTe = 0; + int LowLoadTeError2PosOUTeIndex = 0; // warning message index + int LowLoadTeErrorIndex = 0; // warning message index // The following are for the Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control int AlgorithmIUCtrl; // VRF indoor unit control algorithm, 1-High sensible, 2-Te/Tc constant Array1D CompressorSpeed; // compressor speed array [rps] diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index 12e6639a129..cc4f32b7377 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -2663,7 +2663,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Compressor) thisVRF.RatedEvapCapacity * CurveValue(*state, thisVRF.OUCoolingCAPFT(1), thisVRF.CondensingTemp, thisVRF.EvaporatingTemp); Real64 CompEvaporatingPWRSpdMin = thisVRF.RatedCompPower * CurveValue(*state, thisVRF.OUCoolingPWRFT(1), thisVRF.CondensingTemp, thisVRF.EvaporatingTemp); - EXPECT_NEAR(0.36, CyclingRatio, 0.01); + EXPECT_NEAR(0.37, CyclingRatio, 0.01); EXPECT_NEAR(OUEvapHeatExtract, CompEvaporatingCAPSpdMin + Ncomp, 1e-4); EXPECT_NEAR(1500, CompSpdActual, 1); EXPECT_NEAR(Ncomp, CompEvaporatingPWRSpdMin, 1e-4); @@ -13335,7 +13335,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_ReportOutputVerificationTest) EXPECT_NEAR(5645.5696, thisVRFTU.TotalCoolingRate, 0.0001); EXPECT_NEAR(84.8359, thisFan->totalPower, 0.0001); EXPECT_NEAR(thisDXCoolingCoil.TotalCoolingEnergyRate, (thisVRFTU.TotalCoolingRate + thisFan->totalPower), 0.0001); - EXPECT_NEAR(0.4772, state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio, 0.0001); + EXPECT_NEAR(0.4851, state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio, 0.0001); EXPECT_NEAR(state->dataHVACVarRefFlow->VRF(1).OUFanPower, state->dataHVACVarRefFlow->VRF(1).RatedOUFanPower * state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio, 0.0001);