Coverage for tests/test_fracture.py: 99%
74 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-08-30 14:00 +0200
« prev ^ index » next coverage.py v7.4.1, created at 2024-08-30 14:00 +0200
1import pathlib
2import warnings
4import numpy as np
5import pytest
7import flexfrac1d.lib.phase_shift as ps
8import flexfrac1d.model.frac_handlers as fh
9from flexfrac1d.model.model import DiscreteSpectrum, Domain, Floe, Ice, Ocean
11fracture_handler_types = (
12 fh.BinaryFracture,
13 fh.BinaryStrainFracture,
14 fh.MultipleStrainFracture,
15)
16scattering_handler_types = (
17 ps.ContinuousScatteringHandler,
18 ps.UniformScatteringHandler,
19 ps.PerturbationScatteringHandler,
20)
22PATH_FRACTURE_TARGETS = pathlib.Path("tests/target/fracture")
23binary_energy_no_growth_target = np.loadtxt(
24 PATH_FRACTURE_TARGETS.joinpath("binary_fracture.ssv")
25)
26binary_strain_no_growth_target = np.loadtxt(
27 PATH_FRACTURE_TARGETS.joinpath("binary_strain_fracture.ssv")
28)
29multi_strain_no_growth_archive = np.load(
30 PATH_FRACTURE_TARGETS.joinpath("multi_strain_fracture.npz")
31)
32multi_strain_no_growth_target = (
33 (row, multi_strain_no_growth_archive[f"res{i:02d}"])
34 for i, row in enumerate(multi_strain_no_growth_archive["params"])
35)
38def make_wuf(array, growth_params):
39 (
40 frac_toughness,
41 strain_threshold,
42 thickness,
43 youngs_modulus,
44 depth,
45 gravity,
46 amplitude,
47 frequency,
48 length,
49 left_edge,
50 phase,
51 ) = array
53 ice = Ice(
54 frac_toughness=frac_toughness,
55 strain_threshold=strain_threshold,
56 thickness=thickness,
57 youngs_modulus=youngs_modulus,
58 )
59 ocean = Ocean(depth=depth)
60 spectrum = DiscreteSpectrum(
61 amplitudes=amplitude, frequencies=frequency, phases=phase
62 )
63 domain = Domain.from_discrete(gravity, spectrum, ocean, None, growth_params)
64 floe = Floe(left_edge=left_edge, length=length, ice=ice)
65 domain.add_floes(floe)
66 return domain.subdomains[0]
69def test_abstract():
70 # Abstract classes, should not be instantiated
71 with pytest.raises(TypeError):
72 fh._FractureHandler()
73 with pytest.raises(TypeError):
74 fh._StrainFracture()
77@pytest.mark.parametrize("fracture_handler_type", fracture_handler_types)
78@pytest.mark.parametrize("scattering_spec_type", scattering_handler_types)
79def test_initialisation_scattering(fracture_handler_type, scattering_spec_type):
80 rng_seed = 13
82 loc, scale = 0.3, 0.005
84 if scattering_spec_type == ps.ContinuousScatteringHandler:
85 scattering_spec = scattering_spec_type()
86 elif scattering_spec_type == ps.UniformScatteringHandler:
87 scattering_spec = scattering_spec_type.from_seed(rng_seed)
88 elif scattering_spec_type == ps.PerturbationScatteringHandler: 88 ↛ 91line 88 didn't jump to line 91, because the condition on line 88 was never false
89 scattering_spec = scattering_spec_type.from_seed(rng_seed, loc, scale)
91 fracture_handler: fh._FractureHandler = fracture_handler_type(
92 scattering_handler=scattering_spec
93 )
94 assert isinstance(fracture_handler, fracture_handler_type)
95 assert isinstance(fracture_handler.scattering_handler, scattering_spec_type)
98@pytest.mark.slow
99@pytest.mark.parametrize("row", binary_energy_no_growth_target)
100def test_binary_energy_no_growth(row):
101 growth_params = None
102 an_sol = True
103 binary_handler = fh.BinaryFracture()
105 wuf = make_wuf(row[:-1], growth_params)
106 xf = binary_handler.search(wuf, growth_params, an_sol, None)
107 if xf is not None:
108 # HACK: tests pass locally but need to be tweeked for CI
109 try:
110 assert np.allclose(row[-1] - xf, 0)
111 except AssertionError: # pragma: no cover
112 assert np.allclose(row[-1] - xf, 0, atol=1e-5)
113 warnings.warn(
114 f"Absolute error greater than 1e-8: target {row[-1]}, computed {xf}, "
115 f"diff is {row[-1] - xf}",
116 stacklevel=2,
117 )
118 else:
119 assert np.isnan(row[-1])
122@pytest.mark.parametrize("row", binary_strain_no_growth_target)
123def test_binary_strain_no_growth(row):
124 growth_params = None
125 an_sol = True
126 binary_handler = fh.BinaryStrainFracture()
128 wuf = make_wuf(row[:-1], growth_params)
129 xf = binary_handler.search(wuf, growth_params, an_sol, None)
130 if xf is not None:
131 assert np.allclose(row[-1] - xf, 0)
132 else:
133 assert np.isnan(row[-1])
136@pytest.mark.parametrize("row, target", multi_strain_no_growth_target)
137def test_multi_strain_no_growth(row, target):
138 growth_params = None
139 an_sol = True
140 handler = fh.MultipleStrainFracture()
142 wuf = make_wuf(row, growth_params)
143 xfs = handler.search(wuf, growth_params, an_sol, None)
144 if xfs is not None:
145 assert np.allclose(target - xfs, 0)
146 else:
147 assert np.isnan(target)