Skip to content

Commit 77bcb91

Browse files
committed
Implement Jacobian determinant
Closes #2356 as it implements an equivalent to GEMPAK's JCBN function. The approach is modeled on the deformation calculations.
1 parent 7254801 commit 77bcb91

File tree

2 files changed

+65
-8
lines changed

2 files changed

+65
-8
lines changed

docs/userguide/gempak.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -493,12 +493,12 @@ blue is uncertain of parity, and white is unevaluated.
493493
<td></td>
494494
</tr>
495495
<tr>
496-
<td>JCBN(S1, S2)</td>
497-
<td>Jacobian determinant</td>
498-
<td></td>
499-
<td></td>
500-
<td></td>
501-
<td></td>
496+
<td class="tg-implemented">JCBN(S1, S2)</td>
497+
<td class="tg-implemented">Jacobian determinant</td>
498+
<td class="tg-implemented"><a href="../api/generated/metpy.calc.jacobian.html#metpy.calc.jacobian">metpy.calc.jacobian</a></td>
499+
<td class="tg-yes">Yes</td>
500+
<td class="tg-yes">Yes</td>
501+
<td class="tg-yes">Yes</td>
502502
</tr>
503503
<tr>
504504
<td class="tg-implemented">KNTS(S)</td>

src/metpy/calc/kinematics.py

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,64 @@ def total_deformation(u, v, dx=None, dy=None, x_dim=-1, y_dim=-2, *,
356356
return np.sqrt((dvdx + dudy)**2 + (dudx - dvdy)**2)
357357

358358

359+
@exporter.export
360+
@parse_grid_arguments
361+
@preprocess_and_wrap(wrap_like='u', broadcast=('u', 'v', 'parallel_scale', 'meridional_scale'))
362+
@check_units('[speed]', '[speed]', '[length]', '[length]')
363+
def jacobian(u, v, dx=None, dy=None, x_dim=-1, y_dim=-2, *,
364+
parallel_scale=None, meridional_scale=None):
365+
r"""Calculate the Jacobian determinant of scalar quantities u and v.
366+
367+
Parameters
368+
----------
369+
u : (..., M, N) `xarray.DataArray` or `pint.Quantity`
370+
first scalar quantity (often the x component of the wind)
371+
v : (..., M, N) `xarray.DataArray` or `pint.Quantity`
372+
second scalar quantity (often the y component of the wind)
373+
374+
Returns
375+
-------
376+
(..., M, N) `xarray.DataArray` or `pint.Quantity`
377+
Jacobian Determinant
378+
379+
Other Parameters
380+
----------------
381+
dx : `pint.Quantity`, optional
382+
The grid spacing(s) in the x-direction. If an array, there should be one item less than
383+
the size of `u` along the applicable axis. Optional if `xarray.DataArray` with
384+
latitude/longitude coordinates used as input.
385+
dy : `pint.Quantity`, optional
386+
The grid spacing(s) in the y-direction. If an array, there should be one item less than
387+
the size of `u` along the applicable axis. Optional if `xarray.DataArray` with
388+
latitude/longitude coordinates used as input.
389+
x_dim : int, optional
390+
Axis number of x dimension. Defaults to -1 (implying [..., Y, X] order). Automatically
391+
parsed from input if using `xarray.DataArray`.
392+
y_dim : int, optional
393+
Axis number of y dimension. Defaults to -2 (implying [..., Y, X] order). Automatically
394+
parsed from input if using `xarray.DataArray`.
395+
parallel_scale : `pint.Quantity`, optional
396+
Parallel scale of map projection at data coordinate. Optional if `xarray.DataArray`
397+
with latitude/longitude coordinates and MetPy CRS used as input. Also optional if
398+
longitude, latitude, and crs are given. If otherwise omitted, calculation will be
399+
carried out on a Cartesian, rather than geospatial, grid. Keyword-only argument.
400+
meridional_scale : `pint.Quantity`, optional
401+
Meridional scale of map projection at data coordinate. Optional if `xarray.DataArray`
402+
with latitude/longitude coordinates and MetPy CRS used as input. Also optional if
403+
longitude, latitude, and crs are given. If otherwise omitted, calculation will be
404+
carried out on a Cartesian, rather than geospatial, grid. Keyword-only argument.
405+
406+
See Also
407+
--------
408+
gradient
409+
410+
"""
411+
(dudx, dudy), (dvdx, dvdy) = vector_derivative(
412+
u, v, dx=dx, dy=dy, x_dim=x_dim, y_dim=y_dim, parallel_scale=parallel_scale,
413+
meridional_scale=meridional_scale)
414+
return dudx * dvdy - dudy * dvdx
415+
416+
359417
@exporter.export
360418
@parse_grid_arguments
361419
@preprocess_and_wrap(wrap_like='scalar',
@@ -374,8 +432,7 @@ def advection(
374432
y_dim=-2,
375433
vertical_dim=-3,
376434
parallel_scale=None,
377-
meridional_scale=None
378-
):
435+
meridional_scale=None):
379436
r"""Calculate the advection of a scalar field by 1D, 2D, or 3D winds.
380437
381438
If ``scalar`` is a `xarray.DataArray`, only ``u``, ``v``, and/or ``w`` are required

0 commit comments

Comments
 (0)