-
Notifications
You must be signed in to change notification settings - Fork 460
A new air to water heat pump object #11001
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
Conversation
|
As I read the description it sounds like you intend one set of plant nodes for cooling loop connection and another set of plant nodes for heating loop connectiong. But the IDD only has one set. |
I was debating on this: whether I should do separate sets of nodes for heating, cooling, and potentially domestic hot water; or resemble the actual system which just have one set of nodes (1 air 1 water). Any suggestions? |
|
|
||
| Table 2. Input fields of the heat pump objects in EnergyPlus | ||
|
|
||
| <table class="table table-bordered table-hover table-condensed"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This table is almost impossible to read on GitHub since the columns are so wide and it is so tall it cannot be scrolled. I would suggest either breaking it into multiple tables or make the column width narrower by using shorter titles in each.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me adjust the format and try to make it more readable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reformatted the table. Hope it's more readable now.
| ## Proposed Approach ## | ||
|
|
||
| This new feature proposes to create a new input object, HeatPump:AirToWater. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is very difficult to compare what is being proposed to what appeared in the table of existing heat pumps because the of difficulties in that table (see previous comment). Perhaps repeat the table with the new object or else include it in the original table. Or perhaps you state that you are including all features from that table (if you are).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will include the proposed one in the comparison table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The proposed object is added as another row in the idd comparison table
| - time since defrost started, timeSinceStart | ||
|
|
||
| Note that ambient air temperature is already an existing EnergyPlus actuator. It could be used in defrost calculation as well. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please describe the outputs that you are planning to provide. Including timestep output variables, modifications or additions to the tabular outputs, and whether any rated efficiency metrics (such as from AHRI or ISO or other standards organizations) are going to be provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add a section describing the output
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a section listing the output variables
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. It would be great to add a tabular output file in the Equipment Summary report. Maybe it could include outputting a calculated rating efficiency equivalent to an AHRI or ISO test procedure (assuming there is one).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Just added some contents to the "Outputs" section including some info on entries to be added to the Equipment Summary report.
| boiler to produce hot water. The following is an example of the current object. | ||
| The object specifies capacity and EIR as functions of temperature and part load | ||
| ratio, with three performance curves. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this new object intending to replace the use of any existing objects and deprecate those? If not, adding a new object just seems to add some additional confusion on which one should be used. Perhaps you should include in the NFP some user oriented guidance on when each object that is mentioned in the NFP should be used including the proposed new one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new object can model multi-speed/variable-speed/modular products while the existing one can't. So for these cases users would want to use the new object. I will add some documentation on how to choose between them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a section with notes on which model to use to model an air-to-water heat pump.
|
Thanks for the feedbacks from the last technicality meetings. Regarding the few issues brought up.
Toy example For simplicity, we'll control theControl PLR to be the same: PLR = 0.4 (load / max capacity = 0.4) As the plant loop heat pump only has one EIR curve as a function of air and water temperature, and EIR curve as a function of PLR, we want to find a PLR adjustment function f(.) such that the following holds. As PLR is fixed to 0.4, For heating capacity, the one set of curve is also not enough: Using just one set of curve, the cycling ratio is always 0.4 (for simplicity assuming there's no minPLR limits and cycling ratio and PLR are equal) in this example for all water temperature values shown in the first figure. However, in reality, the second stage compressor will always be off and the first stage compressor will cycle. It's cycling ratio is not always constant, it varies between 0.73 and 0.75. |
|
Re @EnergyArchmage question from last time, we have a field "Compressor Multiplier" to model modular heat pumps where several of the same AWHP objects can be used together to provide larger heating/cooling capacity. We will restrict the system to allow only one Air-to-Water Heat Pump (AWHP) object to serve a single hot or chilled water loop. This means that load splitting between two AWHP objects will not be permitted. The current object cannot model scenarios where two multi-stage AWHPs (AWHP-A with "Compressor Multiplier" = 2) and one variable speed compressor AWHP (AWHP-B with "Compressor Multiplier" = 1) serve the same set of heating or cooling loads, as this would require splitting loads between the two AWHPs, which is not allowed. However, we do allow configurations where one AWHP serves the first floor and another serves the second floor, with each floor having its own dedicated plant loop. |
SpeedRatio is used for multi- or variable-speed components (e.g., the 10-speed coil model). PartLoadRatio is used for single-speed units with a cycling ratio variable to show when the unit turns on and off in a time step. You can certainly add SpeedRatio but it should be the same as PartLoadRatio so would be redundant at speed 1. Update: This new model does have a Number of Speeds input so maybe this is a good idea. |
|
@dareumnam @rraustad thanks for your input. I will add a speed ratio output. |
|
|
| this->eirFuncTempCurveValue = (1 - interpRatio) * eirModifierFuncTempLow + interpRatio * eirModifierFuncTempHigh; | ||
| this->eirFuncPLRModifierValue = (1 - interpRatio) * eirModifierFuncPLRLow + interpRatio * eirModifierFuncPLRHigh; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yujiex do you think you need to pull the powerUsage at lines 702 and 703 into this if/else block? why set speed level and performance curves at the high speed for CompressorControlType::FixedSpeed and interpolated otherwise while the power calculation always interpolates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for the multi-stage fixed-speed case, when the demand is between speed level n and speed level n-1, the heat pump runs p% time at speed n and (1-p)% time at speed n - 1.
for the variable speed case, it interpolates the performance curve to mimic modulating to a intermediate speed to satisfy the demand
I felt the two should theoretically result in the same power consumption? Like if the two speed level has capacity 100W and 200W and that the demand is 150W for example, then in the first case, it will have 50% time running at the lower speed and 50% time running at the higher speed; in the second case, it will interpolate the two speed levels with interpolation factor of 0.5. In both cases, they'll have the same power consumption: average of the power at the two speed level?
| // currentLoad will be met and there should? be some adjustment based on outlet water temp limit? | ||
| } | ||
|
|
||
| void HeatPumpAirToWater::calcLoadSideHeatTransfer(EnergyPlusData &state, Real64 const availableCapacity, Real64 const currentLoad) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be out or scope for this new model but all plant equipment models should be passing back the load met (Real64 ¤tLoad) to the plant manager (i.e., returned from the simulate function call to the plant manager) so the plant knows what the remaining load is. If the load is greater than the equipment capacity then the plant will have a remaining load to meet. All the simulate functions should look like this: simulate(state, , , Real64 &curLoad) {}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Although in void EIRPlantLoopHeatPump::simulate(), it seems like CurLoad is not updated in the function: in in both setOperatingFlowRatesASHP(..., CurLoad), and doPhysics(state, CurLoad), CurLoad is passed by value.
| // calculate power usage from EIR curves | ||
| Real64 eirModifierFuncTempLow = 1.0; | ||
| Real64 eirModifierFuncPLRLow = 1.0; | ||
| if (speedLevel > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed at the bottom of this function is this->speedLevel += 1; and that this conditional and the curve indexes below use a local variable speedLevel. This local variable is always = the operating speed. So what does the this->speedLevel += 1; at the bottom of the function do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this->speedLevel += 1 is for reporting. In the internal calculation, the speed level is 0-indexed. But to follow the reporting convention, speed level need to start from 1. So there is the shift in this->speedLevel.
|
|
rraustad
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All questions were sufficiently answered. @mitchute this looks ready.
|
I bumped the version numbers up to current. We can merge this after CI wraps up one last time. |
|
|
dareumnam
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rraustad, thanks so much for your review and input.
I built it locally, ran the newly added unit tests (all passed), and ran the created test files successfully, confirming the results match what Yujie explained. CI checks look good, diffs are explained and verified, comments have been addressed, and all related documentation has been updated. This one looks all set to go. @mitchute
|
OK, I made another quick review and made one final commit. We'll let CI finish, then merge this. |
|
|
|
Been waiting most of the day, but I think Decent CI is hung up here. Merging and moving on. Thanks all. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just have a couple of questions / suggestions. Sorry for dropping in late.
I'm guessing you tested this with real world manufacturer data?
A datasets/ file would be nice, or at least one example file should use proper data.
| Curve:Biquadratic, | ||
| CapCurveFuncTemp, !- Name | ||
| 0.5, !- Coefficient1 Constant | ||
| 0.0, !- Coefficient2 x | ||
| 0.0, !- Coefficient3 x**2 | ||
| 0.0, !- Coefficient4 y | ||
| 0.0, !- Coefficient5 y**2 | ||
| 0.0, !- Coefficient6 x*y | ||
| 5.0, !- Minimum Value of x | ||
| 10.0, !- Maximum Value of x | ||
| 24.0, !- Minimum Value of y | ||
| 35.0, !- Maximum Value of y | ||
| , !- Minimum Curve Output | ||
| , !- Maximum Curve Output | ||
| Temperature, !- Input Unit Type for X | ||
| Temperature, !- Input Unit Type for Y | ||
| Dimensionless; !- Output Unit Type | ||
|
|
||
| Curve:Biquadratic, | ||
| EIRCurveFuncTemp, !- Name | ||
| 1.0, !- Coefficient1 Constant | ||
| 0.0, !- Coefficient2 x | ||
| 0.0, !- Coefficient3 x**2 | ||
| 0.0, !- Coefficient4 y | ||
| 0.0, !- Coefficient5 y**2 | ||
| 0.0, !- Coefficient6 x*y | ||
| 5.0, !- Minimum Value of x | ||
| 10.0, !- Maximum Value of x | ||
| 24.0, !- Minimum Value of y | ||
| 35.0, !- Maximum Value of y | ||
| , !- Minimum Curve Output | ||
| , !- Maximum Curve Output | ||
| Temperature, !- Input Unit Type for X | ||
| Temperature, !- Input Unit Type for Y | ||
| Dimensionless; !- Output Unit Type | ||
|
|
||
| Curve:Quadratic, | ||
| EIRCurveFuncPLR, !- Name | ||
| 1.0, !- Coefficient1 Constant | ||
| 0.0, !- Coefficient2 x | ||
| 0.0, !- Coefficient3 x**2 | ||
| 0.0, !- Minimum Value of x | ||
| 1.0; !- Maximum Value of x |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for jumping late, i just noticed this PR dropping in develop yesterday and I am interested in the feature, as I have had to model AWHP before including some systems like the one mentioned in the PR's original post.
I'm a bit confused by these curves, and they seem really generic to mimic a real world system.
I'm sure the testfiles added are nice to ensure that a simulation runs and for coverage, but it's also an Example File, so does it mimic real world operation?
| EnergyManagementSystem:Actuator, | ||
| opModeAct_cooling, !- Name | ||
| test_AWHP, !- Actuated Component Unique Name | ||
| HeatPump:AirToWater:Cooling, !- Actuated Component Type | ||
| Operating Mode; !- Actuated Component Control Type | ||
|
|
||
| EnergyManagementSystem:OutputVariable, | ||
| Operating Model Output Cooling, !- Name | ||
| opModeAct_cooling, !- EMS Variable Name | ||
| Averaged, !- Type of Data in Variable | ||
| SystemTimeStep, !- Update Frequency | ||
| , !- EMS Program or Subroutine Name | ||
| ; !- Units | ||
|
|
||
| EnergyManagementSystem:ProgramCallingManager, | ||
| Change_OpMode_EMS_Program_Manager, !- Name | ||
| InsideHVACSystemIterationLoop, !- EnergyPlus Model Calling Point | ||
| Change_OpMode_EMS_Program; !- Program Name 1 | ||
|
|
||
| EnergyManagementSystem:Program, | ||
| Change_OpMode_EMS_Program, !- Name | ||
| IF (Hour <= 12), !- Program Line 2 | ||
| SET opModeAct_cooling = 0, !- <none> | ||
| ELSE, !- <none> | ||
| SET opModeAct_cooling = 1, !- <none> | ||
| ENDIF; !- <none> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get this EMS program here?
Again, this ends up being an Example File.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is some example EMS code for controlling the operating mode. Do you feel it's too simplified and better be removed? I can update the example in a followup PR.
| ! PlantLoopHeatPump_EIR_AirSource.idf | ||
| ! | ||
| ! Basic file description: | ||
| ! The EIR formulated air-to-water heat pump is demonstrated using a simple collection of plant loops. Building loads | ||
| ! are represented using Plant Load Profile objects | ||
| ! Run: 1 design day. | ||
| ! Building: None. | ||
| ! System: None. | ||
| ! Plant: PLANT LOAD PROFILE with District Heating and Cooling as necessary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The three testfiles added have exactly the same description. I feel like there should be be some difference here.
And the mention of the special shenanigans like the EMS program would probably be good for the heating/cooling only ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. I forgot to update the description. I will modify them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for catching this and for all your review! @jmarrec
Yes, a Daikin engineer is using their performance data to test the model. But they don't want to reveal their product data, so the one here uses very generic setting in the curves. I'll try to create another example with more realistic data. I'll create a followup PR to add it in. |


Pull request overview
Description of the purpose of this PR
Heat pumps are an essential technology for decarbonizing buildings. EnergyPlus is capable of modeling several types of heat pumps, e.g., for space cooling or heating: air to air, air to water, water to water; and heat pump water heaters. Although there is an existing feature to model air-to-water heat pumps in EnergyPlus, its capability is limited and its implementation is not straightforward compared with other types of HP. Some of the limitations include:
This feature will create a new air-to-water heat pump (AWHP) model that includes heating and cooling components in one single object, capable of multi-speed controls, and includes more equipment details such as fan characteristics, PLR ranges, availability schedules, etc.
About the extended internal data structure arrays
The following entried are added to the internal data structure to hold info about this new AWHP.
HeatPumpAirToWaterHeating,
HeatPumpAirToWater,
“PlantEquipmentType” in Enums.hh
"HeatPump:AirToWater:Heating",
"HeatPump:AirToWater",
“ConnectionObjectTypeNames” in BranchNodeConnections.cc
"HEATPUMP:AIRTOWATER:HEATING",
"HEATPUMP:AIRTOWATER",
“ConnectionObjectTypeNamesUC” in BranchNodeConnections.cc
Regression diffs
798 files have regression diffs
Select a representative one, for example, 5ZoneAirCooled, the diffs happen in
Pull Request Author
Reviewer