Coverage for tests/test_param_spectra.py: 100%
50 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-09-11 16:30 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-09-11 16:30 +0200
1from hypothesis import given, strategies as st
2import numpy as np
3import pytest
4import scipy.integrate as integrate
6import swiift.api.spectra as spectra
7from swiift.lib.constants import PI_2
8from tests.physical_strategies import PHYSICAL_STRATEGIES
10_freqencies = (
11 np.array([1, 2]),
12 np.array([0.5, 1.2]),
13 np.linspace(0.3, 0.7, 10),
14 0.3,
15)
17generic_spectra = (
18 spectra.PiersonMoskowitz.from_peak_frequency(0.2, 9.8),
19 spectra.Bretschneider.from_peak_frequency_swh(0.18, 2.1),
20 spectra.JONSWAP.from_parameters(0.21, 3.3, 9.8),
21)
24@pytest.mark.parametrize("frequencies", _freqencies)
25@pytest.mark.parametrize("spectrum", generic_spectra)
26def test_angular_density(frequencies, spectrum: spectra._ParametrisedSpectrum):
27 density_from_frequency = spectrum.density(frequencies) 1d
28 angular_frequencies = PI_2 * frequencies 1d
29 density_from_ang_frequency = spectrum._density_ang(angular_frequencies) 1d
31 # The density should be equal up to the scaling factor 2pi.
32 assert np.allclose(density_from_frequency, density_from_ang_frequency * PI_2) 1d
34 # Integrating the densities wrt their arguments
35 # should yield identical results.
36 if len(np.atleast_1d(frequencies)) > 1: 1d
37 assert np.isclose( 1d
38 spectrum.discrete_energy(frequencies),
39 np.trapezoid(density_from_ang_frequency, angular_frequencies),
40 )
43@pytest.mark.parametrize("spectrum", generic_spectra)
44def test_total_energy(spectrum):
45 res, _ = integrate.quad(spectrum.density, 0, np.inf) 1c
46 swh_num = 4 * np.sqrt(res) 1c
47 target = spectrum.swh 1c
49 if isinstance(spectrum, spectra.JONSWAP): 1c
50 # Twice the greatest absolute error from the ITTC polynomial
51 # approximation, with respect to the density numerically
52 # integrated "in-house".
53 jonswap_atol = 9e-3 1c
54 assert np.isclose(swh_num, target, atol=jonswap_atol) 1c
55 else:
56 assert np.isclose(swh_num, target) 1c
59@pytest.mark.parametrize("spectrum", generic_spectra)
60def test_properties(spectrum):
61 fp = spectrum.peak_frequency 1e
63 assert np.isclose(spectrum.peak_period, 1 / fp) 1e
64 assert np.isclose(spectrum.peak_ang_frequency, PI_2 * fp) 1e
67class TestPiersonMoskowitz:
68 @staticmethod
69 @given( 1ab
70 swh=PHYSICAL_STRATEGIES[("wave", "amplitude")],
71 gravity=PHYSICAL_STRATEGIES[("gravity",)],
72 )
73 def test_recover_swh(swh: float, gravity: float):
74 spectrum = spectra.PiersonMoskowitz.from_swh(swh, gravity) 1b
75 assert np.isclose(spectrum.swh, swh) 1b
77 @staticmethod
78 @given( 1ab
79 peak_frequency=PHYSICAL_STRATEGIES[("wave", "frequency")],
80 gravity=PHYSICAL_STRATEGIES[("gravity",)],
81 )
82 def test_recover_peak_frequency(peak_frequency: float, gravity: float):
83 spectrum = spectra.PiersonMoskowitz.from_peak_frequency(peak_frequency, gravity) 1b
84 assert np.isclose(spectrum.peak_frequency, peak_frequency) 1b
87class TestBretschneider:
88 @staticmethod
89 @given( 1ab
90 peak_frequency=PHYSICAL_STRATEGIES[("wave", "frequency")],
91 swh=PHYSICAL_STRATEGIES[("wave", "amplitude")],
92 )
93 def test_recover_physicak_values(peak_frequency, swh):
94 spectrum = spectra.Bretschneider.from_peak_frequency_swh(peak_frequency, swh) 1b
95 assert np.isclose(spectrum.peak_frequency, peak_frequency) 1b
96 assert np.isclose(spectrum.swh, swh) 1b