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

Fix #8599 - Incorrect psychrometric calculation causes error #8833

Merged
merged 14 commits into from Sep 6, 2021

Conversation

jmarrec
Copy link
Contributor

@jmarrec jmarrec commented Jun 21, 2021

Pull request overview

  • Fix Incorrect psychrometric calculation causes error #8599 - Incorrect psychrometric calculation causes error
  • Change PsyPsatFnTemp to correctly use the triple-point of water (0.01°C) to evaluate the two equations 5 and 6 from ASHRAE HoF thus eliminating the discontinuity

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

@jmarrec jmarrec added the Defect Includes code to repair a defect in EnergyPlus label Jun 21, 2021
@jmarrec jmarrec self-assigned this Jun 21, 2021
Real64 constexpr convertJtoGJ = 1.0E-9; // Conversion factor for J to GJ
int constexpr MaxSpeedLevels = 10; // Maximum number of speed that supports
int constexpr ScheduleAlwaysOn = -1; // Value when passed to schedule routines gives back 1.0 (on)
Real64 constexpr TriplePointOfWaterTempKelvin = 273.16; // The triple point of water, in Kelvin
Copy link
Contributor Author

Choose a reason for hiding this comment

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

New constant

Comment on lines +975 to +976
if (std::abs(DY) < small) {
DY = small;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unrelated, but it's handy to put a debugger breakpoint... (We should have clang-format do that everywhere IMHO)

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed. It's standard practice but not enforced.

Comment on lines +576 to +531
if (icvg == 1) {
break;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the "Error Trap for the Discontinuous nature of PsyPsatFnTemp function (Sat Press Curve) at ~0 Deg C." since it's no longer discontinuous.

Copy link
Contributor

Choose a reason for hiding this comment

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

I vaguely remember this. It looks like the unit tests hits this so good there. Gotta check it though.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I remember this now, this is a check for where this used to have a problem. Now that the problem is corrected, this check is no longer needed.

Comment on lines +733 to +690
// Note: the ASHRAE Handbook of Fundamentals is being slightly inaccurate in its wording,
// and referring to Eq 5 applying to -100°C to 0°C and Eq 6 applying to 0°C to 200°C
// In fact, it is **not** 0°C, but the triple-point of water, which is 0.01°C. Evaluating the Eq 5 and 6 up to and from the triple-point
// is removing the discontinuity altogether.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

New note

Copy link
Contributor

Choose a reason for hiding this comment

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

I think you were actually the one that found this critical point. Nice!

Real64 const C5(0.20747825e-8); // Coefficient for TKel < KelvinConvK
Real64 const C6(-0.9484024e-12); // Coefficient for TKel < KelvinConvK
Real64 const C7(4.1635019); // Coefficient for TKel < KelvinConvK
} else if (Tkel < DataGlobalConstants::TriplePointOfWaterTempKelvin) { // Tkel >= 173.15, Tkel < 273.16 (0.01°C)
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 actual fix

Copy link
Contributor Author

Choose a reason for hiding this comment

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

image

@@ -780,21 +787,21 @@ namespace Psychrometrics {

// If below -100C,set value of Pressure corresponding to Saturation Temperature of -100C.
if (Tkel < 173.15) {
Pascal = 0.0017;
Pascal = 0.001405102123874164;
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 and I noted that the value below -100°C does not match the evaluation of the equation at -100°C. So align.

Comment on lines 814 to 771
// If above 200C, set value of Pressure corresponding to Saturation Temperature of 200C.
} else { // Tkel >= 173.15 // Tkel >= KelvinConv // Tkel > 473.15
Pascal = 1555073.745636215;
}
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 and I noted that the value below +200°C does not match the evaluation of the equation at +200°C. So align:

  • One value if using the ASHRAE method: 1555073.745636215
  • Another value if using the IF97 method : 1554671.8682698254
  • (the ASHRAE and IF97 equations give slightly different values at +200°C)

@jmarrec
Copy link
Contributor Author

jmarrec commented Jun 21, 2021

The json big diffs: I think the epregression script is unreasonable: https://github.com/NREL/EnergyPlusRegressionTool/blob/237b8a38c280fd0ce6563b6849ae51376e326d66/epregressions/runtests.py#L630-L643

It assumes an absolute difference > 0.0001 is a big diff. This for eg:

image

It's categorized as a big diff, but in fact it's a 1e-12 difference in %...

In [1]: f_1 = 30310597.103115804

In [2]: f_2 = 30310597.102913737

In [3]: abs(f_1 - f_2) > 0.00001
Out[6]: True

In [7]: (f_1 - f_2) / f_1
Out[7]: 6.6665528125937005e-12

@jmarrec
Copy link
Contributor Author

jmarrec commented Jun 21, 2021

The RefrigeratedWarehouse one seems to be unstable to begin with. Lots of warnings about Zone Air Heat Balance is out of balance. The biggest thing I noticed in the html diff are the initialization summary diffs, and especially the number of warmup days that goes from 8 to 17. I think that may be because it would go into the error trap at iter 4 before.
Simulation time stays about the same (47s to 52s).

Most of the small mathdiffs seem to be in the EIO, Warmup Convergence Information is slightly different.

+                                                                                                                                                      v
- Warmup Convergence Information,CORE_MID,SizingPeriod: CHICAGO ANN CLG .4% CONDNS WB=>MDB,0.2742978374,0.4207863935,Pass,Pass,0.2199779749,0.5291400272,Pass,Pass
+ Warmup Convergence Information,CORE_MID,SizingPeriod: CHICAGO ANN CLG .4% CONDNS WB=>MDB,0.2742978374,0.4207863935,Pass,Pass,0.2199779749,0.5291400273,Pass,Pass

@nrel-bot
Copy link

@jmarrec @lgentile it has been 28 days since this pull request was last updated.

@jmarrec jmarrec requested review from mitchute and Myoldmopar and removed request for mitchute July 23, 2021 12:09
@Myoldmopar Myoldmopar added this to the EnergyPlus 9.6 Release milestone Aug 6, 2021
```
/home/julien/Software/Others/EnergyPlus/tst/EnergyPlus/unit/Psychrometrics.unit.cc:452: Failure
The difference between result and expected_result is 496.82405055164901, which exceeds 0.001, where
result evaluates to -496.82405055164901,
expected_result evaluates to 0, and
0.001 evaluates to 0.001.
```
…rrespond to the value of the curve at these boundary temperatures
…alculated using the current method (IF97 or ASHRAE)**
@rraustad
Copy link
Contributor

rraustad commented Sep 5, 2021

This is important to be included. I'd vote for sooner than later. I can't recall all the details here but I think @jmarrec has hit the nail.

@rraustad
Copy link
Contributor

rraustad commented Sep 5, 2021

I'm OK with these changes. I am trying to think up a test to verify this works, other than a unit test. I do have a high degree of confidence in what this fixes,

@rraustad
Copy link
Contributor

rraustad commented Sep 5, 2021

@jmarrec help me out here, it's been a while. If this corrects an issue of T=0 C (or 0 - 0.1 C), then how could I verify that this now works? I am torn between accepting this and doing some tests to make sure this is correct. I see what you did here and it looks correct, I just need to verify before sending this home. Details.

@rraustad
Copy link
Contributor

rraustad commented Sep 5, 2021

Comparing outdoor weather data between this branch and develop doesn't show an obvious issue.

image

Yet, zooming in does show a difference.

image

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.

@Myoldmopar @mjwitte I recall the reason for this change and agree with these changes.

Pascal = std::exp(C1 / Tkel + C2 + Tkel * (C3 + Tkel * (C4 + Tkel * (C5 + C6 * Tkel))) + C7 * std::log(Tkel));

// If above freezing, calculate saturation pressure over liquid water.
} else if (Tkel <= 473.15) { // Tkel >= 173.15 // Tkel >= KelvinConv
} else if (Tkel <= 473.15) { // Tkel >= 173.15 // Tkel >= TriplePointOfWaterTempKelvin
Copy link
Contributor

Choose a reason for hiding this comment

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

The else if above is Tkel < Real64 constexpr TriplePointOfWaterTempKelvin = 273.16; and this is <= 473.15 ... oh yeah, this is the top end so comment is wrong.

Copy link
Contributor

Choose a reason for hiding this comment

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

These comments are a little confusing but a second looks shows they say what they said before with updates to what was changed. I'd say this is OK.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the comments provide little value overall here, but there were pre-existing. and they should be correct.

Pascal = std::exp(C8 / Tkel + C9 + Tkel * (C10 + Tkel * (C11 + Tkel * C12)) + C13 * std::log(Tkel));

// If above 200C, set value of Pressure corresponding to Saturation Temperature of 200C.
} else { // Tkel >= 173.15 // Tkel >= TriplePointOfWaterTempKelvin // Tkel > 473.15
Copy link
Contributor

Choose a reason for hiding this comment

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

So shouldn't this be the top end? 473.15 ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, it's only a comment issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same for this comment, these are each true and true as a whole.

@rraustad
Copy link
Contributor

rraustad commented Sep 5, 2021

Let's see what the follow up responses are before merging this one.

@rraustad
Copy link
Contributor

rraustad commented Sep 5, 2021

I'd say this is good except for lingering comments in code.

@rraustad
Copy link
Contributor

rraustad commented Sep 6, 2021

In the zoomed in plot above there is an outlier at X= -0.43128 (develop), Y= -0.10992 (this branch). This occurred on 4/3 19:07:30 at row 11669 (and similar point at row 11670 - 19:15:00). Plotting rows 11660 - 11680 shows the WB traces for both branches. This branch smooths out the calculated wet-bulb temperature.

image

Note: additional reports added to diagnose problem and corrective fix.

Output:Variable,Outside Air Inlet Node 1,System Node Humidity Ratio,detailed;
Output:Variable,Outside Air Inlet Node 1,System Node Pressure,detailed;
Output:Variable,Outside Air Inlet Node 1,System Node Wetbulb Temperature,detailed;
Output:Variable,Outside Air Inlet Node 1,System Node Dewpoint Temperature,detailed;

The outdoor conditions at this same time show that OA WB should be smooth and this branch shows the correct result. If I were to do this again I would use System Node OA temp instead of weather OAT to fill in the gaps in the zone timestep environment report. But this is good enough to show this branch corrects the problem.

image

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.

Code reviewed and tested using example file. Results show an improvement in calculated wet-bulb temperature.

@rraustad rraustad merged commit cf82e98 into develop Sep 6, 2021
@rraustad rraustad deleted the 8599_PsychError_SmoothPsat branch September 6, 2021 16:38
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.

Incorrect psychrometric calculation causes error
7 participants