Skip to content

Commit 35b4040

Browse files
test(earthprops): add tests for vertical and horizontal earth model rules
1 parent 998d0c5 commit 35b4040

1 file changed

Lines changed: 252 additions & 0 deletions

File tree

test/earthprops.jl

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
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

Comments
 (0)