Skip to content

Commit

Permalink
Fixed uv_geostrophic
Browse files Browse the repository at this point in the history
* algorithm was incorrect, now fixed
* updated docs to mostly run (fixed xesmf issue in docs conf.py, conda-forge/esmf-feedstock#91 (comment))
* updated formatting in docs
  • Loading branch information
kthyng committed Feb 9, 2024
1 parent d4611a4 commit 0a461c2
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 31 deletions.
2 changes: 1 addition & 1 deletion docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ API
:toctree: generated/
:recursive:

xroms.roms_dataset
xroms
derived
interp
roms_seawater
Expand Down
18 changes: 9 additions & 9 deletions docs/calc.md
Original file line number Diff line number Diff line change
Expand Up @@ -394,26 +394,26 @@ ds.xroms.vertical_shear
ds.xroms.vort
```

### Horizontal divergence
### Horizontal convergence

Horizontal component of the currents divergence.
Horizontal component of the currents convergence.

ds.xroms.div
ds.xroms.convergence

xroms.divergence(ds.u, ds.v, xgrid)
xroms.convergence(ds.u, ds.v, xgrid)

```{code-cell} ipython3
ds.xroms.div
ds.xroms.convergence
```

### Normalized surface divergence
### Normalized surface convergence

Horizontal component of the currents divergence at the surface, normalized by $f$. This is only available through the accessor.
Horizontal component of the currents convergence at the surface, normalized by $f$. This is only available through the accessor.

ds.xroms.div_norm
ds.xroms.convergence_norm

```{code-cell} ipython3
ds.xroms.div_norm
ds.xroms.convergence_norm
```

### Ertel potential vorticity
Expand Down
11 changes: 10 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
from importlib.metadata import version as imversion


# to fix issue with xESMF
# https://github.com/conda-forge/esmf-feedstock/issues/91#issuecomment-1387279692
if "ESMFMKFILE" not in os.environ:
# RTD doesn't activate the env, and esmpy depends on a env var set there
# We assume the `os` package is in {ENV}/lib/pythonX.X/os.py
# See conda-forge/esmf-feedstock#91 and readthedocs/readthedocs.org#4067
os.environ["ESMFMKFILE"] = str(pathlib.Path(os.__file__).parent.parent / "esmf.mk")


print("python exec:", sys.executable)
print("sys.path:", sys.path)
root = pathlib.Path(__file__).parent.parent.absolute()
Expand All @@ -32,7 +41,7 @@
# -- Project information -----------------------------------------------------

project = "xroms"
copyright = "2020-2023"
copyright = "2020-2024"
author = "Rob Hetland, Kristen Thyng, Veronica Ruiz Xomchuk"

release = imversion("xroms")
Expand Down
4 changes: 4 additions & 0 deletions docs/whats_new.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# What's New

## v0.6.0 (February 9, 2023)
* fixed error in `derived.py`'s `uv_geostrophic` function after being pointed out by @ak11283
* updated docs so mostly well-formatted and working

## v0.5.3 (October 11, 2023)
* change to `roms_dataset()` so that input flag `include_3D_metrics` also controls if `ds["3d"] = True`.

Expand Down
4 changes: 4 additions & 0 deletions xroms/accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def set_grid(self, xgrid):
Examples
--------
>>> ds.xroms.set_grid(xgrid)
"""
self._xgrid = xgrid
Expand All @@ -100,6 +101,7 @@ def speed(self):
Examples
--------
>>> ds.xroms.speed
"""

Expand All @@ -120,6 +122,7 @@ def KE(self):
Examples
--------
>>> ds.xroms.KE
"""

Expand All @@ -140,6 +143,7 @@ def ug(self):
Examples
--------
>>> ds.xroms.ug
"""

Expand Down
48 changes: 40 additions & 8 deletions xroms/derived.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ def speed(u, v, xgrid, hboundary="extend", hfill_value=None):
for moving to rho grid.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
hfill_value: float, optional
Passed to `grid` method calls; horizontal boundary fill value
selection for moving to rho grid.
Expand Down Expand Up @@ -122,19 +124,22 @@ def uv_geostrophic(zeta, f, xgrid, hboundary="extend", hfill_value=None, which="
for moving f to rho grid.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
hfill_value: float, optional
Passed to `grid` method calls; horizontal boundary selection
for moving f to rho grid.
From xgcm documentation:
The value to use in the boundary condition with `boundary='fill'`.
which: string, optional
Which components of geostrophic velocity to return.
* 'both': return both components of hgrad
* 'xi': return only xi-direction.
* 'eta': return only eta-direction.
Expand All @@ -147,10 +152,16 @@ def uv_geostrophic(zeta, f, xgrid, hboundary="extend", hfill_value=None, which="
Notes
-----
vg = g * zeta_eta / (d eta * f) # on v grid
ug = -g * zeta_xi / (d xi * f) # on u grid
ug = -g * zeta_eta / (d eta * f) # on u grid
vg = g * zeta_xi / (d xi * f) # on v grid
Translation to Python of Matlab copy of surf_geostr_vel of IRD Roms_Tools.
Good resourcefor more information:
https://uw.pressbooks.pub/ocean285/chapter/geostrophic-balance/
Examples
--------
>>> xroms.uv_geostrophic(ds.zeta, ds.f, xgrid)
Expand All @@ -162,11 +173,13 @@ def uv_geostrophic(zeta, f, xgrid, hboundary="extend", hfill_value=None, which="
if which in ["both", "xi"]:

# calculate derivatives of zeta
dzetadxi = hgrad(zeta, xgrid, which="xi")
dzetadeta = hgrad(zeta, xgrid, which="eta", hcoord="u")

# calculate geostrophic velocities
ug = (
-g * dzetadxi / to_u(f, xgrid, hboundary=hboundary, hfill_value=hfill_value)
-g
* dzetadeta
/ to_u(f, xgrid, hboundary=hboundary, hfill_value=hfill_value)
)

ug.attrs["name"] = "ug"
Expand All @@ -175,13 +188,12 @@ def uv_geostrophic(zeta, f, xgrid, hboundary="extend", hfill_value=None, which="
ug.name = ug.attrs["name"]

if which in ["both", "eta"]:

# calculate derivatives of zeta
dzetadeta = hgrad(zeta, xgrid, which="eta")
dzetadxi = hgrad(zeta, xgrid, which="xi", hcoord="v")

# calculate geostrophic velocities
vg = (
g * dzetadeta / to_v(f, xgrid, hboundary=hboundary, hfill_value=hfill_value)
)
vg = g * dzetadxi / to_v(f, xgrid, hboundary=hboundary, hfill_value=hfill_value)

vg.attrs["name"] = "vg"
vg.attrs["long_name"] = "geostrophic v velocity"
Expand Down Expand Up @@ -214,12 +226,14 @@ def EKE(ug, vg, xgrid, hboundary="extend", hfill_value=None):
for moving to rho grid.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
hfill_value: float, optional
Passed to `grid` method calls; horizontal boundary selection
for moving to rho grid.
Expand Down Expand Up @@ -272,12 +286,14 @@ def dudz(u, xgrid, sboundary="extend", sfill_value=None):
calculating z derivative.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
sfill_value: float, optional
Passed to `grid` method calls; vertical boundary fill value
associated with sboundary input.
Expand Down Expand Up @@ -321,12 +337,14 @@ def dvdz(v, xgrid, sboundary="extend", sfill_value=None):
calculating z derivative.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
sfill_value: float, optional
Passed to `grid` method calls; vertical boundary fill value
associated with sboundary input.
Expand Down Expand Up @@ -372,12 +390,14 @@ def vertical_shear(dudz, dvdz, xgrid, hboundary="extend", hfill_value=None):
for moving dudz and dvdz to rho grid.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
hfill_value: float, optional
Passed to `grid` method calls; horizontal boundary selection
for moving to rho grid.
Expand Down Expand Up @@ -439,12 +459,14 @@ def relative_vorticity(
for calculating horizontal derivatives of u and v.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
hfill_value: float, optional
Passed to `grid` method calls; horizontal boundary selection
fill value.
Expand All @@ -455,12 +477,14 @@ def relative_vorticity(
for calculating horizontal derivatives of u and v.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
sfill_value: float, optional
Passed to `grid` method calls; vertical boundary selection
fill value.
Expand Down Expand Up @@ -537,12 +561,14 @@ def convergence(
for calculating horizontal derivatives of u and v.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
hfill_value: float, optional
Passed to `grid` method calls; horizontal boundary selection
fill value.
Expand All @@ -553,12 +579,14 @@ def convergence(
for calculating horizontal derivatives of u and v.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
sfill_value: float, optional
Passed to `grid` method calls; vertical boundary selection
fill value.
Expand Down Expand Up @@ -660,12 +688,14 @@ def ertel(
horizontal grid changes too.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
hfill_value: float, optional
Passed to `grid` method calls; horizontal boundary selection
fill value.
Expand All @@ -678,12 +708,14 @@ def ertel(
all vertical grid changes too.
From xgcm documentation:
A flag indicating how to handle boundaries:
* None: Do not apply any boundary conditions. Raise an error if
boundary conditions are required for the operation.
* 'fill': Set values outside the array boundary to fill_value
(i.e. a Neumann boundary condition.)
* 'extend': Set values outside the array to the nearest array
value. (i.e. a limited form of Dirichlet boundary condition.
sfill_value: float, optional
Passed to `grid` method calls; vertical boundary selection
fill value.
Expand Down
Loading

0 comments on commit 0a461c2

Please sign in to comment.