Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
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
37 changes: 27 additions & 10 deletions src/EnergyPlus/WaterToAirHeatPumpSimple.cc
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,13 @@ namespace WaterToAirHeatPumpSimple {

if (simpleWAHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
// Cooling mode
InitSimpleWatertoAirHP(state, HPNum, SensLoad, LatentLoad, fanOp, OnOffAirFlowRatio, FirstHVACIteration);
InitSimpleWatertoAirHP(state, HPNum, SensLoad, LatentLoad, fanOp, OnOffAirFlowRatio, FirstHVACIteration, PartLoadRatio);
CalcHPCoolingSimple(state, HPNum, fanOp, SensLoad, LatentLoad, compressorOp, PartLoadRatio, OnOffAirFlowRatio);
UpdateSimpleWatertoAirHP(state, HPNum);
} else if (simpleWAHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit) {
// Heating mode
InitSimpleWatertoAirHP(state, HPNum, SensLoad, DataPrecisionGlobals::constant_zero, fanOp, OnOffAirFlowRatio, FirstHVACIteration);
InitSimpleWatertoAirHP(
state, HPNum, SensLoad, DataPrecisionGlobals::constant_zero, fanOp, OnOffAirFlowRatio, FirstHVACIteration, PartLoadRatio);
CalcHPHeatingSimple(state, HPNum, fanOp, SensLoad, compressorOp, PartLoadRatio, OnOffAirFlowRatio);
UpdateSimpleWatertoAirHP(state, HPNum);
} else {
Expand Down Expand Up @@ -914,9 +915,10 @@ namespace WaterToAirHeatPumpSimple {
int const HPNum, // Current HPNum under simulation
Real64 const SensLoad, // Control zone sensible load[W]
Real64 const LatentLoad, // Control zone latent load[W]
[[maybe_unused]] HVAC::FanOp const fanOp, // fan operating mode
HVAC::FanOp const fanOp, // fan operating mode
[[maybe_unused]] Real64 const OnOffAirFlowRatio, // ratio of compressor on flow to average flow over time step
bool const FirstHVACIteration // Iteration flag
bool const FirstHVACIteration, // Iteration flag
Real64 const PartLoadRatio // compressor part load ratio
)
{

Expand Down Expand Up @@ -1103,12 +1105,27 @@ namespace WaterToAirHeatPumpSimple {
state.dataLoopNodes->Node(AirInletNode).Temp,
state.dataLoopNodes->Node(AirInletNode).HumRat,
RoutineName);
if (simpleWAHP.AirMassFlowRate < 0.25 * RatedAirMassFlowRate) {
ShowRecurringWarningErrorAtEnd(state,
"Actual air mass flow rate is smaller than 25% of water-to-air heat pump coil rated air flow rate.",
state.dataWaterToAirHeatPumpSimple->AirflowErrPointer,
simpleWAHP.AirMassFlowRate,
simpleWAHP.AirMassFlowRate);
if (fanOp != HVAC::FanOp::Cycling) {
if (simpleWAHP.AirMassFlowRate < 0.25 * RatedAirMassFlowRate) {
ShowRecurringWarningErrorAtEnd(
state,
"Actual air mass flow rate is smaller than 25% of water-to-air heat pump coil rated air flow rate.",
state.dataWaterToAirHeatPumpSimple->AirflowErrPointer,
simpleWAHP.AirMassFlowRate,
simpleWAHP.AirMassFlowRate);
}
} else {
if ((PartLoadRatio == 0.0) || (simpleWAHP.AirMassFlowRate / PartLoadRatio) < 0.25 * RatedAirMassFlowRate) {
if (simpleWAHP.LowFlowFlag) {
ShowWarningError(
state,
EnergyPlus::format(
"{}: Actual air mass flow rate is smaller than 25% of water-to-air heat pump coil ({}) rated air flow rate.",
RoutineName,
simpleWAHP.Name));
simpleWAHP.LowFlowFlag = false;
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is the same thing that is done in the calc function so this is correct.

void CalcHPCooling(Heating)Simple:

    if (fanOp == HVAC::FanOp::Continuous) {
        LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate;
    } else {
        // default to cycling fan, cycling compressor, full load air flow
        if (PartLoadRatio > 0.0) {
            LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate / PartLoadRatio;
        } else {
            LoadSideFullMassFlowRate = 0.0;
        }
    }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@joseph-robertson I see the recurring removed from the err file, but where is the 1-time warning? In this diff, shouldn't there be a new warning that wasn't there before ? ASHRAE901_ApartmentHighRise_STD2019_Denver

Image

Copy link
Copy Markdown
Collaborator

@rraustad rraustad Apr 8, 2026

Choose a reason for hiding this comment

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

Also, this should be a SimpleWatertoAirHPConditions struct variable so each coil can report the warning.

if (state.dataWaterToAirHeatPumpSimple->LowFlowFlag) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@rraustad I think previously the recurring warning was being thrown on this testfile for coils in cycling fan mode. With the new / PartLoadRatio, the warning goes away. It's possible there are no testfiles (with coils in continuous fan mode) where we should expect the 1-time warning to be thrown. Perhaps I should look into writing a couple new unit tests for showing that both warning types get thrown under the right conditions; one for coil in continuous fan mode and one for coil in cycling fan mode.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Duh, your right.

Copy link
Copy Markdown
Collaborator Author

@joseph-robertson joseph-robertson Apr 9, 2026

Choose a reason for hiding this comment

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

After the divide by zero fix in dfd83ab, the testfile DOAToWaterToAirHPInlet_MultispeedFan.idf does throw the 1-time warning.

image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What is the node air flow rate when that warning is hit? If it's 0 then that warning should not be reported. Even if the flow rate is > 0 the coil will be off. Why report a warning for a time step when the coil is off? Eventually the coil will be on and that check will throw if necessary. For cycling fan if PLR = 0 then the coil will be off and the fan will be off. A parent can still call the coil with PLR = 0 when there is actually a load and the result will be capacity = 0. A parent will call the coil model with PLR = 0 and PLR = 1 to test whether either of these can meet the load. For continuous fan and PLR = 0 there will be a non-zero capacity because of fan heat and also if OA is provided and that result could meet the load so the parent will not turn on the coil. The check should be testing for if the coil is on, which also protects the divide by 0 but that's a different thing.

if (PartLoadRatio > 0.0 && (simpleWAHP.AirMassFlowRate / PartLoadRatio) < 0.25 * RatedAirMassFlowRate)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I will make this change. (I do see that the node air flow rate > 0 when PLR = 0.)

Since we'll now have no testfiles throwing this warning, I'll see if I can add a unit test for demonstrating it.

}
simpleWAHP.WaterFlowMode = true;
} else { // heat pump is off
Expand Down
4 changes: 3 additions & 1 deletion src/EnergyPlus/WaterToAirHeatPumpSimple.hh
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ namespace WaterToAirHeatPumpSimple {
Real64 LatentCapacityTimeConstant = 0.0; // Latent capcacity time constant [s]
Real64 FanDelayTime = 0.0; // Fan delay time, time delay for the HP's fan to
bool reportCoilFinalSizes = true; // one time report of sizes to coil report
bool LowFlowFlag = true; // one time low flow warning for coil in cycling fan mode
};

void SimWatertoAirHPSimple(EnergyPlusData &state,
Expand Down Expand Up @@ -190,7 +191,8 @@ namespace WaterToAirHeatPumpSimple {
Real64 const LatentLoad, // Control zone latent load[W]
HVAC::FanOp const fanOp, // fan operating mode
Real64 const OnOffAirFlowRatio, // ratio of compressor on flow to average flow over time step
bool const FirstHVACIteration // Iteration flag
bool const FirstHVACIteration, // Iteration flag
Real64 const PartLoadRatio // compressor part load ratio
);

void SizeHVACWaterToAir(EnergyPlusData &state, int const HPNum);
Expand Down
2 changes: 1 addition & 1 deletion tst/EnergyPlus/unit/WaterThermalTanks.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3151,7 +3151,7 @@ TEST_F(EnergyPlusFixture, StratifiedTank_GSHP_DesuperheaterSourceHeat)
CoilBranch.Comp(CompNum).Name = "GSHP_COIL1";

state->dataGlobal->BeginEnvrnFlag = true;
WaterToAirHeatPumpSimple::InitSimpleWatertoAirHP(*state, HPNum, 10.0, 10.0, fanOp, 1.0, true);
WaterToAirHeatPumpSimple::InitSimpleWatertoAirHP(*state, HPNum, 10.0, 10.0, fanOp, 1.0, true, 1.0);
WaterToAirHeatPumpSimple::CalcHPCoolingSimple(*state, HPNum, fanOp, 10.0, 10.0, HVAC::CompressorOp::On, PLR, 1.0);
// Coil source side heat successfully passed to HeatReclaimSimple_WAHPCoil(1).AvailCapacity
EXPECT_EQ(state->dataHeatBal->HeatReclaimSimple_WAHPCoil(1).AvailCapacity, state->dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(1).QSource);
Expand Down
Loading
Loading