Source code for sgs_tools.geometry.vector_calculus

import numpy as np
import xarray as xr

# Vector calculus


[docs] def grad_scalar( sca: xr.DataArray, space_dims: list[str], new_dim_name: str = "c1", name=None ) -> xr.DataArray: """gradient vector of a scalar using centred 2nd order difference, reduced to 1st order at boundaries :param sca: input scalar, with spatial coordinates `space_dims` :param space_dims: labels for the spatial dimensions (to be differentiated against) :param new_dim_name: the name of the new dimension (of the differential direction) :param name: name for output dataarray. If None, the name of the input scalar is used. :return: gradient (assuming cartesian geometry) """ grad = [] for dim in space_dims: grad.append(sca.differentiate(dim, edge_order=1)) grad_xarr = xr.concat( grad, dim=xr.DataArray(range(1, len(space_dims) + 1), dims=[new_dim_name]) ) if name is not None: grad_xarr.name = name return grad_xarr
[docs] def grad_vector( vec: xr.DataArray, space_dims: list[str], new_dim_name: str = "c2", name=None ) -> xr.DataArray: """gradient tensor of a vector using centred 2nd order difference, reduced to 1st order at boundaries :param vec: input vector, with spatial coordinates `space_dims` :param space_dims: labels for the spatial dimensions (to be differentiated against) :param new_dim_name: the name of the new dimension (of the differential direction) :param name: name for output dataarray. If None, the name of the input vector is used. :return: gradient (assuming cartesian geometry) """ gradvec = [] for dim in space_dims: gradvec.append(vec.differentiate(dim, edge_order=1)) gradvec_xarr = xr.concat( gradvec, dim=xr.DataArray(range(1, len(space_dims) + 1), dims=[new_dim_name]) ) if name is not None: gradvec_xarr.name = name return gradvec_xarr
[docs] def grad_vector_lin( vec: xr.DataArray, space_dims: list[str], new_dim_name: str = "c2", name=None ) -> xr.DataArray: """gradient tensor of a vector -- 1st order backward finite-difference :param vec: input vector, with spatial coordinates `space_dims` :param space_dims: labels for the spatial dimensions (to be differentiated against) :param new_dim_name: the name of the new dimension (of the differential direction) :param name: name for output dataarray. If None, the name of the input vector is used. :return: gradient (assuming cartesian geometry) """ gradvec = [] for dim in space_dims: coord = vec[dim].astype(float) # just in case val = vec.astype(float) gradvec.append( (val - val.shift({dim: -1}, fill_value=np.nan)) / (coord - coord.shift({dim: -1}, fill_value=np.nan)) ) gradvec_xarr = xr.concat( gradvec, dim=xr.DataArray(range(1, len(space_dims) + 1), dims=[new_dim_name]) ) if name is not None: gradvec_xarr.name = name return gradvec_xarr