Source code for pyTMD.ellipse

#!/usr/bin/env python
u"""
ellipse.py
Written by Tyler Sutterley (01/2024)
Expresses the amplitudes and phases for the u and v components in terms of
    four ellipse parameters using Foreman's formula

CALLING SEQUENCE:
    umajor,uminor,uincl,uphase = pyTMD.ellipse.ellipse(u,v)

INPUTS:
    u: zonal current (EW)
    v: meridional current (NS)

OUTPUTS:
    umajor: amplitude of the semimajor semi-axis
    uminor: amplitude of the semiminor semi-axis
    uincl: angle of inclination of the northern semimajor semi-axis
    uphase: phase lag of the maximum current behind the maximum tidal potential
        of the individual constituent

REFERENCE:
    M. G. G. Foreman and R. F. Henry, "The harmonic analysis of tidal model time
        series", Advances in Water Resources, 12(3), 109-120, (1989).
        https://doi.org/10.1016/0309-1708(89)90017-1

UPDATE HISTORY:
    Updated 01/2024: added inverse function to get currents from parameters
        use complex algebra to calculate tidal ellipse parameters
    Updated 09/2023: renamed to ellipse.py (from tidal_ellipse.py)
    Updated 03/2023: add basic variable typing to function inputs
    Updated 04/2022: updated docstrings to numpy documentation format
    Written 07/2020
"""
from __future__ import annotations

import numpy as np

[docs]def ellipse(u: np.ndarray, v: np.ndarray): """ Expresses the amplitudes and phases for the u and v components in terms of four ellipse parameters using Foreman's formula [1]_ Parameters ---------- u: np.ndarray zonal current (EW) v: np.ndarray meridional current (NS) Returns ------- umajor: np.ndarray amplitude of the semimajor semi-axis uminor: np.ndarray amplitude of the semiminor semi-axis uincl: np.ndarray angle of inclination of the northern semimajor semi-axis uphase: np.ndarray phase lag of the maximum current behind the maximum tidal potential of the individual constituent References ---------- .. [1] M. G. G. Foreman and R. F. Henry, "The harmonic analysis of tidal model time series," *Advances in Water Resources*, 12(3), 109--120, (1989). `doi: 10.1016/0309-1708(89)90017-1 <https://doi.org/10.1016/0309-1708(89)90017-1>`_ """ # validate inputs u = np.atleast_1d(u) v = np.atleast_1d(v) # wp, wm: complex radius of positively and negatively rotating vectors wp = (u + 1j*v)/2.0 wm = np.conj(u - 1j*v)/2.0 # ap, am: amplitudes of positively and negatively rotating vectors ap = np.abs(wp) am = np.abs(wm) # ep, em: phases of positively and negatively rotating vectors ep = np.angle(wp, deg=True) em = np.angle(wm, deg=True) # determine the amplitudes of the semimajor and semiminor axes # using Foreman's formula umajor = (ap + am) uminor = (ap - am) # determine the inclination and phase using Foreman's formula uincl = (em + ep)/2.0 uphase = (em - ep)/2.0 # adjust orientation of ellipse k = (uincl//180.0) uincl -= 180.0*k uphase += 180.0*k uphase = np.mod(uphase, 360.0) # return values return (umajor, uminor, uincl, uphase)
[docs]def inverse( umajor: np.ndarray, uminor: np.ndarray, uincl: np.ndarray, uphase: np.ndarray ): """ Calculates currents u, v using the four tidal ellipse parameters from Foreman's formula [1]_ Parameters ---------- umajor: np.ndarray amplitude of the semimajor semi-axis uminor: np.ndarray amplitude of the semiminor semi-axis uincl: np.ndarray angle of inclination of the northern semimajor semi-axis uphase: np.ndarray phase lag of the maximum current behind the maximum tidal potential of the individual constituent Returns ------- u: np.ndarray zonal current (EW) v: np.ndarray meridional current (NS) References ---------- .. [1] M. G. G. Foreman and R. F. Henry, "The harmonic analysis of tidal model time series," *Advances in Water Resources*, 12(3), 109--120, (1989). `doi: 10.1016/0309-1708(89)90017-1 <https://doi.org/10.1016/0309-1708(89)90017-1>`_ """ # validate inputs umajor = np.atleast_1d(umajor) uminor = np.atleast_1d(uminor) # convert inclination and phase to radians uincl = np.atleast_1d(uincl)*np.pi/180.0 uphase = np.atleast_1d(uphase)*np.pi/180.0 # ep, em: phases of positively and negatively rotating vectors ep = (uincl - uphase) em = (uincl + uphase) # ap, am: amplitudes of positively and negatively rotating vectors ap = (umajor + uminor)/2.0 am = (umajor - uminor)/2.0 # wp, wm: complex radius of positively and negatively rotating vectors wp = ap * np.exp(1j*ep) wm = am * np.exp(1j*em) # calculate complex currents u = wp + np.conj(wm) v = -1j*(wp - np.conj(wm)) # return values return (u, v)