Conversation
didierthevenard
left a comment
There was a problem hiding this comment.
I reviewed only the C version and requested some changes: not enforce a minimum number of iterations and give some kind of error if the maximum number of iterations is exceeded.
src/c/psychrolib.c
Outdated
| #define INVALID -99999 // Invalid value | ||
| #define MIN_ITER_COUNT 3 // Minimum number of iterations before exiting while loops. | ||
|
|
||
| #define MAX_ITER_COUNT 1000 // Maximum number of iterations before exiting while loops. |
There was a problem hiding this comment.
100 or even 20 should be sufficient. 2^20 = 1e+06 so in any bisection that we are doing we should be below the convergence threshold. NR should converge in 3 to 5 iterations given the type of very smooth function we have to work with. What's more important is that if convergence is not reached in MAX_ITER_COUNT then the program should return an error.
There was a problem hiding this comment.
A couple of points about this I am not sure about:
- Are you proposing to have different MAX_ITER_COUNT in the two loops?
- I am not sure about throwing an error if MAX_ITER_COUNT is not reached. This is manly because there may be conditions where this is triggered but you do not necessarily want your program to stop abruptly. How about printing a warning instead?
There was a problem hiding this comment.
No, one MAX_ITER_COUNT for all loops. 20 should be enough, but put 100 is you want to be extra safe. And if it does not converge in 100 iterations then there is something seriously wrong and we need to have a look, therefore it's appropriate for the program to stop or return -99999. This is just defensive programming - we never expect to get there. If we did at the moment then the program would just hang. At least with a stop or -99999 it won't.
There was a problem hiding this comment.
OK for MAX_ITER_COUNT but I think that the underlying issue still remains -- for an example of no convergence you can try the following conditions:
import psychrolib as psy
psy.SetUnitSystem(psy.SI)
print(psy.GetTWetBulbFromRelHum(7, 0.61, 100000))There was a problem hiding this comment.
I have just looked at this in more details and I think it's now fixed in 52232e2.
The issue was with the the discontinuity of the saturated pressure curve at ~0 deg C (+/-) that leads to the calculation of dew point temperature to oscillate about the zero, thus not converging. If you assume a range of of +/-0.001, the vapour pressure at 0.001 deg C is 611.26 Pa and 611.10 Pa at -0.001 deg C I simply check if vapour pressure is within that range and break if the condition is met. Note that this will only happen when the loop index reaches the MAX_ITER_COUNT value.
psychrolib/src/python/psychrolib.py
Lines 452 to 457 in 4573c17
If for some reason it had not converged after that, I throw an exception (MAX_ITER_COUNT set to 100)
psychrolib/src/python/psychrolib.py
Lines 452 to 457 in 4573c17
I have now implemented this in Python only. If you are happy and there are no additional changes to make, I will propagate the changes to the other languages and add the tests to check this case too so that you can review them.
didierthevenard
left a comment
There was a problem hiding this comment.
Checked only the c version, the issues I have in the c version are likely similar in other languages.
src/c/psychrolib.c
Outdated
| #define INVALID -99999 // Invalid value | ||
|
|
||
| #define INVALID -99999 // Invalid value | ||
| #define MIN_ITER_COUNT 3 // Minimum number of iterations before exiting while loops. |
There was a problem hiding this comment.
I thought we had agreed to drop the minimum number of iterations?
src/c/psychrolib.c
Outdated
| #define INVALID -99999 // Invalid value | ||
| #define MIN_ITER_COUNT 3 // Minimum number of iterations before exiting while loops. | ||
|
|
||
| #define MAX_ITER_COUNT 1000 // Maximum number of iterations before exiting while loops. |
There was a problem hiding this comment.
Should be much lower, like 100
| while (fabs(Tdp - Tdp_c) > PSYCHROLIB_TOLERANCE); | ||
| while (((fabs(Tdp - Tdp_c) > PSYCHROLIB_TOLERANCE) && (index < MAX_ITER_COUNT)) | ||
| || (index < MAX_ITER_COUNT)); | ||
| return min(Tdp, TDryBulb); |
There was a problem hiding this comment.
The || (index < MAX_ITER_COUNT) part is wrong. The while loop should continue only when the first part of the test is satisfied, and the program should return an error if index > MAX_ITER_COUNT. I would actually remove the test on index from the while statement and put it in the body of the do loop.
|
I have just merged the changes from master but I had not acted on the minimum number of iterations yet or the other comments we had opened as I wanted to merge the fix in #26 first. |
More changes to make -- will send an update shortly
|
@didierthevenard can you please look at the py version only and let me know if that's OK (It may be easier to look at the src without diff due https://github.com/psychrometrics/psychrolib/blob/dmey/tighten-validity-checks/src/python/psychrolib.py). If so, I will make the changes for the other languages. Could you also please add a code snippet for the convergence tests for VBA. Here's the py one: psychrolib/tests/test_psychrolib_si.py Lines 79 to 89 in bc4393c |
|
I had a look at the py version and I think it's great. My only recommendation is to change the Will work on the vba test later today. |
|
VBA test has been added to branch djt/vba_convergence_test, I believe I have added you as a reviewer but if that has failed let me know. |
This PR adds test to check that the NR in GetTDewPointFromVapPres converges. This test was known problem in versions of PsychroLib <= 2.0.0
|
Superseded by #30. Closing. |
This PR tightens up checks for handling the minimum value of humidity ratio (now reset to no lower than 1e-7) as well issues with
GetTDewPointFromVapPresandGetTWetBulbFromHumRatiowhere two new checksMIN_ITER_COUNTandMAX_ITER_COUNTare introduced when evaluating the loop condition.MIN_ITER_COUNTchecks the minimum number of iterations before exiting the loops is no less than 3. AndMAX_ITER_COUNTchecks that the maximum number of iterations before exiting the loops is less than 1000. These numbers can be changes.All changes have now been propagated to all languages. All tests pass. For now I have added a simple test to check that the bounded humidity ratio is behaving as expected -- e.g.
GetTWetBulbFromHumRatio(25,1e-09,95461) == GetTWetBulbFromHumRatio(25,1e-07,95461)however do let me know if you want to add more tests and will do so.I have already tested VBA in Excel but not committed it yet as this is dependent to my previous PR (#23). Once #23 is merged, I will commit those tests too.
@didierthevenard can you please review this and let me know for any issues. Please review #23 first. Once this is in, I can prepare the new release. Thanks