Skip to content

Commit 23e1d40

Browse files
feat(datamodel): add baseparams directory to datamodel module
1 parent 08c40f0 commit 23e1d40

14 files changed

Lines changed: 3145 additions & 0 deletions

File tree

src/datamodel/baseparams/BaseParams.jl

Lines changed: 1370 additions & 0 deletions
Large diffs are not rendered by default.

src/datamodel/radii.jl

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
"""
2+
$(TYPEDSIGNATURES)
3+
4+
Resolves radius parameters for cable components, converting from various input formats to standardized inner radius, outer radius, and thickness values.
5+
6+
This function serves as a high-level interface to the radius resolution system. It processes inputs through a two-stage pipeline:
7+
1. First normalizes input parameters to consistent forms using [`_parse_radius_operand`](@ref).
8+
2. Then delegates to specialized implementations via [`_do_resolve_radius`](@ref) based on the component type.
9+
10+
# Arguments
11+
12+
- `param_in`: Inner boundary parameter (defaults to radius) \\[m\\].
13+
Can be a number, a [`Diameter`](@ref) , a [`Thickness`](@ref), or an [`AbstractCablePart`](@ref).
14+
- `param_ext`: Outer boundary parameter (defaults to radius) \\[m\\].
15+
Can be a number, a [`Diameter`](@ref) , a [`Thickness`](@ref), or an [`AbstractCablePart`](@ref).
16+
- `object_type`: Type associated to the constructor of the new [`AbstractCablePart`](@ref).
17+
18+
# Returns
19+
20+
- `radius_in`: Normalized inner radius \\[m\\].
21+
- `radius_ext`: Normalized outer radius \\[m\\].
22+
- `thickness`: Computed thickness or specialized dimension depending on the method \\[m\\].
23+
For [`WireArray`](@ref) components, this value represents the wire radius instead of thickness.
24+
25+
# See also
26+
27+
- [`Diameter`](@ref)
28+
- [`Thickness`](@ref)
29+
- [`AbstractCablePart`](@ref)
30+
"""
31+
@inline _normalize_radii(::Type{T}, rin, rex) where {T} =
32+
_do_normalize_radii(_parse_radius_operand(rin, T), _parse_radius_operand(rex, T), T)
33+
34+
"""
35+
$(TYPEDSIGNATURES)
36+
37+
Parses input values into radius representation based on object type and input type.
38+
39+
# Arguments
40+
41+
- `x`: Input value that can be a raw number, a [`Diameter`](@ref), a [`Thickness`](@ref), or other convertible type \\[m\\].
42+
- `object_type`: Type parameter used for dispatch.
43+
44+
# Returns
45+
46+
- Parsed radius value in appropriate units \\[m\\].
47+
48+
# Examples
49+
50+
```julia
51+
radius = $(FUNCTIONNAME)(10.0, ...) # Direct radius value
52+
radius = $(FUNCTIONNAME)(Diameter(20.0), ...) # From diameter object
53+
radius = $(FUNCTIONNAME)(Thickness(5.0), ...) # From thickness object
54+
```
55+
56+
# Methods
57+
58+
$(METHODLIST)
59+
60+
# See also
61+
62+
- [`Diameter`](@ref)
63+
- [`Thickness`](@ref)
64+
"""
65+
function _parse_radius_operand end
66+
67+
# ------------ Input parsing
68+
@inline _parse_radius_operand(x::Number, ::Type{T}) where {T} = x
69+
@inline _parse_radius_operand(d::Diameter, ::Type{T}) where {T} = d.value / 2
70+
@inline _parse_radius_operand(p::Thickness, ::Type{T}) where {T} = p
71+
@inline function _parse_radius_operand(p::AbstractCablePart, ::Type{T}) where {T}
72+
r = getfield(p, :radius_ext) # outer radius of prior layer
73+
return (typeof(p) == T) ? r : to_certain(r)
74+
end
75+
@inline _parse_radius_operand(x::AbstractString, ::Type{T}) where {T} =
76+
throw(ArgumentError("[$(nameof(T))] radius parameter must be numeric, not String: $(repr(x))"))
77+
@inline _parse_radius_operand(x, ::Type{T}) where {T} =
78+
throw(ArgumentError("[$(nameof(T))] unsupported radius parameter $(typeof(x)): $(repr(x))"))
79+
80+
81+
82+
# ------------ Input parsing
83+
@inline function _do_normalize_radii(radius_in::Number, radius_ext::Number, ::Type{T}) where {T}
84+
return radius_in, radius_ext
85+
end
86+
87+
@inline function _do_normalize_radii(radius_in::Number, thickness::Thickness, ::Type{T}) where {T}
88+
return radius_in, (radius_in + thickness.value)
89+
end
90+
91+
@inline function _do_normalize_radii(radius_in::Number, radius_wire::Number, ::Type{AbstractWireArray})
92+
return radius_in, radius_in + (2 * radius_wire)
93+
end
94+
95+
@inline function _do_normalize_radii(t::Thickness, rex::Number, ::Type{T}) where {T}
96+
rin = rex - t.value
97+
rin >= 0 || throw(ArgumentError("[$(nameof(T))] thickness $(t.value) exceeds outer radius $(rex)."))
98+
return rin, rex
99+
end
100+
101+
# NEW: reject thickness on BOTH ends
102+
@inline function _do_normalize_radii(::Thickness, ::Thickness, ::Type{T}) where {T}
103+
throw(ArgumentError("[$(nameof(T))] cannot specify thickness for both inner and outer radii."))
104+
end
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
"""
2+
LineCableModels.Engine.EarthAdmittance
3+
4+
# Dependencies
5+
6+
$(IMPORTS)
7+
8+
# Exports
9+
10+
$(EXPORTS)
11+
"""
12+
module EarthAdmittance
13+
14+
# Export public API
15+
# export
16+
17+
# Module-specific dependencies
18+
using ...Commons
19+
import ...Commons: get_description
20+
import ..Engine: EarthAdmittanceFormulation
21+
using Measurements
22+
23+
struct Papadopoulos <: EarthAdmittanceFormulation end
24+
get_description(::Papadopoulos) = "Papadopoulos (homogeneous earth)"
25+
26+
function calc_self_potential_coeff_papadopoulos(
27+
h::Vector{Measurement{Float64}},
28+
r::Vector{Measurement{Float64}},
29+
eps_g::Measurement{Float64},
30+
mu_g::Measurement{Float64},
31+
sigma_g::Measurement{Float64},
32+
f::Float64,
33+
con::Int,
34+
kx::Int=0,
35+
)
36+
37+
# Constants
38+
sig0 = 0.0
39+
eps0 = 8.8541878128e-12
40+
mu0 = 4 * pi * 1e-7
41+
w = 2 * pi * f
42+
43+
# Define k_x based on input kx type
44+
# 0 = neglect propagation constant
45+
# 1 = use value of layer 1 (air)
46+
# 2 = use value of layer 2 (earth)
47+
k_x = if kx == 2
48+
ω -> ω * sqrt(mu_g * (eps_g - im * (sigma_g / ω)))
49+
elseif kx == 1
50+
ω -> ω * sqrt(mu0 * eps0)
51+
else
52+
ω -> ω * 0.0 # Default to zero
53+
end
54+
55+
# Define gamma and a functions
56+
gamma_0 = ω -> sqrt(im * ω * mu0 * (sig0 + im * ω * eps0))
57+
gamma_1 = ω -> sqrt(im * ω * mu_g * (sigma_g + im * ω * eps_g))
58+
a_0 = (λ, ω) -> sqrt^2 + gamma_0(ω)^2 + k_x(ω)^2)
59+
a_1 = (λ, ω) -> sqrt^2 + gamma_1(ω)^2 + k_x(ω)^2)
60+
61+
Pg_self = zeros(Complex{Measurement{Float64}}, con, con)
62+
TOL = 1e-3
63+
64+
for k 1:con
65+
if h[k] < 0
66+
yy =
67+
(a0, a1, gamma0, gamma1, hi, hj, λ, mu0, mu_g, ω, y) ->
68+
(
69+
1.0 / gamma1^2 *
70+
mu_g *
71+
ω *
72+
exp(-a1 * abs(hi - hj + TOL)) *
73+
cos* y) *
74+
0.5im
75+
) / (a1 * pi) -
76+
(
77+
1.0 / gamma1^2 *
78+
mu_g *
79+
ω *
80+
exp(a1 * (hi + hj)) *
81+
cos* y) *
82+
(a0 * mu_g + a1 * mu0 * sign(hi)) *
83+
0.5im
84+
) / (a1 * pi * (a0 * mu_g + a1 * mu0)) +
85+
(
86+
a1 * 1.0 / gamma1^2 *
87+
mu0 *
88+
mu_g^2 *
89+
ω *
90+
exp(a1 * (hi + hj)) *
91+
cos* y) *
92+
(sign(hi) - 1.0) *
93+
(gamma0^2 - gamma1^2) *
94+
0.5im
95+
) / (
96+
pi *
97+
(a0 * gamma1^2 * mu0 + a1 * gamma0^2 * mu_g) *
98+
(a0 * mu_g + a1 * mu0)
99+
)
100+
101+
yfun =
102+
λ -> yy(
103+
a_0(λ, w),
104+
a_1(λ, w),
105+
gamma_0(w),
106+
gamma_1(w),
107+
h[k],
108+
h[k],
109+
λ,
110+
mu0,
111+
mu_g,
112+
w,
113+
r[k],
114+
)
115+
Qs, _ = quadgk(yfun, 0, Inf, rtol=1e-6)
116+
Pg_self[k, k] = (im * w * Qs)
117+
end
118+
end
119+
120+
return Pg_self
121+
end
122+
123+
"""
124+
calc_mutual_potential_coeff_papadopoulos(h, d, eps_g, mu_g, sigma_g, f, con; kx=0)
125+
126+
Calculates the mutual earth potential coefficient between conductors using the Papadopoulos
127+
formula, considering the properties of the ground and the frequency of the system.
128+
129+
# Arguments
130+
- `h`: Vector of vertical distances to ground for conductors.
131+
- `d`: Matrix of distances between conductors.
132+
- `eps_g`: Relative permittivity of the earth.
133+
- `mu_g`: Permeability of the earth.
134+
- `sigma_g`: Conductivity of the earth.
135+
- `f`: Frequency of the system (in Hz).
136+
- `con`: Number of conductors in the system.
137+
- `kx`: An optional flag for selecting propagation constant:
138+
- `0`: Default, no propagation constant.
139+
- `1`: Propagation constant for air.
140+
- `2`: Propagation constant for earth.
141+
142+
# Returns
143+
- `Matrix{Complex{Measurement{Float64}}}`: The mutual earth potential coefficient matrix for the given conductors.
144+
145+
# Category: Earth-return impedances and admittances
146+
147+
"""
148+
function calc_mutual_potential_coeff_papadopoulos(
149+
h::Vector{Measurement{Float64}},
150+
d::Matrix{Measurement{Float64}},
151+
eps_g::Measurement{Float64},
152+
mu_g::Measurement{Float64},
153+
sigma_g::Measurement{Float64},
154+
f::Float64,
155+
con::Int,
156+
kx::Int=0,
157+
)
158+
159+
# Constants
160+
sig0 = 0.0
161+
eps0 = 8.8541878128e-12
162+
mu0 = 4 * pi * 1e-7
163+
w = 2 * pi * f
164+
165+
# Define k_x based on input kx type
166+
# 0 = neglect propagation constant
167+
# 1 = use value of layer 1 (air)
168+
# 2 = use value of layer 2 (earth)
169+
k_x = if kx == 2
170+
ω -> ω * sqrt(mu_g * (eps_g - im * (sigma_g / ω)))
171+
elseif kx == 1
172+
ω -> ω * sqrt(mu0 * eps0)
173+
else
174+
ω -> ω * 0.0 # Default to zero
175+
end
176+
177+
# Define gamma and a functions
178+
gamma_0 = ω -> sqrt(im * ω * mu0 * (sig0 + im * ω * eps0))
179+
gamma_1 = ω -> sqrt(im * ω * mu_g * (sigma_g + im * ω * eps_g))
180+
a_0 = (λ, ω) -> sqrt^2 + gamma_0(ω)^2 + k_x(ω)^2)
181+
a_1 = (λ, ω) -> sqrt^2 + gamma_1(ω)^2 + k_x(ω)^2)
182+
183+
Pg_mutual = zeros(Complex{Measurement{Float64}}, con, con)
184+
TOL = 1e-3
185+
186+
# Mutual potential coefficient
187+
for x 1:con
188+
for y x+1:con
189+
if x != y
190+
h1 = h[x]
191+
h2 = h[y]
192+
if abs(h2 - h1) < TOL
193+
h2 += TOL
194+
end
195+
196+
if h1 < 0 && h2 < 0
197+
yy =
198+
(a0, a1, gamma0, gamma1, hi, hj, λ, mu0, mu_g, ω, y) ->
199+
(
200+
1.0 / gamma1^2 *
201+
mu_g *
202+
ω *
203+
exp(-a1 * abs(hi - hj)) *
204+
cos* y) *
205+
0.5im
206+
) / (a1 * pi) -
207+
(
208+
1.0 / gamma1^2 *
209+
mu_g *
210+
ω *
211+
exp(a1 * (hi + hj)) *
212+
cos* y) *
213+
(a0 * mu_g + a1 * mu0 * sign(hi)) *
214+
0.5im
215+
) / (a1 * pi * (a0 * mu_g + a1 * mu0)) +
216+
(
217+
a1 * 1.0 / gamma1^2 *
218+
mu0 *
219+
mu_g^2 *
220+
ω *
221+
exp(a1 * (hi + hj)) *
222+
cos* y) *
223+
(sign(hi) - 1.0) *
224+
(gamma0^2 - gamma1^2) *
225+
0.5im
226+
) / (
227+
pi *
228+
(a0 * gamma1^2 * mu0 + a1 * gamma0^2 * mu_g) *
229+
(a0 * mu_g + a1 * mu0)
230+
)
231+
232+
yfun =
233+
λ -> yy(
234+
a_0(λ, w),
235+
a_1(λ, w),
236+
gamma_0(w),
237+
gamma_1(w),
238+
h1,
239+
h2,
240+
λ,
241+
mu0,
242+
mu_g,
243+
w,
244+
d[x, y],
245+
)
246+
Qm, _ = quadgk(yfun, 0, Inf, rtol=1e-3)
247+
Pg_mutual[x, y] = (im * w * Qm)
248+
Pg_mutual[y, x] = Pg_mutual[x, y]
249+
end
250+
end
251+
end
252+
end
253+
254+
return Pg_mutual
255+
end
256+
257+
end # module EarthAdmittance

0 commit comments

Comments
 (0)