def test_ddeta(): testvars = ["salt", "u", "v", "z_w"] for testvar in testvars: acc = ds[testvar].xroms.ddeta() assert np.allclose(acc, xroms.ddeta(ds[testvar], grid)) acc.name == acc.attrs["name"] acc.attrs["grid"] == ds.xroms.grid items = [ "T", "X", "Y", "Z", "longitude", "latitude", "vertical", "time" ] assert set(items).issubset(acc.cf.get_valid_keys()) acc = ds.xroms.ddeta(testvar) assert np.allclose(acc, xroms.ddeta(ds[testvar], grid)) acc.name == acc.attrs["name"] acc.attrs["grid"] == ds.xroms.grid items = [ "T", "X", "Y", "Z", "longitude", "latitude", "vertical", "time" ] assert set(items).issubset(acc.cf.get_valid_keys())
def test_ddeta(): ddeta = (v[2] - v[0]) / (2 * dy) assert np.allclose(xroms.ddeta(ds.v, grid)[0, 1, 1, 0], ddeta)
def ddeta( self, varname, hcoord=None, scoord=None, hboundary="extend", hfill_value=None, sboundary="extend", sfill_value=None, attrs=None, ): """Calculate d/deta for a variable. Inputs ------ varname: str Name of variable in Dataset to operate on. hcoord: string, optional. Name of horizontal grid to interpolate output to. Options are 'rho', 'psi', 'u', 'v'. scoord: string, optional. Name of vertical grid to interpolate output to. Options are 's_rho', 's_w', 'rho', 'w'. hboundary: string, optional Passed to `grid` method calls; horizontal boundary selection for calculating horizontal derivative of var. This same value will be used for 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. From xgcm documentation: The value to use in the boundary condition with `boundary='fill'`. sboundary: string, optional Passed to `grid` method calls; vertical boundary selection for calculating horizontal derivative of var. This same value will be used for 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. From xgcm documentation: The value to use in the boundary condition with `boundary='fill'`. attrs: dict, optional Dictionary of attributes to add to resultant arrays. Requires that q is DataArray. For example: `attrs={'name': 'varname', 'long_name': 'longvarname', 'units': 'units'}` Returns ------- DataArray of dqdeta, the gradient of q in the eta-direction with attributes altered to reflect calculation. Notes ----- dqdeta = dqdy*dzdz - dqdz*dzdy Derivatives are taken in the ROMS curvilinear grid native eta-direction. These derivatives properly account for the fact that ROMS vertical coordinates are s coordinates and therefore can vary in time and space. This will alter the number of points in the eta and s dimensions. Example usage ------------- >>> ds.xroms.ddeta('salt') """ assert isinstance( varname, str ), "varname should be a string of the name of a variable stored in the Dataset" assert varname in self.ds, 'variable called "varname" must be in Dataset' return xroms.ddeta( self.ds[varname], self.grid, hcoord=hcoord, scoord=scoord, hboundary=hboundary, hfill_value=hfill_value, sboundary=sboundary, sfill_value=sfill_value, attrs=attrs, )