Repository navigation
Conversation
|
@mitchute I am testing this change for diffs. It may not fix the issue entirely but it seems to be a reasonable alternative for the previous assumption. |
|
|
| mixer.OutletPressure += mixer.InletPressure(InletNodeNum) / mixer.NumInletNodes; | ||
| mixer.OutletEnthalpy += mixer.InletEnthalpy(InletNodeNum) / mixer.NumInletNodes; | ||
| mixer.OutletTemp += mixer.InletTemp(InletNodeNum) / mixer.NumInletNodes; | ||
| } |
There was a problem hiding this comment.
If choice of the first branch on the mixer to pass conditions to the outlet when mass flow = 0 is arbitrary, and prone to cause diffs when branch order is switched, then using the average conditions of all branches is a better "arbitrary" choice and less prone to branch order diffs.
|
|
|
@rraustad, the fix here is "working," in the sense that it removes the dependence on mixer inlet order. Under no-flow conditions, the mixer outlet is now set to the average of the mixer inlet states rather than simply forwarding the state of the first inlet. The table below was generated by running
However, looking at the regression results, this change is producing significant differences in energy use and system operation for some files. For example,
Conceptually, when there is no flow through the mixer, the outlet state doesn't (shouldn't?) have meaning. By propagating or averaging those values, we are assigning that information anyway, and it's obviously getting consumed somewhere downstream. I would like to think through this a bit more before merging. |
|
@rraustad to try to move this one forward, I spent some time this afternoon thinking about it. Instead of averaging the inlet node conditions when flow is zero, another option might be to latch the zero-flow mixer outlet conditions to the previous outlet conditions when flow was non-zero. 4746dae was my attempt. I'm not sure it's any better from a results perspective, but maybe (in my mind at least) it's a slightly more palatable explanation of how to do this. We can revert it if you or others would rather stick with the inlet averaging approach. |
|
|
|
@rraustad I think you had this right the first time. I'll post a more detailed review of results later, but I think inlet averaging is the right approach (rather than latching to the past timestep). That, at least, will not affect single-inlet system results. |
|
|
Annual regression resultsSummary: The branch's effect on annual energy is small. Of 825 files, 173 have big diffs, and 162 of those change total site energy by less than 0.01%. Only CompSetPtControl (−0.34%) and HybridVentilationControl (−0.10%) change by more than 0.1%, and no file changes by 0.5% or more. Every file with big diffs contains an The diffs come from the change to zero-flow mixer outlet conditions. Develop takes them from the last inlet in the mixer's list, so the result depends on inlet order. The branch averages the inlets using the last flow fractions. These outlet conditions are the airloop state when equipment turns on, so they shift chiller staging, hybrid ventilation switching and morning start in a few hours, with a small effect over the year. Run status
Total site energy change (Annual Building Performance Summary)
Files with a site energy change above 0.01%
The largest change in any other file is 0.005%. Unmet hours: 25 facility-level changes in occupied heating or cooling unmet hours, none larger than 1.34 h (DXCoilSystemAuto and UnitarySystem_DXCoilSystemAuto: 648.83 → 650.17 h cooling). Warnings: Most changes are a few messages either way. The larger ones:
_FanCoilHybridVentAFN (test-only file): warmup convergence On the branch, RUN PERIOD 2 (07/07–07/11) needs 25 warmup days instead of 8 and ends with three
From 03:30 to 06:40, the West zone hybrid ventilation controller switches between natural ventilation and the fan coil within single timesteps. That controller has no air loop, and the West zone isn't connected to the mixer. Small changes on the air-loop side are enough to keep warmup from settling. Develop converges only with the inlet order in the IDF, which is the order dependence from #6508 that this PR removes. The branch gives the same result for either order. @rraustad this is as far as I plan to go on this one. I'm comfortable with the inlet averaging strategy, but it does result in a lot of diffs, which at this point I believe are all explained by the particulars of each file and how sensitive their specific controls are. |
|
|
||
| auto &mixer = state.dataMixerComponent->MixerCond(MixerNum); | ||
|
|
||
| if (state.dataGlobal->BeginEnvrnFlag && mixer.InletFlowFracResetAtBeginEnv) { |
There was a problem hiding this comment.
Resetting the averaging at the beginning of each environment.
| for (InletNodeNum = 1; InletNodeNum <= mixer.NumInletNodes; ++InletNodeNum) { | ||
| mixer.InletFlowFraction(InletNodeNum) = mixer.InletMassFlowRate(InletNodeNum) / mixer.OutletMassFlowRate; | ||
| } |
There was a problem hiding this comment.
Weight the outlet based each inlet branch's fraction of total flow.
| // Mass flow in air loop is zero and loop is not operating. | ||
| // Use the last active inlet flow fractions with the current inlet conditions. Before flow history exists, | ||
| // the fractions are equal (set at the start of each environment). | ||
| mixer.OutletHumRat = 0.0; | ||
| mixer.OutletPressure = 0.0; | ||
| mixer.OutletEnthalpy = 0.0; | ||
| for (InletNodeNum = 1; InletNodeNum <= mixer.NumInletNodes; ++InletNodeNum) { | ||
| mixer.OutletHumRat += mixer.InletFlowFraction(InletNodeNum) * mixer.InletHumRat(InletNodeNum); | ||
| mixer.OutletPressure += mixer.InletFlowFraction(InletNodeNum) * mixer.InletPressure(InletNodeNum); | ||
| mixer.OutletEnthalpy += mixer.InletFlowFraction(InletNodeNum) * mixer.InletEnthalpy(InletNodeNum); | ||
| } | ||
| // A single inlet passes its temperature through so the outlet matches the inlet exactly | ||
| mixer.OutletTemp = (mixer.NumInletNodes == 1) ? mixer.InletTemp(1) : PsyTdbFnHW(mixer.OutletEnthalpy, mixer.OutletHumRat); |
There was a problem hiding this comment.
Average the inlet conditions here.
| outletNode.CO2 = 0.0; | ||
| for (InletNodeNum = 1; InletNodeNum <= mixer.NumInletNodes; ++InletNodeNum) { | ||
| outletNode.CO2 += mixer.InletFlowFraction(InletNodeNum) * state.dataLoopNodes->Node(mixer.InletNode(InletNodeNum)).CO2; | ||
| } |
There was a problem hiding this comment.
Include CO2 and generic contam here, too.
|
|





Pull request overview
Description of the purpose of this PR
User reported diffs when the only change in an input file was the order of mixer/splitter branch order. When flow rate is 0, instead of choosing the first inlet branch conditions as the outlet branch conditions, average the inlet branch conditions to determine the output branch condition. If using the first branch is arbitrary, then averaging the branches is also a reasonable outcome.
Pull Request Author
Reviewer