Skip to content

Commit

Permalink
Implement Jacobian determinant
Browse files Browse the repository at this point in the history
Closes Unidata#2356 as it implements an equivalent to GEMPAK's JCBN
function.  The approach is modeled on the deformation calculations.
  • Loading branch information
sgdecker committed Mar 5, 2024
1 parent 7254801 commit 77bcb91
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 8 deletions.
12 changes: 6 additions & 6 deletions docs/userguide/gempak.rst
Original file line number Diff line number Diff line change
Expand Up @@ -493,12 +493,12 @@ blue is uncertain of parity, and white is unevaluated.
<td></td>
</tr>
<tr>
<td>JCBN(S1, S2)</td>
<td>Jacobian determinant</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td class="tg-implemented">JCBN(S1, S2)</td>
<td class="tg-implemented">Jacobian determinant</td>
<td class="tg-implemented"><a href="../api/generated/metpy.calc.jacobian.html#metpy.calc.jacobian">metpy.calc.jacobian</a></td>
<td class="tg-yes">Yes</td>
<td class="tg-yes">Yes</td>
<td class="tg-yes">Yes</td>
</tr>
<tr>
<td class="tg-implemented">KNTS(S)</td>
Expand Down
61 changes: 59 additions & 2 deletions src/metpy/calc/kinematics.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,64 @@ def total_deformation(u, v, dx=None, dy=None, x_dim=-1, y_dim=-2, *,
return np.sqrt((dvdx + dudy)**2 + (dudx - dvdy)**2)


@exporter.export
@parse_grid_arguments
@preprocess_and_wrap(wrap_like='u', broadcast=('u', 'v', 'parallel_scale', 'meridional_scale'))
@check_units('[speed]', '[speed]', '[length]', '[length]')
def jacobian(u, v, dx=None, dy=None, x_dim=-1, y_dim=-2, *,
parallel_scale=None, meridional_scale=None):
r"""Calculate the Jacobian determinant of scalar quantities u and v.
Parameters
----------
u : (..., M, N) `xarray.DataArray` or `pint.Quantity`
first scalar quantity (often the x component of the wind)
v : (..., M, N) `xarray.DataArray` or `pint.Quantity`
second scalar quantity (often the y component of the wind)
Returns
-------
(..., M, N) `xarray.DataArray` or `pint.Quantity`
Jacobian Determinant
Other Parameters
----------------
dx : `pint.Quantity`, optional
The grid spacing(s) in the x-direction. If an array, there should be one item less than
the size of `u` along the applicable axis. Optional if `xarray.DataArray` with
latitude/longitude coordinates used as input.
dy : `pint.Quantity`, optional
The grid spacing(s) in the y-direction. If an array, there should be one item less than
the size of `u` along the applicable axis. Optional if `xarray.DataArray` with
latitude/longitude coordinates used as input.
x_dim : int, optional
Axis number of x dimension. Defaults to -1 (implying [..., Y, X] order). Automatically
parsed from input if using `xarray.DataArray`.
y_dim : int, optional
Axis number of y dimension. Defaults to -2 (implying [..., Y, X] order). Automatically
parsed from input if using `xarray.DataArray`.
parallel_scale : `pint.Quantity`, optional
Parallel scale of map projection at data coordinate. Optional if `xarray.DataArray`
with latitude/longitude coordinates and MetPy CRS used as input. Also optional if
longitude, latitude, and crs are given. If otherwise omitted, calculation will be
carried out on a Cartesian, rather than geospatial, grid. Keyword-only argument.
meridional_scale : `pint.Quantity`, optional
Meridional scale of map projection at data coordinate. Optional if `xarray.DataArray`
with latitude/longitude coordinates and MetPy CRS used as input. Also optional if
longitude, latitude, and crs are given. If otherwise omitted, calculation will be
carried out on a Cartesian, rather than geospatial, grid. Keyword-only argument.
See Also
--------
gradient
"""
(dudx, dudy), (dvdx, dvdy) = vector_derivative(
u, v, dx=dx, dy=dy, x_dim=x_dim, y_dim=y_dim, parallel_scale=parallel_scale,
meridional_scale=meridional_scale)
return dudx * dvdy - dudy * dvdx


@exporter.export
@parse_grid_arguments
@preprocess_and_wrap(wrap_like='scalar',
Expand All @@ -374,8 +432,7 @@ def advection(
y_dim=-2,
vertical_dim=-3,
parallel_scale=None,
meridional_scale=None
):
meridional_scale=None):
r"""Calculate the advection of a scalar field by 1D, 2D, or 3D winds.
If ``scalar`` is a `xarray.DataArray`, only ``u``, ``v``, and/or ``w`` are required
Expand Down

0 comments on commit 77bcb91

Please sign in to comment.