-
Notifications
You must be signed in to change notification settings - Fork 415
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
Prevent frontogenesis from returning nans #3696
Conversation
Ideas on how to make my test pass would be greatly appreciated! |
a2f713c
to
98d632d
Compare
Fixes #3768 by making sure the argument to the arcsin function is valid. Previously, frontogenesis could return nans when there was a constant theta field (division by zero would occur) or if round-off error resulted in the argument to arcsin being slightly outside the valid domain of the function (-1 to 1). In this commit, edits are made to set points to zero where nans occur due to division by zero (the frontogenesis is zero when the magnitude of the theta gradient is zero anyway) and to use np.clip to ensure the argument to arcsin is valid. I could not come up with a simplified test case that triggers the round-off error issue with arcsin, but I do include a test case for the constant theta situation. Because the test case results in a division by zero by design, it is currently failing since that triggers a RuntimeWarning.
98d632d
to
12f4285
Compare
Cleaning up numerical issues like division by zero and round-off error after the fact are kludges, so this commit replaces the previous approach with more careful numerics.
Thanks @DWesl for the helpful comments that made the final version of this really nice. |
@@ -567,9 +567,18 @@ def frontogenesis(potential_temperature, u, v, dx=None, dy=None, x_dim=-1, y_dim | |||
|
|||
# Compute the angle (beta) between the wind field and the gradient of potential temperature | |||
psi = 0.5 * np.arctan2(shrd, strd) |
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 you're interested in eliminating all trig:
We have psi
next line to find
We show later that
This lets you replace three trig functions and a multiplication with three or four multiplications, three additions, three square roots, and a division, and four trips through the data with eight. I have no idea whether the eliminating the trig calls makes up for the extra trips through the data.
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 ran through that too and wasn't wild about all the square roots. I'm not passionate about trying it but if someone wants to see about performance/accuracy, I'd entertain it.
Description Of Changes
Previously, frontogenesis could return nans when there was a constant theta field (division by zero would occur) or if round-off error resulted in the argument to arcsin being slightly outside the valid domain of the function (-1 to 1). In this commit, edits are made to set points to zero where nans occur due to division by zero (the frontogenesis is zero when the magnitude of the theta gradient is zero anyway) and to use np.clip to ensure the argument to arcsin is valid.
I could not come up with a simplified test case that triggers the round-off error issue with arcsin, but I do include a test case for the constant theta situation. Because the test case results in a division by zero by design, it is currently failing since that triggers a RuntimeWarning.
Checklist