1+ using Test
2+ using LineCableModels
3+ using DataFrames
4+ using Measurements
5+
6+ # Access internal components for testing
7+ const LCM = LineCableModels
8+ const EP = LCM. EarthProps
9+
10+ @testset " EarthProps module" begin
11+
12+ @testset " FDEM Formulations" begin
13+ @testset " CPEarth" begin
14+ cp_formulation = EP. CPEarth ()
15+ @test cp_formulation isa EP. AbstractFDEMFormulation
16+ @test EP. _get_description (cp_formulation) == " CP model"
17+ end
18+ end
19+
20+ @testset " _calc_earth_properties" begin
21+ frequencies = [50.0 , 60.0 , 1000.0 ]
22+ base_rho_g = 100.0
23+ base_epsr_g = 10.0
24+ base_mur_g = 1.0
25+ formulation = EP. CPEarth ()
26+
27+ @testset " Float64 inputs" begin
28+ rho, epsilon, mu = EP. _calc_earth_properties (frequencies, base_rho_g, base_epsr_g, base_mur_g, formulation)
29+
30+ @test length (rho) == length (frequencies)
31+ @test all (r -> r == base_rho_g, rho)
32+
33+ @test length (epsilon) == length (frequencies)
34+ @test all (e -> isapprox (e, LCM. ε₀ * base_epsr_g), epsilon)
35+
36+ @test length (mu) == length (frequencies)
37+ @test all (m -> isapprox (m, LCM. μ₀ * base_mur_g), mu)
38+ end
39+
40+ @testset " Measurement inputs" begin
41+ rho_m = 100.0 ± 5.0
42+ epsr_m = 10.0 ± 0.5
43+ mur_m = 1.0 ± 0.01
44+
45+ rho, epsilon, mu = EP. _calc_earth_properties (frequencies, rho_m, epsr_m, mur_m, formulation)
46+
47+ @test length (rho) == length (frequencies)
48+ @test all (r -> r == rho_m, rho)
49+
50+ @test length (epsilon) == length (frequencies)
51+ @test all (e -> e. val ≈ (LCM. ε₀ * epsr_m). val, epsilon)
52+ @test all (e -> e. err ≈ (LCM. ε₀ * epsr_m). err, epsilon)
53+
54+ @test length (mu) == length (frequencies)
55+ @test all (m -> m. val ≈ (LCM. μ₀ * mur_m). val, mu)
56+ @test all (m -> m. err ≈ (LCM. μ₀ * mur_m). err, mu)
57+ end
58+ end
59+
60+ @testset " EarthLayer Constructor" begin
61+ frequencies = [50.0 , 60.0 ]
62+ base_rho_g = 100.0
63+ base_epsr_g = 10.0
64+ base_mur_g = 1.0
65+ t = 5.0
66+ formulation = EP. CPEarth ()
67+
68+ layer = EP. EarthLayer (frequencies, base_rho_g, base_epsr_g, base_mur_g, t, formulation)
69+
70+ @test layer. base_rho_g == base_rho_g
71+ @test layer. base_epsr_g == base_epsr_g
72+ @test layer. base_mur_g == base_mur_g
73+ @test layer. t == t
74+ @test length (layer. rho_g) == length (frequencies)
75+ @test all (layer. rho_g .== base_rho_g)
76+ end
77+
78+ @testset " EarthModel Constructor" begin
79+ frequencies = [50.0 , 60.0 ]
80+ rho_g = 100.0
81+ epsr_g = 10.0
82+ mur_g = 1.0
83+
84+ @testset " Homogeneous Model" begin
85+ model = EarthModel (frequencies, rho_g, epsr_g, mur_g)
86+ @test length (model. layers) == 2 # Air + 1 earth layer
87+ @test model. vertical_layers == false
88+ @test model. FDformulation isa EP. CPEarth
89+ @test isinf (model. layers[1 ]. t) # Air layer
90+ @test isinf (model. layers[2 ]. t) # Homogeneous earth
91+ @test model. layers[2 ]. base_rho_g == rho_g
92+ end
93+
94+ @testset " Finite Thickness Layer" begin
95+ model = EarthModel (frequencies, rho_g, epsr_g, mur_g, t= 20.0 )
96+ @test length (model. layers) == 2
97+ @test model. layers[2 ]. t == 20.0
98+ end
99+
100+ @testset " Vertical Layers" begin
101+ model = EarthModel (frequencies, rho_g, epsr_g, mur_g, vertical_layers= true )
102+ @test model. vertical_layers == true
103+ end
104+
105+ @testset " Input Validation" begin
106+ @test_throws AssertionError EarthModel ([- 50.0 ], rho_g, epsr_g, mur_g)
107+ @test_throws AssertionError EarthModel (frequencies, - 100.0 , epsr_g, mur_g)
108+ @test_throws AssertionError EarthModel (frequencies, rho_g, - 10.0 , mur_g)
109+ @test_throws AssertionError EarthModel (frequencies, rho_g, epsr_g, - 1.0 )
110+ @test_throws AssertionError EarthModel (frequencies, rho_g, epsr_g, mur_g, t= - 5.0 )
111+ end
112+ end
113+
114+ @testset " add! for EarthModel" begin
115+ frequencies = [50.0 , 60.0 ]
116+
117+ @testset " Horizontal Layering" begin
118+ model = EarthModel (frequencies, 100.0 , 10.0 , 1.0 , t= 20.0 )
119+ @test length (model. layers) == 2
120+
121+ add! (model, frequencies, 200.0 , 15.0 , 1.0 , t= 50.0 )
122+ @test length (model. layers) == 3
123+ @test model. layers[3 ]. base_rho_g == 200.0
124+ @test model. layers[3 ]. t == 50.0
125+
126+ add! (model, frequencies, 500.0 , 20.0 , 1.0 , t= Inf )
127+ @test length (model. layers) == 4
128+ @test isinf (model. layers[4 ]. t)
129+
130+ # Test invalid addition
131+ @test_throws ErrorException add! (model, frequencies, 1000.0 , 25.0 , 1.0 , t= Inf )
132+ end
133+
134+ @testset " Input Validation in add!" begin
135+ model = EarthModel (frequencies, 100.0 , 10.0 , 1.0 , t= 20.0 )
136+ @test_throws AssertionError add! (model, [- 50.0 ], 200.0 , 15.0 , 1.0 )
137+ @test_throws AssertionError add! (model, frequencies, - 200.0 , 15.0 , 1.0 )
138+ @test_throws AssertionError add! (model, frequencies, 200.0 , - 15.0 , 1.0 )
139+ @test_throws AssertionError add! (model, frequencies, 200.0 , 15.0 , - 1.0 )
140+ @test_throws AssertionError add! (model, frequencies, 200.0 , 15.0 , 1.0 , t= - 5.0 )
141+ end
142+ end
143+
144+ @testset " Consecutive Infinite Layer Checks" begin
145+ frequencies = [50.0 ]
146+ @testset " Horizontal Model" begin
147+ model = EarthModel (frequencies, 100.0 , 10.0 , 1.0 , t= Inf )
148+ # It's an error to add any layer after an infinite one in a horizontal model
149+ @test_throws ErrorException add! (model, frequencies, 200.0 , 15.0 , 1.0 , t= 10.0 )
150+ @test_throws ErrorException add! (model, frequencies, 200.0 , 15.0 , 1.0 , t= Inf )
151+ end
152+
153+ @testset " Vertical Model" begin
154+ # Setup: model with two earth layers, the second being infinite
155+ model = EarthModel (frequencies, 100.0 , 10.0 , 1.0 , t= Inf , vertical_layers= true )
156+ add! (model, frequencies, 150.0 , 12.0 , 1.0 , t= 20.0 ) # Add one more layer
157+ add! (model, frequencies, 150.0 , 12.0 , 1.0 , t= Inf ) # Add one more layer, now Inf
158+
159+ # It's an error to add another infinite layer
160+ @test_throws ErrorException add! (model, frequencies, 200.0 , 15.0 , 1.0 , t= Inf )
161+
162+ # It should not be posssible to add a finite layer after an infinite one
163+ @test_throws ErrorException add! (model, frequencies, 300.0 , 20.0 , 1.0 , t= 5.0 )
164+ @test length (model. layers) == 4
165+ @test model. layers[4 ]. base_rho_g == 150.0
166+ @test isinf (model. layers[4 ]. t) # The last layer should still be infinite
167+ end
168+ end
169+
170+ @testset " show method for EarthModel" begin
171+ frequencies = [50.0 ]
172+ # Homogeneous model
173+ model_homo = EarthModel (frequencies, 100.0 , 10.0 , 1.0 )
174+ s_homo = sprint (show, " text/plain" , model_homo)
175+ @test contains (s_homo, " EarthModel with 1 horizontal earth layer (homogeneous)" )
176+ @test contains (s_homo, " └─ Layer 2: [rho_g=100.0, epsr_g=10.0, mur_g=1.0, t=∞]" )
177+
178+ # Multilayer horizontal model
179+ model_multi_h = EarthModel (frequencies, 100.0 , 10.0 , 1.0 , t= 20.0 )
180+ add! (model_multi_h, frequencies, 200.0 , 15.0 , 1.0 , t= Inf )
181+ s_multi_h = sprint (show, " text/plain" , model_multi_h)
182+ @test contains (s_multi_h, " EarthModel with 2 horizontal earth layers (multilayer)" )
183+ @test contains (s_multi_h, " ├─ Layer 2: [rho_g=100.0, epsr_g=10.0, mur_g=1.0, t=20.0]" )
184+ @test contains (s_multi_h, " └─ Layer 3: [rho_g=200.0, epsr_g=15.0, mur_g=1.0, t=∞]" )
185+
186+ # Multilayer vertical model
187+ model_multi_v = EarthModel (frequencies, 100.0 , 10.0 , 1.0 , t= Inf , vertical_layers= true )
188+ add! (model_multi_v, frequencies, 200.0 , 15.0 , 1.0 , t= 30.0 )
189+ s_multi_v = sprint (show, " text/plain" , model_multi_v)
190+ @test contains (s_multi_v, " EarthModel with 2 vertical earth layers (multilayer)" )
191+ @test contains (s_multi_v, " ├─ Layer 2: [rho_g=100.0, epsr_g=10.0, mur_g=1.0, t=∞]" )
192+ @test contains (s_multi_v, " └─ Layer 3: [rho_g=200.0, epsr_g=15.0, mur_g=1.0, t=30.0]" )
193+ end
194+
195+ @testset " DataFrame for EarthModel" begin
196+ frequencies = [50.0 ]
197+ model = EarthModel (frequencies, 100.0 , 10.0 , 1.0 , t= 20.0 )
198+ add! (model, frequencies, 200.0 , 15.0 , 1.0 , t= Inf )
199+
200+ df = DataFrame (model)
201+ @test df isa DataFrame
202+ @test names (df) == [" rho_g" , " epsr_g" , " mur_g" , " thickness" ]
203+ @test nrow (df) == 3
204+
205+ # Air layer
206+ @test isinf (df. rho_g[1 ])
207+ @test df. epsr_g[1 ] == 1.0
208+ @test df. mur_g[1 ] == 1.0
209+ @test isinf (df. thickness[1 ])
210+
211+ # First earth layer
212+ @test df. rho_g[2 ] == 100.0
213+ @test df. epsr_g[2 ] == 10.0
214+ @test df. thickness[2 ] == 20.0
215+
216+ # Second earth layer
217+ @test df. rho_g[3 ] == 200.0
218+ @test df. epsr_g[3 ] == 15.0
219+ @test isinf (df. thickness[3 ])
220+ end
221+
222+ @testset " show for EarthModel" begin
223+ frequencies = [50.0 , 60.0 ]
224+
225+ @testset " Homogeneous Horizontal" begin
226+ model = EarthModel (frequencies, 100.0 , 10.0 , 1.0 )
227+ str_repr = sprint (show, " text/plain" , model)
228+ @test occursin (" EarthModel with 1 horizontal earth layer (homogeneous) and 2 frequency samples" , str_repr)
229+ @test occursin (" └─ Layer 2:" , str_repr)
230+ @test occursin (" t=∞" , str_repr)
231+ @test occursin (" Frequency-dependent model: CP model" , str_repr)
232+ end
233+
234+ @testset " Multilayer Horizontal" begin
235+ model = EarthModel (frequencies, 100.0 , 10.0 , 1.0 , t= 20.0 )
236+ add! (model, frequencies, 200.0 , 15.0 , 1.0 , t= Inf )
237+ str_repr = sprint (show, " text/plain" , model)
238+ @test occursin (" EarthModel with 2 horizontal earth layers (multilayer) and 2 frequency samples" , str_repr)
239+ @test occursin (" ├─ Layer 2:" , str_repr)
240+ @test occursin (" └─ Layer 3:" , str_repr)
241+ @test occursin (" t=20" , str_repr)
242+ end
243+
244+ @testset " Multilayer Vertical" begin
245+ model = EarthModel (frequencies, 100.0 , 10.0 , 1.0 , t= Inf , vertical_layers= true )
246+ add! (model, frequencies, 200.0 , 15.0 , 1.0 , t= 5.0 )
247+ str_repr = sprint (show, " text/plain" , model)
248+ @test occursin (" EarthModel with 2 vertical earth layers (multilayer) and 2 frequency samples" , str_repr)
249+ @test occursin (" t=5" , str_repr)
250+ end
251+ end
252+ end
0 commit comments