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

Fixes source side sizing calculation for HeatPump:PlantLoop:EIR:Heating issue #10382

Merged
merged 5 commits into from
Feb 8, 2024

Conversation

Nigusse
Copy link
Contributor

@Nigusse Nigusse commented Jan 26, 2024

Pull request overview

NOTE: ENHANCEMENTS MUST FOLLOW A SUBMISSION PROCESS INCLUDING A FEATURE PROPOSAL AND DESIGN DOCUMENT PRIOR TO SUBMITTING CODE

Pull Request Author

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

  • Title of PR should be user-synopsis style (clearly understandable in a standalone changelog context)
  • Label the PR with at least one of: Defect, Refactoring, NewFeature, Performance, and/or DoNoPublish
  • Pull requests that impact EnergyPlus code must also include unit tests to cover enhancement or defect repair
  • Author should provide a "walkthrough" of relevant code changes using a GitHub code review comment process
  • If any diffs are expected, author must demonstrate they are justified using plots and descriptions
  • If changes fix a defect, the fix should be demonstrated in plots and descriptions
  • If any defect files are updated to a more recent version, upload new versions here or on DevSupport
  • If IDD requires transition, transition source, rules, ExpandObjects, and IDFs must be updated, and add IDDChange label
  • If structural output changes, add to output rules file and add OutputChange label
  • If adding/removing any LaTeX docs or figures, update that document's CMakeLists file dependencies

Reviewer

This will not be exhaustively relevant to every PR.

  • Perform a Code Review on GitHub
  • If branch is behind develop, merge develop and build locally to check for side effects of the merge
  • If defect, verify by running develop branch and reproducing defect, then running PR and reproducing fix
  • If feature, test running new feature, try creative ways to break it
  • CI status: all green or justified
  • Check that performance is not impacted (CI Linux results include performance check)
  • Run Unit Test(s) locally
  • Check any new function arguments for performance impacts
  • Verify IDF naming conventions and styles, memos and notes and defaults
  • If new idf included, locally check the err file and other outputs

@Nigusse Nigusse added the Defect Includes code to repair a defect in EnergyPlus label Jan 26, 2024
@Nigusse Nigusse added this to the EnergyPlus 24.1 milestone Jan 26, 2024
Copy link
Contributor Author

@Nigusse Nigusse left a comment

Choose a reason for hiding this comment

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

Code changes walk through:

  • source side capacity and fluid flow rate calc changed for the heating coil only
  • cleaned up function names as an argument in several places

@@ -514,7 +514,7 @@ void EIRPlantLoopHeatPump::doPhysics(EnergyPlusData &state, Real64 currentLoad)
thisLoadPlantLoop.FluidName,
state.dataLoopNodes->Node(this->loadSideNodes.inlet).Temp,
thisLoadPlantLoop.FluidIndex,
"PLHPEIR::simulate()");
"EIRPlantLoopHeatPump::doPhysics()");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated function names used as an argument in several places.

Copy link
Member

Choose a reason for hiding this comment

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

Good catch.

@@ -580,7 +580,7 @@ void EIRPlantLoopHeatPump::doPhysics(EnergyPlusData &state, Real64 currentLoad)
if (this->waterSource) {
auto &thisSourcePlantLoop = state.dataPlnt->PlantLoop(this->sourceSidePlantLoc.loopNum);
CpSrc = FluidProperties::GetSpecificHeatGlycol(
state, thisSourcePlantLoop.FluidName, this->sourceSideInletTemp, thisSourcePlantLoop.FluidIndex, "PLHPEIR::simulate()");
state, thisSourcePlantLoop.FluidName, this->sourceSideInletTemp, thisSourcePlantLoop.FluidIndex, "EIRPlantLoopHeatPump::doPhysics()");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated function names used as an argument.

Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
state.dataPlnt->PlantLoop(this->loadSidePlantLoc.loopNum).FluidName,
loadSideInitTemp,
state.dataPlnt->PlantLoop(this->loadSidePlantLoc.loopNum).FluidIndex,
"EIRPlantLoopHeatPump::size()");
"EIRPlantLoopHeatPump::sizeLoadSide()");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The same change here.

compCp = FluidProperties::GetSpecificHeatGlycol(
state,
state.dataPlnt->PlantLoop(compLoopNum).FluidName,
this->EIRHPType == DataPlant::PlantEquipmentType::HeatPumpEIRCooling ? Constant::HWInitConvTemp : Constant::CWInitConvTemp,
state.dataPlnt->PlantLoop(compLoopNum).FluidIndex,
"EIRPlantLoopHeatPump::size()");
"EIRPlantLoopHeatPump::sizeLoadSide()");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The same change here.

@@ -735,13 +735,13 @@ void EIRPlantLoopHeatPump::sizeLoadSide(EnergyPlusData &state)
state.dataPlnt->PlantLoop(compLoopNum).FluidName,
this->EIRHPType == DataPlant::PlantEquipmentType::HeatPumpEIRCooling ? Constant::HWInitConvTemp : Constant::CWInitConvTemp,
state.dataPlnt->PlantLoop(compLoopNum).FluidIndex,
"EIRPlantLoopHeatPump::size()");
"EIRPlantLoopHeatPump::sizeLoadSide()");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The same change here.

Real64 const compCp = FluidProperties::GetSpecificHeatGlycol(state,
state.dataPlnt->PlantLoop(compLoopNum).FluidName,
Constant::CWInitConvTemp,
state.dataPlnt->PlantLoop(compLoopNum).FluidIndex,
"EIRPlantLoopHeatPump::size()");
"EIRPlantLoopHeatPump::sizeLoadSide()");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The same change here.

@@ -969,12 +969,12 @@ void EIRPlantLoopHeatPump::sizeSrcSideWSHP(EnergyPlusData &state)
state.dataPlnt->PlantLoop(this->loadSidePlantLoc.loopNum).FluidName,
sourceSideInitTemp,
state.dataPlnt->PlantLoop(this->loadSidePlantLoc.loopNum).FluidIndex,
"EIRPlantLoopHeatPump::size()");
"EIRPlantLoopHeatPump::sizeSrcSideWSHP()");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The same change here.

Real64 const CpSrc = FluidProperties::GetSpecificHeatGlycol(state,
state.dataPlnt->PlantLoop(this->loadSidePlantLoc.loopNum).FluidName,
sourceSideInitTemp,
state.dataPlnt->PlantLoop(this->loadSidePlantLoc.loopNum).FluidIndex,
"EIRPlantLoopHeatPump::size()");
"EIRPlantLoopHeatPump::sizeSrcSideWSHP()");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The same change here.

designSourceSideHeatTransfer = tmpCapacity * (1 - 1 / this->referenceCOP);
} else {
designSourceSideHeatTransfer = tmpCapacity * (1 + 1 / this->referenceCOP);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For the heating coil, the source side design capacity is basically the evaporator capacity (heat transfer). Derivation of the above equation for heating coil leads to minus sign. The previous equation is valid for cooling coil only. This fix is for water-source HP.

designSourceSideHeatTransfer = tmpCapacity * (1 - 1 / this->referenceCOP);
} else {
designSourceSideHeatTransfer = tmpCapacity * (1 + 1 / this->referenceCOP);
}
Copy link
Contributor Author

@Nigusse Nigusse Jan 26, 2024

Choose a reason for hiding this comment

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

This change is the same as the previous, but for the air-source HP.

@Nigusse
Copy link
Contributor Author

Nigusse commented Jan 26, 2024

Sample diffs. Only the heating coil source side flow rate was impacted as expected.

Component Sizing Information, Pump:VariableSpeed, HEATSYS1 PUMP, Design Power Consumption [W], 12547.22436
  Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_1 HEATING SIDE, Design Size Nominal Capacity [W], 3583772.55507
  Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_1 HEATING SIDE, Design Size Load Side Volume Flow Rate [m3/s], 0.11637
- Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_1 HEATING SIDE, Design Size Source Side Volume Flow Rate [m3/s], 408.24654
+ Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_1 HEATING SIDE, Design Size Source Side Volume Flow Rate [m3/s], 198.35115
  Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_2 HEATING SIDE, Design Size Nominal Capacity [W], 3583772.55507
  Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_2 HEATING SIDE, Design Size Load Side Volume Flow Rate [m3/s], 0.11637
- Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_2 HEATING SIDE, Design Size Source Side Volume Flow Rate [m3/s], 408.24654
+ Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_2 HEATING SIDE, Design Size Source Side Volume Flow Rate [m3/s], 198.35115

designSourceSideHeatTransfer = tmpCapacity * (1 - 1 / this->referenceCOP);
} else {
designSourceSideHeatTransfer = tmpCapacity * (1 + 1 / this->referenceCOP);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be tmpCapacity / (1 + 1 / this->referenceCOP) for heating. I tried both ways and don't get the same answer.

designSourceSideHeatTransfer = Hcap * (1 - 1/COP) = 1000 * (1 - 1/3) = 667
designSourceSideHeatTransfer = Hcap / (1 + 1/COP) = 1000 / (1 + 1/3) = 750

And as a test, if the cooling and heating EIR HP capacity is hardsized and the heating capacity is 1 + 1/COP the size of the cooling capacity (and the COPs are the same), then the autosized load side water flow rate on the cooling EIR HP should be the same size as the autosized source side water flow rate of the heating EIR HP.

Copy link
Contributor Author

@Nigusse Nigusse Jan 26, 2024

Choose a reason for hiding this comment

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

The above formulations are based on the first-law energy balance equations and COP definition as shown below:

Qcond = Qevap + Power; COPc = Qevap / Power; COPh = Qcond / Power

You can derive them from these three equations. The heat transfer should not be the same even if the COP are equal because the heat transfer at the condenser includes the power input while the heat transfer at the evaporator doesn't.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, that's what I was missing, the COPs are different:

COPh = COPc * (1 + 1/COPc) = 3 * (1 + 1/3) = 4 <-- is this COP conversion correct?

designSourceSideHeatTransfer = Hcap * (1 - 1/COPh) = 1000 * (1 - 1/4) = 750
designSourceSideHeatTransfer = Ccap * (1 + 1/COPc) = 750 * (1 + 1/3) = 1000

I think there are places where the divide by (1 + 1/COP) is used. Maybe those are wrong also.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The correct relationship is COPh = COPc + 1.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only places that needed to be changed were in source side sizing calculation functions: sizeSrcSideASHP() and sizeSrcSideWSHP().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rraustad I searched for (1 + 1/COP) and (1.0 + 1.0 / this->referenceCOP) but did not find any.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for working through this description, it's helpful.

@Nigusse
Copy link
Contributor Author

Nigusse commented Jan 26, 2024

Diffs are expected only if the HeatPump:PlantLoop:EIR:Heating has its Source Side Reference Flow Rate input field set to autosize.

@Nigusse
Copy link
Contributor Author

Nigusse commented Jan 26, 2024

The two example files shown below are expected to have diffs:

 PlantLoopHeatPump_EIR_LargeOffice-2-AWHP-AuxBoiler-Pri-Sec-4PipeBeam.idf
 PlantLoopHeatPump_EIR_Large-Office-2-AWHP-DedHR-AuxBoiler-Pri-Sec-HW.idf 

@Nigusse
Copy link
Contributor Author

Nigusse commented Jan 29, 2024

Modified three unit tests failed due to this fix.

Copy link
Contributor Author

@Nigusse Nigusse left a comment

Choose a reason for hiding this comment

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

Modified failed unit tests.

@@ -868,7 +870,7 @@ TEST_F(EnergyPlusFixture, TestSizing_FullyAutosizedCoolingWithCompanion_WaterSou
thisCoolingPLHP->loadSideDesignVolFlowRate = expectedLoadFlow;
thisCoolingPLHP->sourceSideDesignVolFlowRate = expectedSourceFlow;
thisCoolingPLHP->referenceCapacity = expectedCapacity;
Real64 const designSourceSideHeatTransfer = expectedCapacity * (1 + 1 / thisHeatingPLHP->referenceCOP);
Real64 const designSourceSideHeatTransfer = expectedCapacity * (1 - 1 / thisHeatingPLHP->referenceCOP);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For heating coil, the source side heat transfer calc expression updated to match the correct expression in the code.

Real64 expectedSourceCp = 1004.0;
Real64 expectedSourceRho = 1.2;
Real64 expectedSourceCp = Psychrometrics::PsyCpAirFnW(sourceSideHumRat);
Real64 expectedSourceRho = Psychrometrics::PsyRhoAirFnPbTdbW(*state, state->dataEnvrn->StdBaroPress, sourceSideInitTemp, sourceSideHumRat);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Needed to match the sizing calculation assumptions to remove diffs.

@@ -2688,7 +2691,7 @@ TEST_F(EnergyPlusFixture, TestSizing_FullyAutosizedCoolingWithCompanion_AirSourc
thisCoolingPLHP->sourceSideDesignVolFlowRate = expectedSourceFlow;
thisCoolingPLHP->referenceCapacity = expectedCapacity;
expectedCapacity = expectedLoadRho * expectedLoadFlow * expectedLoadCp * plantSizingLoadDeltaT;
expectedSourceLoad = expectedCapacity * (1 + 1 / COP);
expectedSourceLoad = expectedCapacity * (1 - 1 / thisHeatingPLHP->referenceCOP);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For heating coil, the source side heat transfer calc expression updated to match the correct expression in the code.

@@ -2854,7 +2857,7 @@ TEST_F(EnergyPlusFixture, TestSizing_AutosizedFlowWithCompanion_AirSource)
" 0.005,",
" Autosize,",
" Autosize,",
" 1.0,",
" 2.0,",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed the heating coil COP to 2.0 from 1.0 to avoid zero source side flow rate.

Copy link
Contributor

@rraustad rraustad Jan 29, 2024

Choose a reason for hiding this comment

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

I have seen users set COP=1 on DX equipment for various reasons, mostly for ideal simulations. If a user sets COPh = 1 the new equation calculates 0 source heat transfer. If COPh < 1 then there is negative source side heat transfer and there would be heating on the load and source side. I'm not sure what that means or what the limit of COPh=1 represents other than non-DX equipment. If COPc = 1 you get twice the source heat transfer as the load side. It seems for an ideal run then COPh=2, as you have shown here. I am tempted to change all these COP limits in the idd to >=1 for cooling or >=2 for heating. Not for this issue but for clarity of operation for users.

HeatPump:PlantLoop:EIR:Heating,
   N4,  \field Reference Coefficient of Performance
        \type real
        \minimum> 0.0
        \units W/W
        \default 3.0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the heating coil (heating mode) design COPh is 1.0, it means the source side COPc is 0.0, i.e., there is no heat transfer at the evaporator coil. Also, it means the heat dissipated at the condenser is the same as the power input at the system (compressor). Can this operating condition be possible in the actual machine? To me, this implies the refrigeration cycle will not be complete; hence, it is not possible.

@@ -2925,7 +2928,7 @@ TEST_F(EnergyPlusFixture, TestSizing_AutosizedFlowWithCompanion_AirSource)
thisHeatingPLHP->onInitLoopEquip(*state, myHeatingLoadLocation);

Real64 expectedClgSourceFlow = 86.71;
Real64 expectedHtgSourceFlow = 86.71;
Real64 expectedHtgSourceFlow = 21.68; // changed from 86.71 due to issue#10381;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The source side flow rate is now divided by 4 because of this fix and COP value assumption change.

@Nigusse
Copy link
Contributor Author

Nigusse commented Jan 29, 2024

Uploaded defect file.
PLHP_EIR_AirSource_Issue10381.idf.txt

@Nigusse
Copy link
Contributor Author

Nigusse commented Jan 29, 2024

Demonstration of change in Source Side Reference Flow Rate sizing calculation based on the attached defect file.

Develop:
Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, HEATING COIL, Design Size Source Side Volume Flow Rate [m3/s], 8.69352

Branch:
Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, HEATING COIL, Design Size Source Side Volume Flow Rate [m3/s], 4.82974

The ratio between these flow rates is 1.8 (= 8.69352/4.82974) or (= (1+1/COPh) / (1-1/COPh) = (1+1/3.5) / (1-1/3.5) ).

@Nigusse Nigusse requested a review from rraustad January 29, 2024 21:19
@rraustad
Copy link
Contributor

In the eio diffs I see that the source side volume flow rate did change due to your code correction so that's good. This is an air-source HP so the volume flow rates on the load and source side seem resonable (rho different by about 1000). I don't see any other issues.

  Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_1 HEATING SIDE, Design Size Load Side Volume Flow Rate [m3/s], 0.11637
- Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_1 HEATING SIDE, Design Size Source Side Volume Flow Rate [m3/s], 408.24654
+ Component Sizing Information, HeatPump:PlantLoop:EIR:Heating, AWHP_1 HEATING SIDE, Design Size Source Side Volume Flow Rate [m3/s], 198.35115

Copy link
Contributor

@rraustad rraustad left a comment

Choose a reason for hiding this comment

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

This change seems straight-forward and correct.

Copy link
Member

@Myoldmopar Myoldmopar left a comment

Choose a reason for hiding this comment

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

This seems like a fine change. I'll build and test locally.

@@ -514,7 +514,7 @@ void EIRPlantLoopHeatPump::doPhysics(EnergyPlusData &state, Real64 currentLoad)
thisLoadPlantLoop.FluidName,
state.dataLoopNodes->Node(this->loadSideNodes.inlet).Temp,
thisLoadPlantLoop.FluidIndex,
"PLHPEIR::simulate()");
"EIRPlantLoopHeatPump::doPhysics()");
Copy link
Member

Choose a reason for hiding this comment

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

Good catch.

designSourceSideHeatTransfer = tmpCapacity * (1 - 1 / this->referenceCOP);
} else {
designSourceSideHeatTransfer = tmpCapacity * (1 + 1 / this->referenceCOP);
}
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for working through this description, it's helpful.

@Myoldmopar
Copy link
Member

I'm seeing only the same two regression diffs locally, and otherwise things are happy. Merging this. Thanks @Nigusse

@Myoldmopar Myoldmopar merged commit a509560 into develop Feb 8, 2024
15 checks passed
@Myoldmopar Myoldmopar deleted the plhp_eir_sourceSide_sizing branch February 8, 2024 17:00
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Source side sizing calculation for HeatPump:PlantLoop:EIR:Heating is incorrect
8 participants