Beispiel #1
0
def stability(temp, lev, zdim, punit=100.):
    """
    P level coordinates stability (Brunt-Vaisala).

    :param temp: array_like, temperature.
    :param lev: array_like, pressure level.
    :param zdim: vertical dimension axis.
    :param punit: pressure unit.
    :return: ndarray.
    """

    temp = np.asarray(temp)
    ndim = temp.ndim
    p = arr.expand(lev, ndim, axis=zdim) * punit
    theta = pottemp(temp, lev, zdim, punit=punit)
    alpha = Rd * temp / p
    N = -alpha * grid.dvardp(np.log(theta), lev, zdim, punit=punit)

    return N
Beispiel #2
0
def pottemp(temp, lev, zdim, punit=100., p0=100000.):
    """
    Calculate potential temperature.

    :param temp: array_like, temperature [K].
    :param lev: array_like, level [punit*Pa].
    :param zdim: vertical dimensions.
    :param punit: pressure level punit.
    :param p0: reference pressure.
    :return: ndarray.
    """

    temp = np.asarray(temp)
    ndim = temp.ndim
    p = arr.expand(lev, ndim, axis=zdim)

    out = temp * ((p0 / p / punit)**kappa)

    return out
def ertelpv(uwnd,
            vwnd,
            temp,
            lon,
            lat,
            lev,
            xdim,
            ydim,
            zdim,
            cyclic=True,
            punit=100.,
            sphere=True):
    """
    Calculate Ertel potential vorticity.
    Hoskins, B.J., M.E. McIntyre and A.E. Robertson, 1985:
      On the use and significance of isentropic potential
      vorticity maps, `QJRMS`, 111, 877-946,
    <http://onlinelibrary.wiley.com/doi/10.1002/qj.49711147002/abstract>

    :param uwnd: ndarray, u component wind [m/s].
    :param vwnd: ndarray, v component wind [m/s].
    :param temp: ndarray, temperature [K].
    :param lon: array_like, longitude [degrees].
    :param lat: array_like, latitude [degrees].
    :param lev: array_like, pressure level [punit*Pa].
    :param xdim: west-east axis
    :param ydim: south-north axis
    :param zdim: vertical axis
    :param cyclic: west-east cyclic boundary
    :param punit: pressure level unit
    :param sphere: sphere coordinates.
    :return:
    """

    u, v, t = np.ma.getdata(uwnd), np.ma.getdata(vwnd), np.ma.getdata(temp)
    mask = np.ma.getmask(uwnd) | np.ma.getmask(vwnd) | np.ma.getmask(temp)
    ndim = u.ndim

    # potential temperature
    theta = pottemp(t, lev, zdim, punit=punit)

    # partial derivation
    dthdp = dvardp(theta, lev, zdim, punit=punit)
    dudp = dvardp(u, lev, zdim, punit=punit)
    dvdp = dvardp(v, lev, zdim, punit=punit)

    dthdx = dvardx(theta, lon, lat, xdim, ydim, cyclic=cyclic, sphere=sphere)
    dthdy = dvardy(theta, lat, ydim, sphere=sphere)

    # absolute vorticity
    vor = rot(u, v, lon, lat, xdim, ydim, cyclic=cyclic, sphere=sphere)
    f = arr.expand(constants.earth_f(lat), ndim, axis=ydim)
    avor = f + vor

    out = -g * (avor * dthdp - (dthdx * dvdp - dthdy * dudp))

    out = np.ma.array(out, mask=mask)
    out = arr.mrollaxis(out, ydim, 0)
    out[0, ...] = np.ma.masked
    out[-1, ...] = np.ma.masked
    out = arr.mrollaxis(out, 0, ydim + 1)

    return out
def tnflux3d(U,
             V,
             T,
             strm,
             lon,
             lat,
             lev,
             xdim,
             ydim,
             zdim,
             cyclic=True,
             limit=100,
             punit=100.):
    """
    Takaya & Nakamura (2001) 计算等压面上的波活动度.
    Takaya, K and H. Nakamura, 2001: A formulation of a phase-independent
      wave-activity flux for stationary and migratory quasigeostrophic eddies
      on a zonally varying basic flow, `JAS`, 58, 608-627.
    http://journals.ametsoc.org/doi/abs/10.1175/1520-0469%282001%29058%3C0608%3AAFOAPI%3E2.0.CO%3B2

    :param U: u component wind [m/s].
    :param V: v component wind [m/s].
    :param T: climate temperature [K].
    :param strm: stream function bias [m^2/s]
    :param lon: longitude degree.
    :param lat: latitude degree.
    :param lev: level pressure.
    :param xdim: longitude dimension index.
    :param ydim: latitude dimension index.
    :param zdim: level dimension index.
    :param cyclic: east-west cyclic boundary.
    :param limit:
    :param punit: level pressure unit.
    :return: east-west, south-north, vertical component.
    """

    U, V, T = np.asarray(U), np.asarray(V), np.asarray(T)
    ndim = U.ndim
    S = stability(T, lev, zdim, punit=punit)
    f = arr.expand(constants.earth_f(lat), ndim, axis=ydim)

    dstrmdx = dvardx(strm, lon, lat, xdim, ydim, cyclic=cyclic)
    dstrmdy = dvardy(strm, lat, ydim)
    dstrmdp = dvardp(strm, lev, zdim, punit=punit)
    d2strmdx2 = d2vardx2(strm, lon, lat, xdim, ydim, cyclic=cyclic)
    d2strmdy2 = d2vardy2(strm, lat, ydim)
    d2strmdxdy = dvardy(dstrmdx, lat, ydim)
    d2strmdxdp = dvardx(dstrmdp, lon, lat, xdim, ydim, cyclic=True)
    d2strmdydp = dvardy(dstrmdp, lat, ydim)

    tnx = U * (dstrmdx ** 2 - strm * d2strmdx2) + \
        V * (dstrmdx * dstrmdy - strm * d2strmdxdy)
    tny = U * (dstrmdx * dstrmdy - strm * d2strmdxdy) + \
        V * (dstrmdy ** 2 - strm * d2strmdy2)
    tnz = f**2 / S**2 * (U * (dstrmdx * dstrmdp - strm * d2strmdxdp) - V *
                         (dstrmdy * dstrmdp - strm * d2strmdydp))

    tnx = 0.5 * tnx / np.abs(U + 1j * V)
    tny = 0.5 * tny / np.abs(U + 1j * V)

    tnxy = np.sqrt(tnx**2 + tny**2)
    tnx = np.ma.asarray(tnx)
    tny = np.ma.asarray(tny)
    tnz = np.ma.asarray(tnz)
    tnx[(U < 0) | (tnxy > limit)] = np.ma.masked
    tny[(U < 0) | (tnxy > limit)] = np.ma.masked
    tnz[(U < 0) | (tnxy > limit)] = np.ma.masked

    return tnx, tny, tnz