Skip to content

Commit 6750533

Browse files
committed
add sh94 and md96 stretching and computation of gdep and e3
1 parent bb206e2 commit 6750533

1 file changed

Lines changed: 148 additions & 9 deletions

File tree

pydomcfg/domzgr/sco.py

Lines changed: 148 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Class to generate NEMO v4.0 s-coordinates
55
"""
66

7-
from typing import Optional
7+
from typing import Optional, Tuple
88

99
import numpy as np
1010
import xarray as xr
@@ -43,7 +43,6 @@ class Sco(Zgr):
4343
*) Madec, Delecluse, Crepon & Lott, JPO 26(8):1393-1408, 1996.
4444
"""
4545

46-
# --------------------------------------------------------------------------
4746
def __call__(
4847
self,
4948
min_dep: float,
@@ -138,17 +137,16 @@ def __call__(
138137
self._sigmas = self._compute_sigma(self._z)
139138

140139
# compute z3 depths of zco vertical levels
141-
# dsz = self._sco_z3(ds_env)
140+
z3t, z3w = self._sco_z3
142141

143142
# compute e3 scale factors
144-
# dse = self._compute_e3(dsz) if self._ln_e3_dep else self._analyt_e3(dsz)
143+
e3t, e3w = self._compute_e3(z3t, z3w)
145144

146145
# addind this only to not make darglint complying
147-
ds = self._bathy.copy()
148-
ds["hbatt"] = self._envlp
149-
return ds
146+
# ds = self._bathy.copy()
147+
# ds["hbatt"] = self._envlp
148+
return self._merge_z3_and_e3(z3t, z3w, e3t, e3w)
150149

151-
# --------------------------------------------------------------------------
152150
def _check_stretch_par(self, psurf, pbott, alpha, efold, pbot2):
153151
"""
154152
Check consistency of stretching parameters
@@ -174,7 +172,6 @@ def _check_stretch_par(self, psurf, pbott, alpha, efold, pbot2):
174172
sf12 stretching."
175173
)
176174

177-
# --------------------------------------------------------------------------
178175
def _compute_env(self, depth: DataArray) -> DataArray:
179176
"""
180177
Compute the envelope bathymetry surface by applying the
@@ -215,3 +212,145 @@ def _compute_env(self, depth: DataArray) -> DataArray:
215212
zenv = zenv.where(zenv > self._min_dep, self._min_dep)
216213

217214
return zenv
215+
216+
@property
217+
def _sco_z3(self) -> Tuple[DataArray, ...]:
218+
"""Compute and return z3{t,w} for s-coordinates grids"""
219+
220+
grids = ("T", "W")
221+
sigmas = self._sigmas
222+
scosrf = self._envlp * 0.0 # unperturbed free-surface
223+
224+
both_z3 = []
225+
for grid, sigma in zip(grids, sigmas):
226+
227+
if self._stretch:
228+
# Stretched sco grid
229+
su = -sigma
230+
ss = self._stretch_sco(-sigma)
231+
a1 = scosrf
232+
a2 = 0.0
233+
a3 = self._envlp
234+
if self._stretch != "sf12":
235+
a2 += self._hc
236+
a3 -= self._hc
237+
else:
238+
# Uniform sco grid
239+
su = -sigma
240+
ss = DataArray((0.0))
241+
a1 = a3 = scosrf
242+
a2 = self._envlp
243+
244+
z3 = self._compute_z3(su, ss, a1, a2, a3)
245+
246+
both_z3 += [z3]
247+
248+
return tuple(both_z3)
249+
250+
def _stretch_sco(self, sigma: DataArray) -> DataArray:
251+
"""
252+
Wrapping method for calling generalised analytical
253+
stretching function for terrain-following s-coordinates.
254+
255+
Parameters
256+
----------
257+
sigma: DataArray
258+
Uniform non-dimensional sigma-coordinate:
259+
MUST BE positive, i.e. 0 <= sigma <= 1
260+
261+
Returns
262+
-------
263+
DataArray
264+
Stretched coordinate
265+
"""
266+
if self._stretch == "sh94":
267+
ss = self._sh94(sigma)
268+
elif self._stretch == "md96":
269+
ss = self._md96(sigma)
270+
# elif self._stretch == "sf12":
271+
# ss = self._sf12(sigma)
272+
273+
return ss
274+
275+
def _sh94(self, sigma: DataArray) -> DataArray:
276+
"""
277+
Song and Haidvogel 1994 analytical stretching
278+
function for terrain-following s-coordinates.
279+
280+
Reference:
281+
Song & Haidvogel, J. Comp. Phy., 115, 228-244, 1994.
282+
283+
Parameters
284+
----------
285+
sigma: DataArray
286+
Uniform non-dimensional sigma-coordinate:
287+
MUST BE positive, i.e. 0 <= sigma <= 1
288+
289+
Returns
290+
-------
291+
DataArray
292+
Stretched coordinate
293+
"""
294+
ca = self._psurf
295+
cb = self._pbott
296+
297+
if ca == 0.0:
298+
ss = sigma
299+
else:
300+
ss = (1.0 - cb) * np.sinh(ca * sigma) / np.sinh(ca) + cb * (
301+
(np.tanh(ca * (sigma + 0.0)) - np.tanh(0.0 * ca))
302+
/ (2.0 * np.tanh(0.0 * ca))
303+
)
304+
305+
return ss
306+
307+
def _md96(self, sigma: DataArray) -> DataArray:
308+
"""
309+
Madec et al. 1996 analytical stretching
310+
function for terrain-following s-coordinates.
311+
312+
Reference:
313+
pag 65 of NEMO Manual
314+
Madec, Lott, Delecluse and Crepon, 1996. JPO, 26, 1393-1408
315+
316+
Parameters
317+
----------
318+
sigma: DataArray
319+
Uniform non-dimensional sigma-coordinate:
320+
MUST BE positive, i.e. 0 <= sigma <= 1
321+
322+
Returns
323+
-------
324+
DataArray
325+
Stretched coordinate
326+
"""
327+
ca = self._psurf
328+
cb = self._pbott
329+
330+
ss = (
331+
(np.tanh(ca * (sigma + cb)) - np.tanh(cb * ca))
332+
* (np.cosh(ca) + np.cosh(ca * (2.0e0 * cb - 1.0e0)))
333+
/ (2.0 * np.sinh(ca))
334+
)
335+
336+
return ss
337+
338+
# def _sf12(self, sigma: DataArray) -> DataArray:
339+
# """
340+
# Siddorn and Furner 2012 analytical stretching
341+
# function for terrain-following s-coordinates.
342+
#
343+
# Reference:
344+
# Siddorn & Furner, Oce. Mod. 66:1-13, 2013.
345+
346+
# Parameters
347+
# ----------
348+
# sigma: DataArray
349+
# Uniform non-dimensional sigma-coordinate:
350+
# MUST BE positive, i.e. 0 <= sigma <= 1
351+
#
352+
# Returns
353+
# -------
354+
# DataArray
355+
# Stretched coordinate
356+
# """

0 commit comments

Comments
 (0)