-
Notifications
You must be signed in to change notification settings - Fork 392
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
New Feature Runaround Heat Recovery Loop #8520
Conversation
…-runaround-heat-recovery-loop
1. Connect 2 water cooling coils in a typical plant configuration. With one coil on the demand side of the plant loop while the other is a supply side component. This would allow alternate configurations if desired. For example to allow a boiler, chiller, evap cooler, etc. on the supply side which maintains a certain temperature to the supply side coil. Although I can't think of a reason to do this, it seems like a very flexible way to achieve the goal for a run-around coil application. A user could create a plant loop and then add two coils and a pump. | ||
|
||
**Pro:** This approach may require minimal changes to the IDD (the PlantLoop field for Plant Equipment Operation Scheme Name is required). Would provide flexibility in configuration. Pipe losses could be modeled. | ||
**Con:** The coil model would use ControlcompOutput as the solution algorithm. The air-side and water-side calculations would be disassociated the same as water coils on a branch are currently modeled. |
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.
Why would it need to use ControlCompOutput? Seems like a versatile coil controller that can switch between heating and cooling is the main thing to do here and it could use root solver.
Plant loop approach can also provide autosizing, support for different glycol mixtures, different pumping arrangements, pump heat to fluid modeling, and ability to combine multiple air handlers.
![RunaroundCoilLoop](RunaroundCoilHXLoop.png) | ||
## *Figure 1. Run around coil loop schematic.* ## | ||
|
||
Figure 2 shows an example run-around coil design for winter and summer operation. During the heating season (Inset A), heat extracted from the exhaust air stream (EA) |
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.
Exhaust air stream is interesting. If there is scope would be interesting to be able to put a coil in the outlet of each zone exhaust fan.
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 have a related new feature task for "Dedicated Airstreams to Model General Exhaust Fans" so it should be possible to design that to work with this.
**Pro:** This approach may require minimal changes to the IDD (the PlantLoop field for Plant Equipment Operation Scheme Name is required). Would provide flexibility in configuration. Pipe losses could be modeled. | ||
**Con:** The coil model would use ControlcompOutput as the solution algorithm. The air-side and water-side calculations would be disassociated the same as water coils on a branch are currently modeled. | ||
|
||
I'm not yet sure if objects other than the PlantLoop are even needed for a loop with 2 coils and a pump. Without a plant component (e.g., boiler or chiller) would the other typical plant objects shown here even be needed? |
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 suspect some kind of operation scheme will be needed, probably Uncontrolled or ComponentSetpoint
5 similar comments
I think the best performance review of this model is to compare the heat exchange of the two water coils to ensure they are equal and opposite in magnitude. The new example file, with a water cooling coil at the OA mixer's OA inlet and another at the relief air outlet, shows this characteristic over the annual simulation and also during a three week winter period. HR COOLING COIL 1 (blue) is the coil in the outdoor air stream and is heating the incoming outdoor air while the other coil is cooling the exhaust air. |
@@ -287,9 +286,6 @@ namespace UnitarySystems { | |||
int m_HeatRecoveryOutletNodeNum; | |||
int m_DesignSpecMSHPIndex; | |||
Real64 m_NoLoadAirFlowRateRatio; | |||
Real64 m_IdleMassFlowRate; | |||
Real64 m_IdleVolumeAirRate; // idle air flow rate [m3/s] | |||
Real64 m_IdleSpeedRatio; |
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 have wanted to get rid of these for a while now. When a new developer comes in they create their own new model variables instead of using existing, when the existing would work just as well. Running into the memory issue I had gave me the incentive. Idle flow rate is the same as NoLoad or NoCoolHeat variables so I just substituted and eliminated these.
@@ -195,7 +195,6 @@ namespace UnitarySystems { | |||
|
|||
UnitarySysInputSpec original_input_specs; | |||
int m_UnitarySysNum; | |||
int m_unitarySystemType_Num; |
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.
Another variable that wasn't used anywhere.
} else { | ||
this->enableHRLoop = false; | ||
} | ||
} |
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.
In Init the model checks the limits and either sets temperatureOffsetControlStatus to 0 or 1.
src/EnergyPlus/UnitarySystem.cc
Outdated
this->m_IdleVolumeAirRate = this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio; | ||
this->m_IdleMassFlowRate = this->m_IdleVolumeAirRate * state.dataEnvrn->StdRhoAir; | ||
this->m_IdleSpeedRatio = this->m_IdleVolumeAirRate / this->m_DesignFanVolFlowRate; | ||
if (MSHPIndex > -1) { |
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.
Note the change from 0 to -1 here. That was a mistake from the get go. designSpecMSHP is 0 based.
src/EnergyPlus/UnitarySystem.cc
Outdated
@@ -3218,7 +3252,7 @@ namespace UnitarySystems { | |||
} | |||
|
|||
// Early calls to ATMixer don't have enough info to pass GetInput. Need to get the data next time through. | |||
if (sysNum == -1 || !state.dataZoneEquip->ZoneEquipInputsFilled) { | |||
if (sysNum == -1 && !state.dataZoneEquip->ZoneEquipInputsFilled) { |
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.
!state.dataZoneEquip->ZoneEquipInputsFilled means it is too early for zone equipment or maybe even air loop equipment with a control zone that needs zone node data. The old logic said to return anytime a new instance of the UnitarySystem exists when if all the data is available data gathering should continue. I think sysNum == -1 isn't even needed now but too chicken to remove it.
src/EnergyPlus/UnitarySystem.cc
Outdated
@@ -3521,7 +3555,7 @@ namespace UnitarySystems { | |||
} | |||
|
|||
// check if the UnitarySystem is connected to an outside air system | |||
if (!AirLoopFound && state.dataSize->CurOASysNum > 0) { | |||
if (!AirLoopFound && state.dataAirLoop->NumOASystems > 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.
If we are going to look through the OA system components then it does not matter if this model is called from the OA system or not, the end result is if the UnitarySystem resides there, not that it was called from there.
src/EnergyPlus/UnitarySystem.cc
Outdated
// set water-side economizer flag | ||
thisSys.m_waterSideEconomizerFlag = true; | ||
|
||
thisSys.processInputSpec(state, input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum); |
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.
New CoilSystem:Cooling:Water inputs are processed normally in processInputsSpec and then inputs specific to the heat recovery model are processed after this point.
Ah ha. In develop branch, in function setOnOffMassFlowRate, I put a break point at all the lines with MaxNoCoolHeatAirMassFlow. These break points should never get hit for this multi-speed coil file. So this coil model (Coil:Cooling:DX) is using the wrong no load condition air flow rate. I suspect that the variable m_MultiOrVarSpeedHeatCoil never got set for this new model when number of speeds > 1. Now that there is no longer m_IdleMassFlowRate variable this logic will get easier.
|
Example of correction to results with this branch. Sys 2 has a blank for No Load Supply Air Flow Ratio, which defaults to 1. This means the no load air flow rate should be at the maximum flow rate. In develop, the flow rate would operate at the MaxNoCoolHeatAirMassFlowRate, not the m_IdleMassFlowRate. These are the numbers from the develop branch debugger: this->Name = Sys 2 Furnace DX Cool Unitary System
In fact, in develop the no load air flow rate was actually operating at the 2nd speed cooling air flow rate (0-based index issue?). Additionally, since this difference was at a no load condition, this operation did not significantly affect other output reports in this file and was easily overlooked as being an issue since an air flow report was not included, except that the html file showed diffs in mech vent numbers. In this branch: |
idd/Energy+.idd.in
Outdated
@@ -49491,87 +49491,6 @@ Coil:Cooling:Water:DetailedGeometry, | |||
\note higher than the coil design outlet air temperature, then the design inlet water temperature | |||
\note value is reset to coil design outlet air temperature minus 5.0 DeltaC. | |||
|
|||
CoilSystem:Cooling:Water, |
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.
Not sure what happened when this was merged in. This is somewhat nit-picking, but this object should stay where it is in the idd.
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 saw some discussion of moving this CoilSystem object next to CoilSystem:Cooling:DX and moved my version. Then I saw that was a docs discussion and didn't move it back. I'll do that shortly.
idd/Energy+.idd.in
Outdated
@@ -49499,6 +49499,7 @@ CoilSystem:Cooling:Water, | |||
\min-fields 10 | |||
A1, \field Name | |||
\required-field | |||
\reference WaterCoilSystemName |
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 assume this should not be here?
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.
Correct
Really? Now it's the UsingEnergyPlusForCompliance doc that fails. Did someone tape a sign on my back? |
@mjwitte I logic'd these reports out of the new example file. The CoilSystem:Cooling:DX didn't report anything before hence the previous logic, now the new example file does and I missed the subtle change here. Why not just report these out for the parent since the coil doesn't report all of these (as a direct line item). This branch included.
|
…/NREL/EnergyPlus into NFP-runaround-heat-recovery-loop
Opted for 0 diffs and we will address this in the near future. |
I didn't pay close attention to the sizing outputs when Coilsystem:Cooling:Water went in. The wrapper doesn't size anything (same as CoilSystem:Cooling:DX), so they shouldn't be reporting any sizing results. |
I am up to date with all comments up to this point. |
Tracking my way through the conversation, it looks like this has been scrutinized pretty heavily and comments addressed thoroughly, and CI is reasonably happy. I will take a look at the changes now and get it building locally with latest develop. Anything else I should know as I review? |
No, good to go after review. Diff's have been explained and justified. |
Pulled develop in, all tests passing and regressions locally are still inline with what CI last showed. Doing a final look over the code changes but I suspect this will merge shortly. |
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.
No problems here, this is good to go.
|
||
if (present(heatRecoveryCoil)) { | ||
state.dataWaterCoils->WaterCoil(CoilNum).heatRecoveryCoil = heatRecoveryCoil; | ||
} |
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.
Another optional isn't great, but it would be a big effort to modify now and not worth holding anything up.
Thanks @rraustad and everyone who reviewed! |
Pull request overview
Fixes #8966 through code clean up.
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.
[ ] 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 DevSupportIf 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 labelReviewer
This will not be exhaustively relevant to every PR.