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

1from hypothesis import given 

2import hypothesis.extra.numpy as npst 

3import numpy as np 

4 

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 

16 

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) 

22 

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) 

28 

29 

30class TestNoAttenuation: 

31 @staticmethod 

32 def test_unit(): 

33 assert att.no_attenuation() == 0 

34 

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 

42 

43 

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 ) 

55 

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 ) 

65 

66 

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 ) 

83 

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 ): 

89 

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 ) 

95 

96 assert np.allclose( 

97 wui.attenuations, 

98 att.parameterisation_yu2022( 

99 ice.thickness, gravity, spectrum.angular_frequencies 

100 ), 

101 ) 

102 

103 

104class TestGeneric: 

105 # Test passing a generic attenuation function against the existing 

106 # parameterisations. 

107 

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 

116 

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) 

130 

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) 

144 

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)