Skip to content

Commit 9002bb0

Browse files
Do not drop indexes when computing rmax (#40)
* Do not drop indexes when computing rmax * implement #39 * replace land with 0s * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * handle land properly * use max rather than mean and use xarray max instead of np maximum * same as pyroms Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent f68612d commit 9002bb0

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

pydomcfg/domzgr/zgr.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ def __init__(self, ds_bathy: Dataset, jpk: int):
2020
Parameters
2121
----------
2222
ds_bathy: Dataset
23-
xarray dataset including grid coordinates and bathymetry
23+
xarray dataset including grid coordinates and bathymetry.
24+
All bathymetry values MUST be >= 0, where 0 is land.
2425
jpk: int
2526
number of computational levels
2627
"""

pydomcfg/tests/bathymetry.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -142,34 +142,49 @@ def _calc_rmax(depth):
142142
Calculate rmax: measure of steepness
143143
144144
This function returns the slope steepness criteria rmax, which is simply
145-
(H[0] - H[1]) / (H[0] + H[1])
145+
|H[0] - H[1]| / (H[0] + H[1])
146146
147147
Parameters
148148
----------
149149
depth: float
150-
Bottom depth (units: m).
150+
Bottom depth (units: m).
151151
152152
Returns
153153
-------
154154
rmax: float
155-
Slope steepness value (units: None)
155+
Slope steepness value (units: None)
156+
157+
Notes
158+
-----
159+
This function uses a "conservative approach" and rmax is overestimated.
160+
rmax at T points is the maximum rmax estimated at any adjacent U/V point.
156161
"""
157-
depth = depth.reset_index(list(depth.dims))
158162

163+
# Mask land
164+
depth = depth.where(depth > 0)
165+
166+
# Loop over x and y
159167
both_rmax = []
160168
for dim in depth.dims:
161169

162-
# (H[0] - H[1]) / (H[0] + H[1])
163-
depth_diff = depth.diff(dim)
164-
depth_rolling_sum = depth.rolling({dim: 2}).sum().dropna(dim)
165-
rmax = depth_diff / depth_rolling_sum
170+
# Compute rmax
171+
rolled = depth.rolling({dim: 2}).construct("window_dim")
172+
diff = rolled.diff("window_dim").squeeze("window_dim")
173+
rmax = np.abs(diff) / rolled.sum("window_dim")
174+
175+
# Construct dimension with velocity points adjacent to any T point
176+
# We need to shift as we rolled twice
177+
rmax = rmax.rolling({dim: 2}).construct("vel_points")
178+
rmax = rmax.shift({dim: -1})
166179

167-
# (R[0] + R[1]) / 2
168-
rmax = rmax.rolling({dim: 2}).mean().dropna(dim)
180+
both_rmax.append(rmax)
169181

170-
# Fill first row and column
171-
rmax = rmax.pad({dim: (1, 1)}, constant_values=0)
182+
# Find maximum rmax at adjacent U/V points
183+
rmax = xr.concat(both_rmax, "vel_points")
184+
rmax = rmax.max("vel_points", skipna=True)
172185

173-
both_rmax.append(np.abs(rmax))
186+
# Mask halo points
187+
for dim in rmax.dims:
188+
rmax[{dim: [0, -1]}] = 0
174189

175-
return np.maximum(*both_rmax)
190+
return rmax.fillna(0)

0 commit comments

Comments
 (0)