Coverage for tests/test_attenuation.py: 0%
83 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-09-11 16:23 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-09-11 16:23 +0200
1from hypothesis import given
2import hypothesis.extra.numpy as npst
3import numpy as np
5import swiift.lib.att as att
6from swiift.model.model import (
7 DiscreteSpectrum,
8 FloatingIce,
9 Ice,
10 Ocean,
11 WavesUnderElasticPlate,
12 WavesUnderIce,
13)
14from tests.model_strategies import coupled_ocean_ice, spec_mono, spec_poly
15from tests.physical_strategies import PHYSICAL_STRATEGIES
17wavenumbers_strategy = npst.arrays(
18 float,
19 npst.array_shapes(min_dims=1, max_dims=1, min_side=1, max_side=10),
20 elements=PHYSICAL_STRATEGIES[("wave", "wavenumber")],
21)
23frequencies_strategy = npst.arrays(
24 float,
25 npst.array_shapes(min_dims=1, max_dims=1, min_side=1, max_side=10),
26 elements=PHYSICAL_STRATEGIES[("wave", "frequency")],
27)
30class TestNoAttenuation:
31 @staticmethod
32 def test_unit():
33 assert att.no_attenuation() == 0
35 @staticmethod
36 @given(**coupled_ocean_ice, wavenumbers=wavenumbers_strategy)
37 def test_integrated(ice, ocean, gravity, wavenumbers):
38 fi = FloatingIce.from_ice_ocean(ice, ocean, gravity)
39 wup = WavesUnderElasticPlate(fi, wavenumbers)
40 wui = WavesUnderIce.without_attenuation(wup)
41 assert wui.attenuations == 0
44class TestParam01:
45 @staticmethod
46 @given(
47 thickness=PHYSICAL_STRATEGIES[("ice", "thickness")],
48 wavenumbers=wavenumbers_strategy,
49 )
50 def test_unit(thickness, wavenumbers):
51 attenuations = wavenumbers**2 * thickness / 4
52 assert np.allclose(
53 attenuations - att.parameterisation_01(thickness, wavenumbers), 0
54 )
56 @staticmethod
57 @given(**coupled_ocean_ice, wavenumbers=wavenumbers_strategy)
58 def test_integrated(ice, ocean, gravity, wavenumbers):
59 fi = FloatingIce.from_ice_ocean(ice, ocean, gravity)
60 wup = WavesUnderElasticPlate(fi, wavenumbers)
61 wui = WavesUnderIce.with_attenuation_01(wup)
62 assert np.allclose(
63 wui.attenuations - att.parameterisation_01(ice.thickness, wavenumbers), 0
64 )
67class TestYu2022:
68 @staticmethod
69 @given(
70 thickness=PHYSICAL_STRATEGIES[("ice", "thickness")],
71 gravity=PHYSICAL_STRATEGIES[("gravity",)],
72 frequencies=frequencies_strategy,
73 )
74 def test_unit(thickness: float, gravity: float, frequencies: np.ndarray):
75 prefactor, exponent = 0.108, 4.46
76 ang_freqs = 2 * np.pi * frequencies
77 nondim_ang_freqs = ang_freqs * np.sqrt(thickness / gravity)
78 nondim_attenuations = prefactor * nondim_ang_freqs**exponent
79 attenuations = nondim_attenuations / thickness
80 assert np.allclose(
81 attenuations, att.parameterisation_yu2022(thickness, gravity, ang_freqs)
82 )
84 @staticmethod
85 @given(**coupled_ocean_ice, spectrum=spec_mono() | spec_poly())
86 def test_integrated(
87 ice: Ice, ocean: Ocean, gravity: float, spectrum: DiscreteSpectrum
88 ):
90 fi = FloatingIce.from_ice_ocean(ice, ocean, gravity)
91 wup = WavesUnderElasticPlate.from_floating(fi, spectrum, gravity)
92 wui = WavesUnderIce.with_attenuation_yu2022(
93 wup, gravity, spectrum.angular_frequencies
94 )
96 assert np.allclose(
97 wui.attenuations,
98 att.parameterisation_yu2022(
99 ice.thickness, gravity, spectrum.angular_frequencies
100 ),
101 )
104class TestGeneric:
105 # Test passing a generic attenuation function against the existing
106 # parameterisations.
108 @staticmethod
109 @given(**coupled_ocean_ice, wavenumbers=wavenumbers_strategy)
110 def test_no_attenuation(ice, ocean, gravity, wavenumbers):
111 fi = FloatingIce.from_ice_ocean(ice, ocean, gravity)
112 wup = WavesUnderElasticPlate(fi, wavenumbers)
113 wui = WavesUnderIce.with_generic_attenuation(wup, lambda: 0)
114 wui_ref = WavesUnderIce.without_attenuation(wup)
115 assert wui.attenuations == wui_ref.attenuations
117 @staticmethod
118 @given(**coupled_ocean_ice, wavenumbers=wavenumbers_strategy)
119 def test_param01_args(ice, ocean, gravity, wavenumbers):
120 # Test Param01 providing arguments as a string
121 fi = FloatingIce.from_ice_ocean(ice, ocean, gravity)
122 wup = WavesUnderElasticPlate(fi, wavenumbers)
123 wui = WavesUnderIce.with_generic_attenuation(
124 wup,
125 lambda thickness, wavenumbers: wavenumbers**2 * thickness / 4,
126 "ice.thickness wavenumbers",
127 )
128 wui_ref = WavesUnderIce.with_attenuation_01(wup)
129 assert np.allclose(wui.attenuations - wui_ref.attenuations, 0)
131 @staticmethod
132 @given(**coupled_ocean_ice, wavenumbers=wavenumbers_strategy)
133 def test_param01_kwargs(ice, ocean, gravity, wavenumbers):
134 # Test Param01 providing arguments as a dict
135 fi = FloatingIce.from_ice_ocean(ice, ocean, gravity)
136 wup = WavesUnderElasticPlate(fi, wavenumbers)
137 wui = WavesUnderIce.with_generic_attenuation(
138 wup,
139 lambda thickness, wavenumbers: wavenumbers**2 * thickness / 4,
140 **{"thickness": ice.thickness, "wavenumbers": wavenumbers},
141 )
142 wui_ref = WavesUnderIce.with_attenuation_01(wup)
143 assert np.allclose(wui.attenuations - wui_ref.attenuations, 0)
145 @staticmethod
146 @given(**coupled_ocean_ice, spectrum=spec_mono() | spec_poly())
147 def test_yu2022(ice, ocean, gravity, spectrum: DiscreteSpectrum):
148 # Test Yu2022 providing arguments as a mix of string (accessible from
149 # WUI object) and dict (not accessible from WUI object).
150 fi = FloatingIce.from_ice_ocean(ice, ocean, gravity)
151 wup = WavesUnderElasticPlate.from_floating(fi, spectrum, gravity)
152 wui = WavesUnderIce.with_generic_attenuation(
153 wup,
154 lambda thickness, gravity, angfs: (
155 0.108 * (angfs * (thickness / gravity) ** 0.5) ** 4.46 / thickness
156 ),
157 "ice.thickness",
158 **{"gravity": gravity, "angfs": spectrum.angular_frequencies},
159 )
160 wui_ref = WavesUnderIce.with_attenuation_yu2022(
161 wup, gravity, spectrum.angular_frequencies
162 )
163 assert np.allclose(wui.attenuations, wui_ref.attenuations)