11using LinearAlgebra
22
3+ const Interp1 = 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}
4+ const Interp2 = Interpolations. FilledExtrapolation{Float64, 2 , Interpolations. ScaledInterpolation{Float64, 2 , Interpolations. BSplineInterpolation{Float64, 2 , Interpolations. OffsetArrays. OffsetMatrix{Float64, Matrix{Float64}}, Interpolations. BSpline{Interpolations. Linear{Interpolations. Throw{Interpolations. OnGrid}}}, Tuple{Base. Slice{UnitRange{Int64}}, Base. Slice{UnitRange{Int64}}}}, Interpolations. BSpline{Interpolations. Linear{Interpolations. Throw{Interpolations. OnGrid}}}, Tuple{StepRangeLen{Float64, Base. TwicePrecision{Float64}, Base. TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base. TwicePrecision{Float64}, Base. TwicePrecision{Float64}, Int64}}}, Interpolations. BSpline{Interpolations. Linear{Interpolations. Throw{Interpolations. OnGrid}}}, Float64}
5+
36"""
47 Panel
58
@@ -36,9 +39,9 @@ mutable struct Panel
3639 cl_coefficients:: Vector{Float64}
3740 cd_coefficients:: Vector{Float64}
3841 cm_coefficients:: Vector{Float64}
39- cl_interp:: Function
40- cd_interp:: Function
41- cm_interp:: Function
42+ cl_interp:: Union{Nothing, Interp1, Interp2}
43+ cd_interp:: Union{Nothing, Interp1, Interp2}
44+ cm_interp:: Union{Nothing, Interp1, Interp2}
4245 aerodynamic_center:: MVec3
4346 control_point:: MVec3
4447 bound_point_1:: MVec3
@@ -82,45 +85,58 @@ mutable struct Panel
8285
8386 # Initialize aerodynamic properties
8487 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
8688
89+ # Calculate width
90+ width = norm (bound_point_2 - bound_point_1)
91+
92+ # Initialize filaments
93+ filaments = [
94+ BoundFilament (bound_point_2, bound_point_1),
95+ BoundFilament (bound_point_1, TE_point_1),
96+ BoundFilament (TE_point_2, bound_point_2)
97+ ]
98+
8799 if aero_model === :lei_airfoil_breukels
88100 cl_coeffs, cd_coeffs, cm_coeffs = compute_lei_coefficients (section_1, section_2)
101+
89102 elseif aero_model === :polar_data
90103 aero_1 = section_1. aero_input[2 ]
91104 aero_2 = section_2. aero_input[2 ]
92- if size (aero_1) != size (aero_2)
105+ if ! all ( size . (aero_1) .== size . (aero_2) )
93106 throw (ArgumentError (" Polar data must have same shape" ))
94107 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 )
108+
109+ if length (aero_1) == 4
110+ ! all (isapprox .(aero_1[1 ], aero_2[1 ])) && @error " Make sure you use the same alpha range for all your interpolations."
111+ polar_data = (
112+ (aero_1[2 ] + aero_2[2 ]) / 2 ,
113+ (aero_1[3 ] + aero_2[3 ]) / 2 ,
114+ (aero_1[4 ] + aero_2[4 ]) / 2
115+ )
116+ cl_interp = linear_interpolation (aero_1[1 ], polar_data[1 ]; extrapolation_bc= NaN )
117+ cd_interp = linear_interpolation (aero_1[1 ], polar_data[2 ]; extrapolation_bc= NaN )
118+ cm_interp = linear_interpolation (aero_1[1 ], polar_data[3 ]; extrapolation_bc= NaN )
119+
120+ elseif length (aero_1) == 5
121+ ! all (isapprox .(aero_1[1 ], aero_2[1 ])) && @error " Make sure you use the same alpha range for all your interpolations."
122+ ! all (isapprox .(aero_1[2 ], aero_2[2 ])) && @error " Make sure you use the same beta range for all your interpolations."
123+
124+ polar_data = (
125+ (aero_1[3 ] + aero_2[3 ]) / 2 ,
126+ (aero_1[4 ] + aero_2[4 ]) / 2 ,
127+ (aero_1[5 ] + aero_2[5 ]) / 2
128+ )
129+ cl_interp = linear_interpolation ((aero_1[1 ], aero_1[2 ]), polar_data[1 ]; extrapolation_bc= NaN )
130+ cd_interp = linear_interpolation ((aero_1[1 ], aero_1[2 ]), polar_data[2 ]; extrapolation_bc= NaN )
131+ cm_interp = linear_interpolation ((aero_1[1 ], aero_1[2 ]), polar_data[3 ]; extrapolation_bc= NaN )
132+ # cl_interp = extrapolate(scale(interpolate(cl_matrix, BSpline(Linear())), alphas, d_trailing_edge_angles), NaN)
133+ # cd_interp = extrapolate(scale(interpolate(cl_matrix, BSpline(Linear())), alphas, d_trailing_edge_angles), NaN)
134+ # cm_interp = extrapolate(scale(interpolate(cl_matrix, BSpline(Linear())), alphas, d_trailing_edge_angles), NaN)
135+ end
136+
111137 elseif ! (aero_model === :inviscid )
112138 throw (ArgumentError (" Unsupported aero model: $aero_model " ))
113139 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- ]
124140
125141 new (
126142 TE_point_1, LE_point_1, TE_point_2, LE_point_2,
@@ -262,8 +278,12 @@ function calculate_cl(panel::Panel, alpha::Float64)::Float64
262278 end
263279 elseif panel. aero_model === :inviscid
264280 cl = 2 π * alpha
265- elseif panel. aero_model === :polar_data || panel. aero_model === :interpolations
266- cl = panel. cl_interp (alpha):: Float64
281+ elseif panel. aero_model === :polar_data
282+ if isa (panel. cl_interp, Interp1)
283+ cl = panel. cl_interp (alpha):: Float64
284+ elseif isa (panel. cl_interp, Interp2)
285+ cl = panel. cl_interp (alpha, 0.0 ):: Float64
286+ end
267287 else
268288 throw (ArgumentError (" Unsupported aero model: $(panel. aero_model) " ))
269289 end
@@ -284,9 +304,14 @@ function calculate_cd_cm(panel::Panel, alpha::Float64)
284304 if abs (alpha) > (π/ 9 ) # Outside ±20 degrees
285305 cd = 2 * sin (alpha)^ 3
286306 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
307+ elseif panel. aero_model === :polar_data
308+ if isa (panel. cd_interp, Interp1)
309+ cd = panel. cd_interp (alpha):: Float64
310+ cm = panel. cm_interp (alpha):: Float64
311+ elseif isa (panel. cd_interp, Interp2)
312+ cd = panel. cd_interp (alpha, 0.0 ):: Float64
313+ cm = panel. cm_interp (alpha, 0.0 ):: Float64
314+ end
290315 elseif ! (panel. aero_model === :inviscid )
291316 throw (ArgumentError (" Unsupported aero model: $(panel. aero_model) " ))
292317 end
0 commit comments