-
Notifications
You must be signed in to change notification settings - Fork 18
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
velocity to strain rate with gauge length support #399
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #399 +/- ##
=======================================
Coverage 99.84% 99.84%
=======================================
Files 109 109
Lines 8788 8843 +55
=======================================
+ Hits 8774 8829 +55
Misses 14 14
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
dascore/transform/strain.py
Outdated
patch = differentiate.func(patch, dim="distance", order=order) | ||
data = patch.data / distance_step |
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.
@d-chambers can you please double check if we need to divide by gauge length 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.
We don't actually need this; numpy.grad takes a dx parameter to properly normalize in that function call. This makes me feel better, I was worried the outputs were scaled wrong 😓.
I have an idea for making both order and gauge_length to work together. I will try to find time later this week to think more about it and work on it. |
Ok @ahmadtourei, If you have a chance take a look at this. It allows I think it is probably worth keeping |
closes #399 |
eg: an array of [a b c d e] uses b and d to calculate diff of c when | ||
step = 1 and order = 2. When step = 2, a and e are used to calcualte | ||
diff at c. |
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.
So, when step=1
and order=2
(same as how the Patch.velocity_to_strain_rate
function used to work before), does it mean technically gauge_length = 2 * distance step
?
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.
Yes, you are right. The gauge length should be 2*dx in the original function.
It looks good to me but it seems the data outputs of both functions are not similar. I even noticed some changes in polarity for the same channels of the resulting array from each method. Here I'm including a test (that currently breaks) for further investigation. def test_compare_two_funcs(self, terra15_das_patch):
g_m = 1
out1 = terra15_das_patch.velocity_to_strain_rate_cd(gauge_multiple=g_m)
out2 = terra15_das_patch.velocity_to_strain_rate(gauge_multiple=g_m)
dist1 = int(np.floor(g_m / 2))
dist2 = -int(np.ceil(g_m / 2))
out2_selected = out2.select(distance=(dist1, dist2), samples=True)
assert np.allclose(out1.data, out2_selected.data, rtol=1e-03, atol=1e-05) Also, I think we need to change the name of the second function as it actually does a central differentiation. The reference below illustrates what I implemented in the second function (eq. 2): Therefore, I agree we need to keep both functions. |
Yes, that is odd. Looking at the second function more closely, it should be doing exactly what the first function does when gauge_multiple = 1 and order =2, except the edges are handled differently as we already discussed, I will look into it more closely. |
I have some insight. Consider this simple grid of numbers turned into a patch with distance_step = 1 where distance corresponds to axis 1. [ [8, 6, 7, 5],
[[ -3.5 -0.5 -0.5 -3.5]
[[-2. 1. -2.] The first function is estimating the strain at a point x using the neighboring points: the second function is estimating the strain between two points: so naturally there will be some differences. When given a patch made of a nicely behaved analytical function, like the test I just added, they produce the same (expected) results. As for renaming the second function, you are right. Tentatively, I have called it |
I also renamed |
Isn't this the same as the case when the gauge length is actually Also, it seems |
I think what should be happening when step_multiple = 2 is this for function 1: and this for function 2: Consider this evenly spaced array: [a, b, c, d, e] When step_multiple = 2, the first function calculates the strain at c via: (e - a) / 4 dx The second function doesn't estimate strain at c, it can only estimate strain between c and d via (e - b) / 3 dx Does that make sense?
Yes, good point. |
I think this for function 2 should be ( So, it actually estimates at c: However, when
Also, to me, this looks like a step_multiple of 4 as we are averaging over 4*dx (not considering the order effect) |
So basically, function 1 with |
Yes, you are right. Function 2 produced the same output as function 1 when its def test_equal_cases(self, terra15_das_patch):
for mult in range(1, 20):
# Get function 1s output and trim off edges
out1 = (
terra15_das_patch
.velocity_to_strain_rate(step_multiple=mult)
.select(distance=(mult, -mult), samples=True)
)
# function 2's output should match function 1 when its step is double
out2 = terra15_das_patch.staggered_velocity_to_strain_rate(step_multiple=2*mult)
assert np.allclose(out1.data, out2.data) Summary
|
Here are my thoughts on how to move this forward. First, reflecting on what users might want and future DASCore plans:
So here is what I propose:
What do you think? |
Thanks for the discussion, Derrick! As we discussed today, let's keep |
Thanks @ahmadtourei. This findiff documentation page might be helpful for better understanding the edge stencil implementations. |
Thanks @ahmadtourei for all your work on this. |
Description
This PR addresses #396 by adding a new
velocity_to_strain_rate
patch function that changes data shape and supports higher gauge lengths.We plan to combine the two of the
velocity_to_strain_rate
functions for a more general function in the future.Checklist
I have (if applicable):