Coverage for tests/conftest.py: 97%

1 from hypothesis import strategies as st (empty)

2 import numpy as np (empty)

3

4 from swiift.lib.constants import PI_2 (empty)

5 from swiift.model.model import DiscreteSpectrum, Floe, Ice, Ocean (empty)

6

7# Generic float options

8 float_kw = { (empty)

9 "allow_nan": False,

10 "allow_subnormal": False,

11}

12

13

14# For the composite strategies, set somewhat stricter upper bounds than plain

15# inequality to avoid head-scratching floating point innacuracies

16@st.composite (empty)

17 def ice_density(draw, ocean_density): (empty)

18 ex = draw(ocean_density) 1 ctx 1b

19 return draw(st.floats(10, 0.9999 * ex, **float_kw)) 1 ctx 1b

20

21

22@st.composite (empty)

23 def ice_thickness(draw, ocean_density, ocean_depth, ice_density): (empty)

24 kwgs = {"rhow": ocean_density, "rhoi": ice_density, "H": ocean_depth} 1 ctx 1b

25 ex = {k: draw(v) for k, v in kwgs.items()} 1 ctx 1b

26 upper_bound = 0.9999 * ex["rhow"] / ex["rhoi"] * ex["H"] 1 ctx 1b

27 return draw(st.floats(0.1e-3, min(1000, upper_bound), exclude_max=True, **float_kw)) 1 ctx 1b

28

29

30@st.composite (empty)

31 def floe_length(draw, ice: Ice) -> float: (empty)

32 return draw(st.floats(2 * draw(ice).thickness, 1000e3, **float_kw))

33

34

35# All SI units

36 physical_strategies = { (empty)

37 "floe": {

38 "left_edge": st.floats(0, 5e3, **float_kw),

39 },

40 "ocean": {

41 "depth": (

42 st.floats(min_value=1e-3, max_value=1000e3, **float_kw) | st.just(np.inf)

43 ),

44 "density": st.floats(500, 5e3, **float_kw),

45 },

46 "ice": {

47 "frac_toughness": st.floats(1e3, 1e7, **float_kw),

48 "poissons_ratio": st.floats(-0.999, 0.5, **float_kw),

49 "strain_threshold": st.floats(1e-7, 1e-3, **float_kw),

50 "thickness": st.floats(1e-3, 1e3, **float_kw),

51 "youngs_modulus": st.floats(1e6, 100e9, **float_kw),

52 "elastic_length": st.floats(

53 5e-4, 3e4, **float_kw

54 ), # derived from the bounds on its constituents

55 },

56 "wave": {

57 "amplitude": st.floats(1e-6, 1e3, **float_kw),

58 "period": st.floats(min_value=1e-1, max_value=1e4, **float_kw),

59 "frequency": st.floats(min_value=1e-4, max_value=10, **float_kw),

60 "phase": st.floats(0, PI_2, exclude_max=True, **float_kw),

61 "wavenumber": st.floats(

62 7e-4, 600, **float_kw

63 ), # covers waves from about 10 cm to 10 km

64 },

65 "gravity": st.floats(0.1, 30, **float_kw),

66}

67

68

69 physical_strategies["floe"]["length"] = floe_length (empty)

70 physical_strategies["ice"]["density_coupled"] = ice_density (empty)

71 physical_strategies["ice"]["thickness_coupled"] = ice_thickness (empty)

72

73

74@st.composite (empty)

75 def spec_mono(draw): (empty)

76 return DiscreteSpectrum( 1 ctx 1b

77 draw(st.just(0.5)), draw(physical_strategies["wave"]["frequency"])

78 )

79

80

81@st.composite (empty)

82 def spec_poly(draw): (empty)

83 n = draw(st.integers(min_value=2, max_value=10)) 1 ctx 1b

84 amplitudes = draw( 1 ctx 1b

85 st.lists(

86 physical_strategies["wave"]["amplitude"],

87 min_size=n,

88 max_size=n,

89 unique=True,

90 )

91 )

92 frequencies = draw( 1 ctx 1b

93 st.lists(

94 physical_strategies["wave"]["frequency"],

95 min_size=n,

96 max_size=n,

97 unique=True,

98 )

99 )

100 # phases = draw(

101 # st.lists(

102 # physical_strategies["wave"]["phase"],

103 # min_size=n,

104 # max_size=n,

105 # unique=True,

106 # )

107 # )

108 return DiscreteSpectrum(amplitudes, frequencies) 1 ctx 1b

109

110

111 ocean_and_mono_spectrum = { (empty)

112 "ocean": st.builds(

113 Ocean,

114 depth=physical_strategies["ocean"]["depth"],

115 density=physical_strategies["ocean"]["density"],

116 ),

117 "spectrum": spec_mono(),

118 "gravity": physical_strategies["gravity"],

119}

120

121 ocean_and_poly_spectrum = { (empty)

122 "ocean": st.builds(

123 Ocean,

124 depth=physical_strategies["ocean"]["depth"],

125 density=physical_strategies["ocean"]["density"],

126 ),

127 "spectrum": spec_poly(),

128 "gravity": physical_strategies["gravity"],

129}

130

131 ocean_and_spectrum = { (empty)

132 "ocean": st.builds(

133 Ocean,

134 depth=physical_strategies["ocean"]["depth"],

135 density=physical_strategies["ocean"]["density"],

136 ),

137 "spectrum": spec_mono() | spec_poly(),

138 "gravity": physical_strategies["gravity"],

139}

140

141 coupled_ocean_ice = { (empty)

142 "ocean": st.builds(

143 Ocean,

144 depth=st.shared(physical_strategies["ocean"]["depth"], key="H"),

145 density=st.shared(physical_strategies["ocean"]["density"], key="rhow"),

146 ),

147 "ice": st.shared(

148 st.builds(

149 Ice,

150 density=st.shared(

151 physical_strategies["ice"]["density_coupled"](

152 st.shared(physical_strategies["ocean"]["density"], key="rhow")

153 ),

154 key="rhoi",

155 ),

156 frac_toughness=physical_strategies["ice"]["frac_toughness"],

157 poissons_ratio=physical_strategies["ice"]["poissons_ratio"],

158 thickness=physical_strategies["ice"]["thickness_coupled"](

159 ocean_depth=st.shared(physical_strategies["ocean"]["depth"], key="H"),

160 ocean_density=st.shared(

161 physical_strategies["ocean"]["density"], key="rhow"

162 ),

163 ice_density=st.shared(

164 physical_strategies["ice"]["density_coupled"](

165 st.shared(physical_strategies["ocean"]["density"], key="rhow")

166 ),

167 key="rhoi",

168 ),

169 ),

170 youngs_modulus=physical_strategies["ice"]["youngs_modulus"],

171 ),

172 key="ice",

173 ),

174 "gravity": physical_strategies["gravity"],

175}

176

177 coupled_floe = { (empty)

178 "floe": st.builds(

179 Floe,

180 left_edge=physical_strategies["floe"]["left_edge"],

181 length=physical_strategies["floe"]["length"](

182 st.shared(coupled_ocean_ice["ice"], key="ice")

183 ),

184 ice=st.shared(coupled_ocean_ice["ice"], key="ice"),

185 )

186} | coupled_ocean_ice

187

188 simple_objects = { (empty)

189 "ocean": Ocean(),

190 "ice": Ice(),

191 "spec_mono": DiscreteSpectrum(0.5, 1 / 7),

192 "spec_poly": DiscreteSpectrum((0.1, 0.2), (1 / 7, 1 / 5)),

193 "gravity": 9.8,

194 "length": 101.5,

195 "left_edge": 13.8,

196}