11using LinearAlgebra
22
3+ # static types for interpolations
4+ const I1 = Interpolations. FilledExtrapolation{Float64, 1 , Interpolations. GriddedInterpolation{Float64, 1 , Vector{Float64}, Interpolations. Gridded{Interpolations. Linear{Interpolations. Throw{Interpolations. OnGrid}}}, Tuple{Vector{Float64}}}, Interpolations. Gridded{Interpolations. Linear{Interpolations. Throw{Interpolations. OnGrid}}}, Float64}
5+ const I2 = Interpolations. FilledExtrapolation{Float64, 2 , Interpolations. GriddedInterpolation{Float64, 2 , Matrix{Float64}, Interpolations. Gridded{Interpolations. Linear{Interpolations. Throw{Interpolations. OnGrid}}}, Tuple{Vector{Float64}, Vector{Float64}}}, Interpolations. Gridded{Interpolations. Linear{Interpolations. Throw{Interpolations. OnGrid}}}, Float64}
6+
37"""
48 Panel
59
@@ -36,9 +40,9 @@ mutable struct Panel
3640 cl_coefficients:: Vector{Float64}
3741 cd_coefficients:: Vector{Float64}
3842 cm_coefficients:: Vector{Float64}
39- cl_interp:: Function
40- cd_interp:: Function
41- cm_interp:: Function
43+ cl_interp:: Union{Nothing, I1, I2}
44+ cd_interp:: Union{Nothing, I1, I2}
45+ cm_interp:: Union{Nothing, I1, I2}
4246 aero_center:: MVec3
4347 control_point:: MVec3
4448 bound_point_1:: MVec3
@@ -82,45 +86,65 @@ mutable struct Panel
8286
8387 # Initialize aerodynamic properties
8488 cl_coeffs, cd_coeffs, cm_coeffs = zeros (3 ), zeros (3 ), zeros (3 )
85- cl_interp, cd_interp, cm_interp = (α:: Float64 )-> 0.0 , (α:: Float64 )-> 0.0 , (α:: Float64 )-> 0.0
8689
90+ # Calculate width
91+ width = norm (bound_point_2 - bound_point_1)
92+
93+ # Initialize filaments
94+ filaments = [
95+ BoundFilament (bound_point_2, bound_point_1),
96+ BoundFilament (bound_point_1, TE_point_1),
97+ BoundFilament (TE_point_2, bound_point_2)
98+ ]
99+
100+ cl_interp, cd_interp, cm_interp = nothing , nothing , nothing
101+
87102 if aero_model === :lei_airfoil_breukels
88103 cl_coeffs, cd_coeffs, cm_coeffs = compute_lei_coefficients (section_1, section_2)
104+
89105 elseif aero_model === :polar_data
90106 aero_1 = section_1. aero_input[2 ]
91107 aero_2 = section_2. aero_input[2 ]
92- if size (aero_1) != size (aero_2)
108+ if ! all ( size . (aero_1) .== size . (aero_2) )
93109 throw (ArgumentError (" Polar data must have same shape" ))
94110 end
95- polar_data = (aero_1 + aero_2) / 2
96- cl_interp_ = linear_interpolation (polar_data[:,1 ], polar_data[:,2 ]; extrapolation_bc= NaN )
97- cd_interp_ = linear_interpolation (polar_data[:,1 ], polar_data[:,3 ]; extrapolation_bc= NaN )
98- cm_interp_ = linear_interpolation (polar_data[:,1 ], polar_data[:,4 ]; extrapolation_bc= NaN )
99- cl_interp = (α:: Float64 ) -> cl_interp_ (α)
100- cd_interp = (α:: Float64 ) -> cd_interp_ (α)
101- cm_interp = (α:: Float64 ) -> cm_interp_ (α)
102- elseif aero_model === :interpolations
103- cl_left, cd_left, cm_left = section_1. aero_input[2 ]
104- cl_right, cd_right, cm_right = section_2. aero_input[2 ]
105- cl_interp = cl_left === cl_right ? (α:: Float64 ) -> cl_left (α, 0.0 ) :
106- (α:: Float64 ) -> 0.5 cl_left (α, 0.0 ) + 0.5 cl_right (α, 0.0 ) # TODO : add trailing edge deflection
107- cd_interp = cd_left === cd_right ? (α:: Float64 ) -> cd_left (α, 0.0 ) :
108- (α:: Float64 ) -> 0.5 cd_left (α, 0.0 ) + 0.5 cd_right (α, 0.0 )
109- cm_interp = cm_left === cm_right ? (α:: Float64 ) -> cm_left (α, 0.0 ) :
110- (α:: Float64 ) -> 0.5 cm_left (α, 0.0 ) + 0.5 cm_right (α, 0.0 )
111+
112+ if length (aero_1) == 4
113+ ! all (isapprox .(aero_1[1 ], aero_2[1 ])) && @error " Make sure you use the same alpha range for all your interpolations."
114+
115+ polar_data = (
116+ Vector {Float64} ((aero_1[2 ] + aero_2[2 ]) / 2 ),
117+ Vector {Float64} ((aero_1[3 ] + aero_2[3 ]) / 2 ),
118+ Vector {Float64} ((aero_1[4 ] + aero_2[4 ]) / 2 )
119+ )
120+ alphas = Vector {Float64} (aero_1[1 ])
121+
122+ cl_interp = linear_interpolation (alphas, polar_data[1 ]; extrapolation_bc= NaN )
123+ cd_interp = linear_interpolation (alphas, polar_data[2 ]; extrapolation_bc= NaN )
124+ cm_interp = linear_interpolation (alphas, polar_data[3 ]; extrapolation_bc= NaN )
125+
126+ elseif length (aero_1) == 5
127+ ! all (isapprox .(aero_1[1 ], aero_2[1 ])) && @error " Make sure you use the same alpha range for all your interpolations."
128+ ! all (isapprox .(aero_1[2 ], aero_2[2 ])) && @error " Make sure you use the same beta range for all your interpolations."
129+
130+ polar_data = (
131+ Matrix {Float64} ((aero_1[3 ] + aero_2[3 ]) / 2 ),
132+ Matrix {Float64} ((aero_1[4 ] + aero_2[4 ]) / 2 ),
133+ Matrix {Float64} ((aero_1[5 ] + aero_2[5 ]) / 2 )
134+ )
135+ alphas = Vector {Float64} (aero_1[1 ])
136+ betas = Vector {Float64} (aero_1[2 ])
137+
138+ cl_interp = linear_interpolation ((alphas, betas), polar_data[1 ]; extrapolation_bc= NaN )
139+ cd_interp = linear_interpolation ((alphas, betas), polar_data[2 ]; extrapolation_bc= NaN )
140+ cm_interp = linear_interpolation ((alphas, betas), polar_data[3 ]; extrapolation_bc= NaN )
141+ else
142+ throw (ArgumentError (" Polar data in wrong format: $aero_1 " ))
143+ end
144+
111145 elseif ! (aero_model === :inviscid )
112146 throw (ArgumentError (" Unsupported aero model: $aero_model " ))
113147 end
114-
115- # Calculate width
116- width = norm (bound_point_2 - bound_point_1)
117-
118- # Initialize filaments
119- filaments = [
120- BoundFilament (bound_point_2, bound_point_1),
121- BoundFilament (bound_point_1, TE_point_1),
122- BoundFilament (TE_point_2, bound_point_2)
123- ]
124148
125149 new (
126150 TE_point_1, LE_point_1, TE_point_2, LE_point_2,
@@ -262,8 +286,14 @@ function calculate_cl(panel::Panel, alpha::Float64)::Float64
262286 end
263287 elseif panel. aero_model === :inviscid
264288 cl = 2 π * alpha
265- elseif panel. aero_model === :polar_data || panel. aero_model === :interpolations
266- cl = panel. cl_interp (alpha):: Float64
289+ elseif panel. aero_model === :polar_data
290+ if isa (panel. cl_interp, I1)
291+ cl = panel. cl_interp (alpha):: Float64
292+ elseif isa (panel. cl_interp, I2)
293+ cl = panel. cl_interp (alpha, 0.0 ):: Float64
294+ else
295+ throw (ArgumentError (" cl_interp is $(panel. cl_interp) " ))
296+ end
267297 else
268298 throw (ArgumentError (" Unsupported aero model: $(panel. aero_model) " ))
269299 end
@@ -284,9 +314,14 @@ function calculate_cd_cm(panel::Panel, alpha::Float64)
284314 if abs (alpha) > (π/ 9 ) # Outside ±20 degrees
285315 cd = 2 * sin (alpha)^ 3
286316 end
287- elseif panel. aero_model === :polar_data || panel. aero_model === :interpolations
288- cd = panel. cd_interp (alpha):: Float64
289- cm = panel. cm_interp (alpha):: Float64
317+ elseif panel. aero_model === :polar_data
318+ if isa (panel. cd_interp, I1)
319+ cd = panel. cd_interp (alpha):: Float64
320+ cm = panel. cm_interp (alpha):: Float64
321+ elseif isa (panel. cd_interp, I2)
322+ cd = panel. cd_interp (alpha, 0.0 ):: Float64
323+ cm = panel. cm_interp (alpha, 0.0 ):: Float64
324+ end
290325 elseif ! (panel. aero_model === :inviscid )
291326 throw (ArgumentError (" Unsupported aero model: $(panel. aero_model) " ))
292327 end
0 commit comments