Skip to content

Season Annual Harmonic

get_phase_amp(coef_sw_amp, omega, heat_cap_eff=None, lambda_eff=None, coef_phase=None, coef_amp=None)

Convert between harmonic temperature response and energy-budget parameters.

Uses the linear surface energy budget

\[ C_{\mathrm{eff}}\,\frac{dT'}{dt} = Q'_{\mathrm{SW}} - \lambda_{\mathrm{eff}} T'. \]

The forcing and steady periodic temperature response are defined as

\[ Q'_{\mathrm{SW}}(t) = A_{\mathrm{SW}}\cos(\omega t), \qquad T'(t) = A_T\cos(\omega t - \phi). \]

Here, positive \(\phi\) denotes a temperature lag relative to the forcing, and positive \(\lambda_{\mathrm{eff}}\) denotes damping.

Parameters:

Name Type Description Default
coef_sw_amp DataArray

First-harmonic amplitude of absorbed surface shortwave forcing [W m^-2].

required
omega float

Angular frequency [rad s^-1], equal to 2*pi / period.

required
heat_cap_eff Optional[DataArray]

Effective heat capacity per unit area [J m^-2 K^-1]. Supply with lambda_eff to calculate temperature phase and amplitude.

None
lambda_eff Optional[DataArray]

Effective linear damping coefficient [W m^-2 K^-1]. Supply with heat_cap_eff.

None
coef_phase Optional[DataArray]

First-harmonic temperature phase lag relative to the shortwave forcing [rad]. Supply with coef_amp to infer effective heat capacity and damping.

None
coef_amp Optional[DataArray]

First-harmonic temperature amplitude [K]. Supply with coef_phase.

None

Returns:

Type Description
Tuple[DataArray, DataArray]

A tuple of DataArrays containing either: (coef_phase, coef_amp), when heat_cap_eff and lambda_eff are supplied. (heat_cap_eff, lambda_eff), when coef_phase and coef_amp are supplied.

Raises:

Type Description
ValueError

If neither complete input pair is supplied, or if inputs from both pairs are supplied.

Notes

Assumes time-independent coefficients and a steady periodic response. Phase is relative to the forcing, not an absolute calendar phase. The corresponding time lag is coef_phase / omega. Inversion requires nonzero omega and coef_amp.

Source code in isca_tools/thesis/season_annual_harmonic.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
def get_phase_amp(coef_sw_amp: xr.DataArray, omega: float, heat_cap_eff: Optional[xr.DataArray]=None,
                  lambda_eff: Optional[xr.DataArray]=None, coef_phase: Optional[xr.DataArray]=None,
                  coef_amp: Optional[xr.DataArray]=None) -> Tuple[xr.DataArray, xr.DataArray]:
    r"""Convert between harmonic temperature response and energy-budget parameters.

    Uses the linear surface energy budget

    $$
    C_{\mathrm{eff}}\,\frac{dT'}{dt} = Q'_{\mathrm{SW}} - \lambda_{\mathrm{eff}} T'.
    $$

    The forcing and steady periodic temperature response are defined as

    $$
    Q'_{\mathrm{SW}}(t) = A_{\mathrm{SW}}\cos(\omega t),
    \qquad
    T'(t) = A_T\cos(\omega t - \phi).
    $$

    Here, positive $\phi$ denotes a temperature lag relative to the forcing,
    and positive $\lambda_{\mathrm{eff}}$ denotes damping.

    Args:
        coef_sw_amp: First-harmonic amplitude of absorbed surface shortwave forcing
            [W m^-2].
        omega: Angular frequency [rad s^-1], equal to 2*pi / period.
        heat_cap_eff: Effective heat capacity per unit area [J m^-2 K^-1].
            Supply with lambda_eff to calculate temperature phase and amplitude.
        lambda_eff: Effective linear damping coefficient [W m^-2 K^-1].
            Supply with heat_cap_eff.
        coef_phase: First-harmonic temperature phase lag relative to the
            shortwave forcing [rad]. Supply with coef_amp to infer effective
            heat capacity and damping.
        coef_amp: First-harmonic temperature amplitude [K]. Supply with
            coef_phase.

    Returns:
        A tuple of DataArrays containing either:
            (coef_phase, coef_amp), when heat_cap_eff and lambda_eff are supplied.
            (heat_cap_eff, lambda_eff), when coef_phase and coef_amp are supplied.

    Raises:
        ValueError: If neither complete input pair is supplied, or if inputs
            from both pairs are supplied.

    Notes:
        Assumes time-independent coefficients and a steady periodic response.
        Phase is relative to the forcing, not an absolute calendar phase.
        The corresponding time lag is coef_phase / omega.
        Inversion requires nonzero omega and coef_amp.
    """
    if (coef_phase is None) and (coef_amp is None):
        coef_phase = np.arctan2(omega * heat_cap_eff, lambda_eff)
        coef_amp = coef_sw_amp / np.sqrt(omega ** 2 * heat_cap_eff ** 2 + lambda_eff ** 2)
        return coef_phase, coef_amp
    elif (lambda_eff is None) and (heat_cap_eff is None):
        heat_cap_eff = np.sin(coef_phase) / omega / (coef_amp/coef_sw_amp)
        lambda_eff = coef_sw_amp * np.cos(coef_phase) / coef_amp
        return heat_cap_eff, lambda_eff
    else:
        raise ValueError('Incorrect arguments for get_phase_amp')