1- using Distributed, Timers, Serialization, SharedArrays
2- using Xfoil
3- using Pkg
4- using ControlPlots
1+ # using Distributed, Timers, Serialization, SharedArrays
2+ # using Xfoil
3+ # using Pkg
4+ # using ControlPlots
55
6- function distributed_create_polars (foil_file, v_wind, middle_length, tip_length )
6+ function distributed_create_polars (foil_path, polar_path, v_wind, area, width, x_turn )
77 procs = addprocs ()
88
99 function normalize! (x, y)
@@ -20,7 +20,6 @@ function distributed_create_polars(foil_file, v_wind, middle_length, tip_length)
2020
2121 function turn_trailing_edge! (angle, x, y, lower_turn, upper_turn)
2222 theta = deg2rad (angle)
23- x_turn = 0.75
2423 turn_distance = upper_turn - lower_turn
2524 smooth_idx = []
2625 rm_idx = []
@@ -57,60 +56,26 @@ function distributed_create_polars(foil_file, v_wind, middle_length, tip_length)
5756 nothing
5857 end
5958
60- function calculate_constants (d_trailing_edge_angle_, x_, y_, cp, lower, upper)
61- d_trailing_edge_angle = deg2rad (d_trailing_edge_angle_)
62- x = deepcopy (x_)
63- y = deepcopy (y_)
64- c_te = 0.0
65- if d_trailing_edge_angle > 0
66- x_ref, y_ref = 0.75 , upper
67- else
68- x_ref, y_ref = 0.75 , lower
69- end
70-
71- # straighten out the trailing_edge in order to find the trailing edge torque constant
72- for i in eachindex (x)
73- x_rel = x[i] - x_ref
74- y_rel = y[i] - y_ref
75- x[i] = x_ref + x_rel * cos (- d_trailing_edge_angle) + y_rel * sin (- d_trailing_edge_angle)
76- y[i] = y_ref - x_rel * sin (- d_trailing_edge_angle) + y_rel * cos (- d_trailing_edge_angle)
77- end
78-
79- x2 = []
80- y2 = []
81- for i in 1 : (length (x)- 1 )
82- if x[i] > x_ref && lower < y[i] < upper
83- push! (x2, x[i])
84- push! (y2, y[i])
85- dx = x[i+ 1 ] - x[i]
86- cp_avg = (cp[i] + cp[i+ 1 ]) / 2
87- c_te -= dx * cp_avg * (x[i] - x_ref) # clockwise torque around (x_ref, y_ref)
88- end
89- end
90- return c_te
91- end
92-
93- function solve_alpha! (cls, cds, c_tes, alphas, alpha_idxs, d_trailing_edge_angle, re, x_, y_, lower, upper, kite_speed, speed_of_sound)
59+ function solve_alpha! (cls, cds, cms, alphas, alpha_idxs, d_trailing_edge_angle, re, x_, y_, lower, upper, kite_speed, speed_of_sound)
9460 x = deepcopy (x_)
9561 y = deepcopy (y_)
9662 turn_trailing_edge! (d_trailing_edge_angle, x, y, lower, upper)
9763 Xfoil. set_coordinates (x, y)
9864 x, y = Xfoil. pane (npan= 140 )
99- @show d_trailing_edge_angle
65+ @info d_trailing_edge_angle
10066 reinit = true
10167 for (alpha, alpha_idx) in zip (alphas, alpha_idxs)
10268 converged = false
10369 cl = 0.0
10470 cd = 0.0
10571 # Solve for the given angle of attack
106- cl, cd, _, cm, converged = Xfoil. solve_alpha (alpha, re; iter= 50 , reinit= reinit, mach= kite_speed/ speed_of_sound, xtrip= (0.05 , 0.05 )) # TODO : use 5% point
72+ cl, cd, _, cm, converged = Xfoil. solve_alpha (alpha, re; iter= 50 , reinit= reinit, mach= kite_speed/ speed_of_sound, xtrip= (0.05 , 0.05 ))
10773 reinit = false
10874 if converged
10975 _, cp = Xfoil. cpdump ()
110- c_te = calculate_constants (d_trailing_edge_angle, x, y, cp, lower, upper)
11176 cls[alpha_idx] = cl
11277 cds[alpha_idx] = cd
113- c_tes [alpha_idx] = c_te
78+ cms [alpha_idx] = cm
11479 end
11580 end
11681 return nothing
@@ -119,16 +84,16 @@ function distributed_create_polars(foil_file, v_wind, middle_length, tip_length)
11984 function run_solve_alpha (alphas, d_trailing_edge_angle, re, x_, y_, lower, upper, kite_speed, speed_of_sound)
12085 cls = Float64[NaN for _ in alphas]
12186 cds = Float64[NaN for _ in alphas]
122- c_tes = Float64[NaN for _ in alphas]
87+ cms = Float64[NaN for _ in alphas]
12388 neg_idxs = sort (findall (alphas .< 0.0 ), rev= true )
12489 neg_alphas = alphas[neg_idxs]
12590 pos_idxs = sort (findall (alphas .>= 0.0 ))
12691 pos_alphas = alphas[pos_idxs]
127- solve_alpha! (cls, cds, c_tes , neg_alphas, neg_idxs, d_trailing_edge_angle,
92+ solve_alpha! (cls, cds, cms , neg_alphas, neg_idxs, d_trailing_edge_angle,
12893 re, x_, y_, lower, upper, kite_speed, speed_of_sound)
129- solve_alpha! (cls, cds, c_tes , pos_alphas, pos_idxs, d_trailing_edge_angle,
94+ solve_alpha! (cls, cds, cms , pos_alphas, pos_idxs, d_trailing_edge_angle,
13095 re, x_, y_, lower, upper, kite_speed, speed_of_sound)
131- return cls, cds, c_tes
96+ return cls, cds, cms
13297 end
13398 end
13499
@@ -139,13 +104,13 @@ function distributed_create_polars(foil_file, v_wind, middle_length, tip_length)
139104 min_upper_distance = Inf
140105 for (xi, yi) in zip (x, y)
141106 if yi < 0
142- lower_distance = abs (xi - 0.75 )
107+ lower_distance = abs (xi - x_turn )
143108 if lower_distance < min_lower_distance
144109 min_lower_distance = lower_distance
145110 lower_trailing_edge = yi
146111 end
147112 else
148- upper_distance = abs (xi - 0.75 )
113+ upper_distance = abs (xi - x_turn )
149114 if upper_distance < min_upper_distance
150115 min_upper_distance = upper_distance
151116 upper_trailing_edge = yi
@@ -163,26 +128,59 @@ function distributed_create_polars(foil_file, v_wind, middle_length, tip_length)
163128 return matrix[rows_to_keep, cols_to_keep]
164129 end
165130
166- println (" Creating polars" )
167- if ! endswith (foil_file, " .dat" )
168- foil_file *= " .dat"
131+ function replace_nan! (matrix)
132+ rows, cols = size (matrix)
133+ distance = max (rows, cols)
134+ for i in 1 : rows
135+ for j in 1 : cols
136+ if isnan (matrix[i, j])
137+ neighbors = []
138+ for d in 1 : distance
139+ found = false
140+ if i- d >= 1 && ! isnan (matrix[i- d, j]);
141+ push! (neighbors, matrix[i- d, j])
142+ found = true
143+ end
144+ if i+ d <= rows && ! isnan (matrix[i+ d, j])
145+ push! (neighbors, matrix[i+ d, j])
146+ found = true
147+ end
148+ if j- d >= 1 && ! isnan (matrix[i, j- d])
149+ push! (neighbors, matrix[i, j- d])
150+ found = true
151+ end
152+ if j+ d <= cols && ! isnan (matrix[i, j+ d])
153+ push! (neighbors, matrix[i, j+ d])
154+ found = true
155+ end
156+ if found; break ; end
157+ end
158+ if ! isempty (neighbors)
159+ matrix[i, j] = sum (neighbors) / length (neighbors)
160+ end
161+ end
162+ end
163+ end
164+ return nothing
169165 end
170- polar_file = foil_file[1 : end - 4 ] * " _polar.bin"
171166
172- # alphas = -90:1.0:90
173- alphas = - 1.0 : 1.0 : 1.0
174- # d_trailing_edge_angles = -90:1.0:90
175- d_trailing_edge_angles = - 1.0 : 1.0 : 1.0
167+ @info " Creating polars"
168+
169+ alphas = - 90 : 1.0 : 90
170+ # alphas = -1.0:1.0:1.0
171+ d_trailing_edge_angles = - 90 : 1.0 : 90
172+ # d_trailing_edge_angles = -1.0:1.0:1.0
176173 cl_matrix = SharedArray {Float64} ((length (alphas), length (d_trailing_edge_angles)), init = (a) -> fill! (a, NaN ))
177174 cd_matrix = SharedArray {Float64} ((length (alphas), length (d_trailing_edge_angles)), init = (a) -> fill! (a, NaN ))
178- c_te_matrix = SharedArray {Float64} ((length (alphas), length (d_trailing_edge_angles)), init = (a) -> fill! (a, NaN ))
175+ cm_matrix = SharedArray {Float64} ((length (alphas), length (d_trailing_edge_angles)), init = (a) -> fill! (a, NaN ))
179176
180177 kite_speed = v_wind
181178 speed_of_sound = 343
182- reynolds_number = kite_speed * (middle_length + tip_length)/ 2 / 1.460e-5
179+ chord_length = area / width
180+ reynolds_number = kite_speed * chord_length / 1.460e-5 # wikipedia
183181
184182 # Read airfoil coordinates from a file.
185- x, y = open (foil_file , " r" ) do f
183+ x, y = open (foil_path , " r" ) do f
186184 x = Float64[]
187185 y = Float64[]
188186 for line in eachline (f)
@@ -203,24 +201,37 @@ function distributed_create_polars(foil_file, v_wind, middle_length, tip_length)
203201
204202 try
205203 @sync @distributed for j in eachindex (d_trailing_edge_angles)
206- cl_matrix[:, j], cd_matrix[:, j], c_te_matrix [:, j] = run_solve_alpha (alphas, d_trailing_edge_angles[j],
204+ cl_matrix[:, j], cd_matrix[:, j], cm_matrix [:, j] = run_solve_alpha (alphas, d_trailing_edge_angles[j],
207205 reynolds_number, x, y, lower, upper, kite_speed, speed_of_sound)
208206 end
209207 catch e
210- println (e)
208+ rmprocs (procs)
209+ throw (e)
211210 finally
212- println ( " Removing processes" )
211+ @info " Removing processes"
213212 rmprocs (procs)
214213 end
215214
216- println (" cl_matrix" )
217- [println (cl_matrix[i, :]) for i in eachindex (alphas)]
215+ @info " cl_matrix" begin
216+ display (cl_matrix)
217+ end
218+
219+ replace_nan! (cl_matrix)
220+ replace_nan! (cd_matrix)
221+ replace_nan! (cm_matrix)
222+
223+ cl_interp_ = extrapolate (scale (interpolate (cl_matrix, BSpline (Linear ())), alphas, d_trailing_edge_angles), NaN )
224+ cd_interp_ = extrapolate (scale (interpolate (cd_matrix, BSpline (Linear ())), alphas, d_trailing_edge_angles), NaN )
225+ cm_interp_ = extrapolate (scale (interpolate (cm_matrix, BSpline (Linear ())), alphas, d_trailing_edge_angles), NaN )
218226
219- println (" Relative trailing_edge height: " , upper - lower)
220- println (" Reynolds number for flying speed of $kite_speed is $reynolds_number " )
227+ cl_interp = (α, β) -> cl_interp_ (α, β)
228+ cd_interp = (α, β) -> cd_interp_ (α, β)
229+ cm_interp = (α, β) -> cm_interp_ (α, β)
221230
222- serialize (polar_file, (alphas, d_trailing_edge_angles, Matrix (cl_matrix), Matrix (cd_matrix), Matrix (c_te_matrix)))
231+ @info " Relative trailing_edge height: $upper - $lower "
232+ @info " Reynolds number for flying speed of $kite_speed is $reynolds_number "
233+
234+ serialize (polar_path, (cl_interp, cd_interp, cm_interp))
223235 toc ()
236+ return (cl_interp, cd_interp, cm_interp)
224237end
225-
226- distributed_create_polars (" data/centre_line_profile_with_billow" , 9.81 , 2.0 , 1.0 )
0 commit comments