Unidata / MetPy

MetPy is a collection of tools in Python for reading, visualizing and performing calculations with weather data.

Home Page:https://unidata.github.io/MetPy/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Divergence equation in different coordinates? And derivative documentation is limited access, could someone add the finite differentiation scheme formulation or provide a different document?

TemporarySir opened this issue · comments

What can be better?

$\nabla \cdot U = \frac{\partial u}{\partial x} + \frac{\partial v}{\partial y}$ is the computation for the divergence in the documentation. The divergence function accepts quantities mapped in spherical coordinates though. We know that the divergence is not nearly as straightforward as this in different coordinate schemes, so I think it would be helpful for those trying to verify the computations if the conversions were added so the users can be certain exactly how these quantities are being computed. From Bijlsma, the computation for a horizontal wind field in spherical coordinates

$$\delta = \frac{1}{\sigma} \Big[\frac{\partial u}{\partial \lambda} + \frac{\partial \sigma v}{\partial \theta}\Big]$$. If the vector field were to have a $w$ component, it would be:

$$\nabla \cdot U(\lambda,\theta,r) = \frac{1}{r^2}\frac{\partial w}{\partial r} + \frac{1}{r\sigma} \Big[\frac{\partial u}{\partial \lambda}+\frac{\partial \sigma v}{\partial \theta}\Big]$$

The del operator is actually quite a fickle and annoying thing when moving between coordinate schemes it isn't just as simple as converting x and y distances to degrees/radians (which I'm suspecting might be the case), so the user being aware that this is known and accounted for in different coordinate schemes would be great for ease of mind for a user trying to verify the results.

Additionally, the formula using the finite differentiation would be a good addition to include for this and all different formulations because the documentation for Bowens 2005 is set to limited access, which also makes it difficult for users to verify the results for themselves. Either that or have the documentation all link back to the first_derivative and other differentiation functions used in the calc library and adding the finite differentiation formulae there, so we can see exactly how they work. Thank you!

I assume this is related to this Stack Overflow question (if so it would be really helpful to focus asking questions in a single venue rather than posting in multiple places--we the developers watch both).

As noted in that question, I don't think Bowen 2005 is truly relevant here; that article describes 3-point first and second derivative estimates using finite differencing that is appropriate for grids with non-uniform spacing. You can certainly take a look at the article. The formulation is:

image image

Which, bluntly, I did not feel like encoding into mathtext--and isn't exhaustive since you also need to add the forward/backward difference equations for the edges of the domain. PRs welcome to do so.

As far as the divergence appropriate to spherical (and projected) coordinates, you can see extensive discussion in #893. We've implemented similar to GEMPAK's implementation. Rather than explicit terms around spherical coordinates, we rely on map factors from PyProj, which gives us parallel_scale and meridional_scale. This allows us to implement that calculus in a fashion that is coordinate system agnostic. All of the "corrections" are wrapped up in the vector_derivative() function.

Thank you for getting back to me!

You're correct, as I was digging through and skimming documentation related to Divergence, I realize I misread the documentation for the first_derivative, this would not be relevant to me as someone who does not have irregular grid spacing. So it is a 3-point stencil (or centered): $$D[f] = \frac{f(x+\delta x)+f(x-\delta x)}{2\delta x}$$.

Also, thank you, I was trying to figure out where parallel_scale and meridional_scale were coming from when I looked through the source code. I am not all familiar with these terms mathematically speaking (how are they computed? what are their units? are they a ratio as "scale" in the name would imply?), nor did I see a computation of them in pyproj's documentation, they are simply user inputs so it is likely that they assume that the user knows exactly what they are, and the definitions provided are "meridional_scale – Meridional scale at coordinate" and "parallel_scale – Parallel scale at coordinate"; that doesn't really tell me anything. I don't know anything about "map factors" either other than they are the equivalent to the grid spacing $\partial x$ and $\partial y$, though I don't know what that means mathematically. I am simply outside of my depth here. I only know how to keep the coordinates in spherical and use geometric arguments to convert the m/s quantity to rad/s or deg/s and then differentiate along the deltas in degrees after working out the equation for divergence in spherical coordinates.

It would be a bit much to ask you to sit there and derive all of this out for me, so are there any resources you could point me to that could help me catch up on all of this? Also, if you think these resources are at all useful for me, would it be something you could provide a link to in the documentation to help users working with data gridded in different coordinate schemes?

And for future reference, is the vorticity computed by Metpy now computed using the equation provided in the thread you linked me? If so, could you provide that as well for the vorticity documentation? If not, then just ignore this.

Actually, your answer on stackexchange might have provided a good place to start HERE. So all of this comes from tensor analysis I'm assuming. I'll need to look more into it. Unless you have anything you'd like to add, you can probably close this and thank you for your time!

Yes, the vorticity computed by MetPy use the equation from that thread. The reference we were working from was the GEMPAK Appendix B2, which has the equation at the end. We were able to replicate GEMPAK results using meridional_scale for my and parallel_scale for mx.

Here are some useful spots in the PROJ source code for those factors:

https://github.com/OSGeo/PROJ/blob/356e255022cea47bf242bc9e6345a1e87ab1031d/src/factors.cpp#L77-L79

https://github.com/OSGeo/PROJ/blob/356e255022cea47bf242bc9e6345a1e87ab1031d/src/4D_api.cpp#L2971-L2986

To be honest, I never got to a point where I could derive this generally from first principles. We are relying heavily on our ability to reproduce results from GEMPAK for multiple model fields. I think this Wikipedia article should provide the math, but I never got there.

Let me respond to these 1-by-1

Got it! So it doesn't look exactly like $\nabla \times V = \frac{\partial v}{\partial x} - \frac{\partial u}{\partial y}$, if we're starting from non-Cartesian coordinates, it's a bit different. I think it would be good for the user to see this form in the documentation as it would clear up any confusion for those in globally gridded coordinates, and for any additional information they need, a link to the GEMPAK document should be good enough as a place for them to start.

For the code: thankfully the first code snippet is near the start, though I will admit it's been a while since I've used C (though this is C++). I'm guessing PJ_COORD and PJ_LP are defined somewhere in the header files this file imports from at the top. lp is some kind of parameter passed into pj_factors (which is the function we care about) and lp gets brought up frequently.

Not quite sure what fac ->der does in

fac->h = hypot(fac->der.x_p, fac->der.y_p);
fac->k = hypot(fac->der.x_l, fac->der.y_l) / cosphi;

but, from here x_p and x_l are derivatives of x for lambda and phi so I'm guessing $\frac{\partial x}{\partial \lambda}$ and so on for the other variables, and it looks like the hypotenuse is used to find the magnitude of the tangent vector in the direction of $\phi$. I'll need to go back over my vector calculus and draw out exactly what they're doing, just looking at it right now, I think it would look like

$$h = \sqrt{\Big(\frac{\partial y}{\partial \phi}\Big)^2+\Big(\frac{\partial x}{\partial \phi}\Big)^2}$$

$$k = \sqrt{\Big(\frac{\partial y}{\partial \lambda}\Big)^2+\Big(\frac{\partial x}{\partial \lambda}\Big)^2}$$

I might need to keep looking into this for a while, but this looks like the equation for a delta along a surface and I remember seeing this used heavily in line integration. Thank you for finding this!

For the wikipedia article on orthogonal vectors, I'll gladly look more into this from here. I myself need to get as accurate of a calculation as I can get for divergence so that I can use it to solve for other important dynamical features like velocity potential.

Unless there is anything else you wanted to add, we can close it here. Thank you for your help!

We can close I think. I'll say that our goal is to have as accurate a calculation as we can reliably do here, which is why the momentous amount of work that was discussed in #893 was something we embarked on. If you find there to be any errors or shortcomings in the current implementation, please do let us know.

Regarding the docs, since you're in the best place to know what you'd like to see, we'd be happy to see a PR adding additional information. We're always happy to have submissions and contributions from the community.