def get_max_cl(Re, r): """ Analyze airfoil at a fixed Re, changing aoa from 10 to 15 by 0.1 and returns cl, cd, aoa that makes maximum cl """ xf = XFoil() if r <= 0.175: xf.airfoil = naca6409 else: xf.airfoil = naca2412 xf.Re = Re xf.Re = Re xf.max_iter = 200 xf.n_crit = 9.00 xf.xtr = [1.00, 1.00] xf.M = 0 a_seq, cl_seq, cd_seq, cm_seq, cp_seq = xf.aseq(10, 15, 0.1) # ignore nan by making it 0 cl_seq = np.nan_to_num(cl_seq) # find the maximum cl cl_maxi = np.max(cl_seq) # index of the maximum cl idx = np.argmax(cl_seq) return round(cl_maxi, 2), round(a_seq[idx], 2), round(cd_seq[idx], 2)
def hello(): x = request.args.get('x') y = request.args.get('y') Re = float(request.args.get('Re')) M = float(request.args.get('M')) Alpha = float(request.args.get('Alpha')) x = x.split() y = y.split() ctrlX = [float(ele) for ele in x] ctrlY = [float(ele) for ele in y] bezierX, bezierY = airfoil(ctrlX, ctrlY, 16) xf = XFoil() xf.Re = Re xf.M = 0 xf.max_iter = 100 xf.airfoil = Airfoil(np.array(bezierX), np.array(bezierY)) aero = xf.a(Alpha) xcp, cp = xf.get_cp_distribution() y = savgol_filter(cp, 5, 2) for i in range(30): y = savgol_filter(y, 5, 2) LD = aero[0] / aero[1] vol = PolyArea(bezierX, bezierY) print(len(xcp)) return jsonify(result=str(round(aero[0], 3)) + " " + str(round(aero[1], 3)) + " " + str(round(aero[2], 3)) + " " + str(round(LD, 2)) + " " + str(round(vol, 3)), xcp=xcp.tolist(), cp=y.tolist())
def get_cl(coord, xf=None, angle=5): if xf is None: xf = XFoil() xf.print = False xf.Re = 3e6 xf.max_iter = 100 datax, datay = coord.reshape(2, -1) xf.airfoil = Airfoil(x=datax, y=datay) c = xf.a(angle) cl= c[0] return cl
def evaluate(self, individual): ratios = self.decoder(individual, self.code_division) datlist_list = [fc.read_datfile(file) for file in self.datfiles] datlist_shaped_list = [ fc.shape_dat(datlist) for datlist in datlist_list ] newdat = fc.interpolate_dat(datlist_shaped_list, ratios) foil_para = fc.get_foil_para(newdat) datx = np.array([ax[0] for ax in newdat]) daty = np.array([ax[1] for ax in newdat]) newfoil = Airfoil(x=datx, y=daty) mt, mta, mc, mca, s = foil_para penalty = 0 for g, p in zip(self.gs, self.penalties): if (not g): penalty += p xf = XFoil() xf.airfoil = newfoil xf.Re = self.re xf.max_iter = 60 print(self.assigns, self.datfiles) scope = locals() exec(self.assigns, scope) #---------------------------------- #目的値 #---------------------------------- try: obj1, obj2, obj3 = [eval(o) for o in self.Os] except IndexError as e: obj1, obj2, obj3 = [1.0] * self.NOBJ traceback.print_exc() except SyntaxError as e: raise ValueError("invalid objection") if (np.isnan(obj1) or obj1 > 1): obj1 = 1 if (np.isnan(obj2) or obj2 > 1): obj2 = 1 if (np.isnan(obj3) or obj3 > 1): obj3 = 1 obj1 += penalty obj2 += penalty obj3 += penalty return [obj1, obj2, obj3]
def getCoefficients(naca, reynolds=1e6, iterations=20, angle=10, angle_step=.5): xf = XFoil() xf.naca(f"{naca:04d}") xf.Re = reynolds xf.max_iter = 20 a, cl, cd, cm, cp = xf.aseq(0, angle, .5) ratio = cl / cd max_idx = np.nanargmax(ratio) return (ratio[max_idx], a[max_idx]), a, cl, cd, max_idx
def cl_visc_analysis(airfoil, cl_i, cl_f, cl_step, re, mach, max_iter, id): """Viscous analysis over range of lift coefficients.""" # Initializes airfoil and assigns NACA xf = XFoil() xf.naca(airfoil) xf.max_iter = max_iter xf.Re = re xf.M = mach # Collects values a, cl, cd, cm, cp = xf.cseq(cl_i, cl_f, cl_step) x, cp_0 = xf.get_cp_distribution() # Plots all the data plot(a, cl, cd, cm, cp, x, cp_0, id)
def alpha_visc_analysis(airfoil, alpha_i, alpha_f, alpha_step, re, mach, max_iter, id): """Viscous analysis over range of angle of attacks.""" # Initializes airfoil and assigns NACA xf = XFoil() xf.naca(airfoil) xf.max_iter = max_iter xf.Re = re xf.M = mach # Collects values a, cl, cd, cm, cp = xf.aseq(alpha_i, alpha_f, alpha_step) x, cp_0 = xf.get_cp_distribution() # Plots all the data plot(a, cl, cd, cm, cp, x, cp_0, id)
def get_torque(angular_velocity): torque_sum_small = 0 torque_sum_large = 0 w = angular_velocity for key, value in dfdict.items(): value["blade_velocity"] = value['r_position'] * w value["relative_velocity"] = round( math.sqrt(value["blade_velocity"]**2 + value["wind_velocity"]**2), 2) value["arctan"] = math.degrees( math.atan2(value["wind_velocity"], value["blade_velocity"])) aoa = round(value["arctan"] - value["pitch_angle"], 2) value["angle_of_attack"] = aoa re_n = round( value["relative_velocity"] * value["chord_length"] / 0.00001511, 3) value["Reynolds_number"] = re_n xf = XFoil() if key < 13: xf.airfoil = naca6409 else: xf.airfoil = naca2412 xf.Re = re_n xf.max_iter = 100 xf.n_crit = 9.00 xf.xtr = [1.00, 1.00] xf.M = 0 value["Cl"], value["Cd"], value["Cm"], value["Cp"] = xf.a(aoa) force_reference = 0.5 * density * value["relative_velocity"]**2 if math.isnan(value["Cl"]): value["torque"] = 0 else: lift = value["Cl"] * force_reference * 0.0125 * value[ 'chord_length'] drag = value["Cd"] * force_reference * 0.0125 * value[ 'chord_length'] value["torque"] = value["r_position"] * ( lift * math.sin(math.radians(value["pitch_angle"])) - drag * math.cos(math.radians(value["pitch_angle"]))) if key < 13: torque_sum_small += value["torque"] else: pass if key > 0: torque_sum_large += value["torque"] else: pass df2 = pd.DataFrame.from_dict(dfdict, orient="index") df_collection.append(df2) torque_sum_avg = 0.5 * (torque_sum_small + torque_sum_large) return torque_sum_avg
def total_dict(angular_velocity): torque_sum = 0 w = angular_velocity for key, value in dfdict.items(): value["blade_velocity"] = value['r_position'] * w value["relative_velocity"] = round( math.sqrt(value["blade_velocity"]**2 + value["wind_velocity"]**2), 2) value["arctan"] = math.degrees( math.atan2(value["wind_velocity"], value["blade_velocity"])) aoa = round(value["arctan"] - value["pitch_angle"], 1) value["angle_of_attack"] = aoa re_n = round(value["relative_velocity"] * value["chord_length"] / 0.00001511) value["Reynolds_number"] = re_n xf = XFoil() if key < 13: xf.airfoil = naca6409 else: xf.airfoil = naca2412 xf.Re = round(re_n / 100) * 100 xf.max_iter = 200 xf.n_crit = 9.00 xf.xtr = [1.00, 1.00] xf.M = 0 c_l, c_d, c_m, c_p = xf.a(aoa) force_reference = 0.5 * density * value["relative_velocity"]**2 if math.isnan(c_l): pass else: value["Cl"] = c_l value["Cd"] = c_d value["Cm"] = c_m value["Cp"] = c_p lift = c_l * force_reference * 0.0125 * value['chord_length'] drag = c_d * force_reference * 0.0125 * value['chord_length'] value["lift"] = lift value["drag"] = drag # value["torque"] = value["r_position"] * lift * math.sin(math.radians(value["pitch_angle"])) torque = value["r_position"] * ( lift * math.sin(math.radians(value["pitch_angle"])) - drag * math.cos(math.radians(value["pitch_angle"]))) value["torque"] = torque torque_sum += torque xf.reset_bls() # detailed_df = pd.DataFrame.from_dict(dfdict, orient="index") # print(detailed_df) print(torque_sum, angular_velocity) return dfdict, torque_sum
def evaluate(individual): global code_division #---------------------------------- #遺伝子にも続いて新翼型を生成 #---------------------------------- #遺伝子をデコード ratios = decoder(individual, code_division) #遺伝子に基づき翼型を混合して、新しい翼型を作る datlist_list = [fc.read_datfile(file) for file in datfiles] datlist_shaped_list = [fc.shape_dat(datlist) for datlist in datlist_list] newdat = fc.interpolate_dat(datlist_shaped_list,ratios) #翼型の形に関する情報を取得する #foilpara == [最大翼厚、最大翼厚位置、最大キャンバ、最大キャンバ位置、S字の強さ] foil_para = fc.get_foil_para(newdat) #新しい翼型をAerofoilオブジェクトに適用 datx = np.array([ax[0] for ax in newdat]) daty = np.array([ax[1] for ax in newdat]) newfoil = Airfoil(x = datx, y = daty) mt, mta, mc, mca, s = foil_para #---------------------------------- #翼の形に関する拘束条件 #---------------------------------- penalty = 0 print('===================') if(mc<0): print("out of the border") print("reverse_cmaber") penalty -= mc if(mt<0.08): print("out of the border") print("too_thin") penalty += 0.08-mt if(mt>0.11): print("out of the border") print("too_fat") penalty += mt-0.11 #if(foil_para[4]>0.03): # print("out of the border") # print("peacock") # print('===================') # return (1.0+(foil_para[4]-0.03),)*NOBJ if(mta<0.23): print("out of the border") print("Atama Dekkachi!") penalty += 0.23 - mta if(mta>0.3): print("out of the border") print("Oshiri Dekkachi!") penalty += mta - 0.3 #---------------------------------- #新翼型の解析 #---------------------------------- xf = XFoil() xf.airfoil = newfoil #レイノルズ数の設定 xf.Re = 1.5e5 #境界要素法計算時1ステップにおける計算回数 xf.max_iter = 60 #座標整形 xf.repanel(n_nodes = 300) xf.print = False #計算結果格納 a, cl, cd, cm, cp = xf.cseq(0.4, 1.1, 0.1) lr = [l/d for l, d in zip(cl,cd)] #---------------------------------- #目的値 #---------------------------------- try: #揚抗比の逆数を最小化 obj1 = 1/lr[1] #揚抗比のピークを滑らかに(安定性の最大化) maxlr = max(lr) maxlr_index = lr.index(maxlr) obj2 = abs(maxlr - lr[maxlr_index+1]) #下面の反りを最小化(製作再現性の最大化) obj3 = foil_para[4] except Exception as e: obj1,obj2,obj3=[1.0]*NOBJ traceback.print_exc() if (np.isnan(obj1) or obj1 > 1): obj1 = 1 if (np.isnan(obj2) or obj2 > 1): obj2 = 1 if (np.isnan(obj3) or obj3 > 1): obj3 = 1 obj1 += penalty obj2 += penalty obj3 += penalty print("individual",individual) print("evaluate",obj1,obj2,obj3) print("max_thickness",foil_para[0]) print("at",foil_para[1]) print("max_camber",foil_para[2]) print("at",foil_para[3]) print("S",foil_para[4]) print('===================') return [obj1, obj2, obj3]
if c = (a_max * 8 * pi * r * math.sin(phi) ** 2) / ((1 - a_max) * prop_blades * c_l * math.cos(phi)) re = (v_r * c) / (nu_mars) # XFOIL ####### from xfoil import XFoil xf = XFoil() # Import an airfoil from xfoil.test import XXXXX xf.airfoil = XXXXX # Setting up the analysis parameters xf.Re = re xf.max_iter = 100 xf.M = 0.7 # Obtaining the angle of attack, lift coefficient, drag coefficient and momentum coefficient of the airfoil a, cl, cd, cm = xf.aseq(0, 30, 0.5)
def evaluate(self,individual): DELTA = 1e10 #---------------------------------- #遺伝子に基づいて新翼型を生成 #---------------------------------- #遺伝子に基づきスプライン翼型を作成 x = individual[:int(len(individual)/2)] x.insert(0,1.0) x.insert(int(len(x)/2)+1,0.0) x.append(1.0) y = individual[int(len(individual)/2):] if not (all([u - d > 0 for u, d in zip(y[:int(len(y)/2)], y[int(len(y)/2):])]) or all([u - d < 0 for u, d in zip(y[:int(len(y)/2)], y[int(len(y)/2):])])): print("crossed") return [DELTA*10]*self.NOBJ y.insert(0,0.0) y.insert(int(len(y)/2)+1,0.0) y.append(0.0) newdat = fc.spline_foil(x, y, 200) shape_dat = fc.shape_dat([[a, b] for a, b in zip(newdat[0][::-1], newdat[1][::-1])]) #翼型の形に関する情報を取得する foil_para = fc.get_foil_para(shape_dat) mt, mta, mc, mca, s, crossed, bd, bt, bc, smooth, td = foil_para # mt: 最大翼厚(百分率) # mta: 最大翼厚位置(百分率) # mc: 最大キャンバー(百分率) # mca: 最大きゃんばー位置(百分率) # s: 翼型の下面における、最大y座標-最小y座標 # crossed: 翼型が交差しているならTrue,それ以外ならFalse # bd: 翼型の粗さ(大きいほど粗い) # bt: 翼厚分布の粗さ(大きいほど粗い) # bc: キャンバー分布の粗さ(大きいほど粗い) # smooth: 無視 # td: 翼厚分布 if crossed: print("crossed_a") return [DELTA*10]*self.NOBJ else: print("hi_a") #新しい翼型をAerofoilオブジェクトに適用 datx = np.array(newdat[0][::-1]) daty = np.array(newdat[1][::-1]) newfoil = Airfoil(x = datx, y = daty) #翼型の形に関する拘束条件 penalty = 0 if not all([t >= 0.0035 for t in td[10:80]]): penalty += 100 * (sum([abs(t - 0.0035)*10 for t in td[15:85] if t - 0.0035 < 0])) if not all([t <= 0.015 for t in td[:15]]): penalty += 100 * (sum([abs(t - 0.015)*10 for t in td[:15] if t > 0.015])) if mta > 0.4: penalty += 100 * (mta - 0.4) if mc < 0.0: penalty += 100 * (-mc) if datx[0] > 1.002 or datx[0] < 0.998: print("invalid foil") return [DELTA*10]*self.NOBJ #---------------------------------- #新翼型の解析 #---------------------------------- try: xf = XFoil() #レイノルズ数の設定 xf.airfoil = newfoil xf.Re = self.re xf.print = False xf.max_iter = 40 #xf.polar = "polar" + id #境界要素法計算時1ステップにおける計算回数 #xf.repanel(n_nodes = 180) #計算結果格納 #result = xf.OneAlpha() cl, cd, cm, cp = xf.a(5.0) #---------------------------------- #目的値 #---------------------------------- if cl >= 0: obj1 = 1/cl else: obj1 = self.delta obj2 = cd except Exception as e: obj1,obj2=[DELTA]*self.NOBJ traceback.print_exc() if (np.isnan(obj1)): obj1 = DELTA if (np.isnan(obj2)): obj2 = DELTA return [obj1 + penalty, obj2 + penalty]
#!/usr/bin/python3 from xfoil import XFoil import matplotlib.pyplot as plt xf = XFoil() xf.load("revclarky.dat") xf.Re = 1e5 xf.M = 0 xf.max_iter = 100 a, cl, cd, cm, cp = xf.aseq(-2, 2, 0.5) plt.plot(a, cl) plt.title("alfa vs cl") plt.show() #plt.plot(xf.airfoil.x,xf.airfoil.y) #plt.axis('equal') #plt.show()
def analyze_airfoil(x, y_u, y_l, cl, rey, mach=0, xf=None, pool=None, show_output=False): """ Analyze an airfoil at a given lift coefficient for given Reynolds and Mach numbers using XFoil. Parameters ---------- x : array_like Airfoil x-coordinates y_u, y_l : array_like Airfoil upper and lower curve y-coordinates cl : float Target lift coefficient rey, mach : float Reynolds and Mach numbers xf : XFoil, optional An instance of the XFoil class to use to perform the analysis. Will be created if not given pool : multiprocessing.ThreadPool, optional An instance of the multiprocessing.Threadpool class used to run the xfoil_worker. Will be created if not given show_output : bool, optional If True, a debug string will be printed after analyses. False by default. Returns ------- cd, cm : float or np.nan Drag and moment coefficients of the airfoil at specified conditions, or nan if XFoil did not run successfully """ # If the lower and upper curves swap, this is a bad, self-intersecting airfoil. Return 1e27 immediately. if np.any(y_l > y_u): return np.nan else: clean_xf = False if xf is None: xf = XFoil() xf.print = show_output clean_xf = True clean_pool = False if pool is None: pool = ThreadPool(processes=1) clean_pool = True xf.airfoil = Airfoil(x=np.concatenate((x[-1:0:-1], x)), y=np.concatenate((y_u[-1:0:-1], y_l))) xf.Re = rey xf.M = mach xf.max_iter = 100 xf.n_crit = 0.1 cd, cm = pool.apply(xfoil_worker, args=(xf, cl)) if clean_xf: del xf if clean_pool: del pool return cd, cm, None if clean_xf else xf
for v in zip(*rankedAerofoils_names): print(str(header).format(*v)) span = 52 rho = 0.4135 velocity = 230 g = 9.81 reynolds_div_chord = 7331382 mean_chord = 3 #https://www.grc.nasa.gov/WWW/K-12/airplane/reynolds.html massMin = 70000 massMax = 90000 massSpacing = 10000 xf = XFoil() #Reynolds number, unit chord (see XFOIL docs UNITS section) xf.Re = reynolds_div_chord * mean_chord xf.max_iter = 100 print("Reynolds Number: {0}\nMax iterations: {1}\n".format(xf.Re, xf.max_iter)) cl, massList = liftCoCalc() allAerofoils_obj = initialiseAerofoils() runAnalysis() print("\n") rankedAerofoils_obj, rankedAerofoils_names = sortResults() print("\n") displayResults()
SPAN_POINTS_PER_METRE = 10 chord_points = int((END_CHORD - START_CHORD) * CHORD_POINTS_PER_METRE) chord_increment = float((END_CHORD - START_CHORD) / chord_points) span_points = int((END_SPAN - START_SPAN) * SPAN_POINTS_PER_METRE) span_increment = float((END_SPAN - START_SPAN) / span_points) print("Max iterations: {0}\nMass: {1}Kg".format(xf.max_iter, mass)) for j in range(chord_points + 1): chord = START_CHORD + (j * chord_increment) chord = round(chord, 2) mac = START_CHORD + (j * chord_increment) * (8 / (3 * pi)) mac = round(mac, 2) for i in range(span_points + 1): span = START_SPAN + (i * span_increment) span = round(span, 2) #Reynolds number, unit chord (see XFOIL docs UNITS section) xf.Re = reynolds_div_chord * mac print("\nSpan: {0}m\tRoot Chord: {1}m\tReynolds: {2}".format( span, chord, xf.Re)) cl = liftCoCalc() Aerofoils_obj = initialiseAerofoils() runAnalysis() displayResults() saveResults()
def evaluate(self,individual): #---------------------------------- #遺伝子に基づいて新翼型を生成 #---------------------------------- #遺伝子をデコード ratios = self.decoder(individual, self.code_division) #遺伝子に基づき翼型を混合して、新しい翼型を作る datlist_list = [fc.read_datfile(file) for file in self.datfiles] datlist_shaped_list = [fc.shape_dat(datlist) for datlist in datlist_list] newdat = fc.interpolate_dat(datlist_shaped_list,ratios) #翼型の形に関する情報を取得する #foilpara == [最大翼厚、最大翼厚位置、最大キャンバ、最大キャンバ位置、S字の強さ] foil_para = fc.get_foil_para(newdat) #新しい翼型をAerofoilオブジェクトに適用 datx = np.array([ax[0] for ax in newdat]) daty = np.array([ax[1] for ax in newdat]) newfoil = Airfoil(x = datx, y = daty) mt, mta, mc, mca, s = foil_para #---------------------------------- #翼の形に関する拘束条件 #---------------------------------- """ penalty = 0 for g, p in zip(self.gs, self.penalties): if(not g): penalty += p """ penalty = 0 print('===================') if(mc<0): print("out of the border") print("reverse_cmaber") penalty -= mc if(mt<0.08): print("out of the border") print("too_thin") penalty += 0.08-mt if(mt>0.11): print("out of the border") print("too_fat") penalty += mt-0.11 #if(foil_para[4]>0.03): # print("out of the border") # print("peacock") # print('===================') # return (1.0+(foil_para[4]-0.03),)*NOBJ if(mta<0.23): print("out of the border") print("Atama Dekkachi!") penalty += 0.23 - mta if(mta>0.3): print("out of the border") print("Oshiri Dekkachi!") penalty += mta - 0.3 #---------------------------------- #新翼型の解析 #---------------------------------- xf = XFoil() xf.airfoil = newfoil #レイノルズ数の設定 xf.Re = self.re #境界要素法計算時1ステップにおける計算回数 xf.max_iter = 60 #print("hi") #print(vars) #scope = locals() #var0, var1, var2, var3, var4, var5, var6, var7 = [0 if var == None or var == '' else eval(var,scope) for var in self.vars] #計算結果格納 a, cl, cd, cm, cp = xf.cseq(0.4, 1.1, 0.1) lr = [l/d for l, d in zip(cl,cd)] #---------------------------------- #目的値 #---------------------------------- """ try: obj1,obj2,obj3 = [eval(o) for o in Os] except Exception as e: obj1,obj2,obj3=[1.0]*self.NOBJ traceback.print_exc() """ try: #揚抗比の逆数を最小化 obj1 = 1/lr[1] #揚抗比のピークを滑らかに(安定性の最大化) maxlr = max(lr) maxlr_index = lr.index(maxlr) obj2 = abs(maxlr - lr[maxlr_index+1]) #下面の反りを最小化(製作再現性の最大化) obj3 = s except Exception as e: obj1,obj2,obj3=[1.0]*self.NOBJ traceback.print_exc() if (np.isnan(obj1) or obj1 > 1): obj1 = 1 if (np.isnan(obj2) or obj2 > 1): obj2 = 1 if (np.isnan(obj3) or obj3 > 1): obj3 = 1 obj1 += penalty obj2 += penalty obj3 += penalty return [obj1, obj2, obj3]
fig, ax = plt.subplots(1, 1, figsize=(9, 8)) klist = [1] for k in range(1): print(k) x = aifoils[k]['x'].values y = aifoils[k]['y'].values ang_low = -32 ang_high = 32 ang_spacing = 2 xfc = XFoil() xfc.airfoil = Airfoil(x, y) xfc.Re = re[k] xfc.max_iter = 40 ac, clc, cdc, cmc, cpminc = xfc.aseq(ang_low, ang_high, ang_spacing) df = aifoils_cfd[k].where(aifoils_cfd[k]['alpha [deg]'] >= aoa_l) df = df.where(aifoils_cfd[k] <= aoa_h) df = df.dropna() #.values cl_panel = [] cdp_panel = [] for aoa in df['alpha [deg]']: data_xy = aifoils[k].values CL, CDP, Cp, pp = panel(data_xy[:, :], alfader=aoa) cl_panel.append(CL) cdp_panel.append(CDP)
def evaluate(self, individual): #解析が発散した際の評価値 DELTA = 1e10 #---------------------------------- #遺伝子に基づいて新翼型を生成 #---------------------------------- #遺伝子をデコード ratios = self.decoder(individual, self.code_division) #遺伝子に基づき翼型を混合して、新しい翼型を作る datlist_list = [fc.read_datfile(file) for file in self.datfiles] datlist_shaped_list = [ fc.shape_dat(datlist) for datlist in datlist_list ] newdat = fc.interpolate_dat(datlist_shaped_list, ratios) #翼型の形に関する情報を取得する mt, mta, mc, mca, s, crossed, bd, bt, bc, smooth, td = fc.get_foil_para( newdat) #新しい翼型をAerofoilオブジェクトに適用 datx = np.array([ax[0] for ax in newdat]) daty = np.array([ax[1] for ax in newdat]) newfoil = Airfoil(x=datx, y=daty) #---------------------------------- #翼の形に関する拘束条件 #---------------------------------- penalty = 0 #キャンバに関する拘束条件 if (mc < 0): penalty -= mc #最大翼厚に関する拘束条件 if (mt < 0.08): penalty += 0.08 - mt if (mt > 0.11): penalty += mt - 0.11 #最大翼厚位置に関する拘束条件 if (mta < 0.23): penalty += 0.23 - mta if (mta > 0.3): penalty += mta - 0.3 #---------------------------------- #新翼型の解析 #---------------------------------- xf = XFoil() xf.airfoil = newfoil #レイノルズ数の設定 xf.Re = self.re #境界要素法計算時1ステップにおける計算回数 xf.max_iter = 60 xf.print = False #計算結果格納 a, cl, cd, cm, cp = xf.cseq(0.4, 1.1, 0.1) #---------------------------------- #目的値 #---------------------------------- try: #揚抗比の逆数を最小化 obj1 = 1 / lr[1] #揚抗比のピークを滑らかに(安定性の最大化) maxlr = max(lr) maxlr_index = lr.index(maxlr) obj2 = abs(maxlr - lr[maxlr_index + 1]) #下面の反りを最小化(製作再現性の最大化) obj3 = s except Exception as e: obj1, obj2, obj3 = [DELTA] * self.NOBJ traceback.print_exc() if (np.isnan(obj1) or obj1 > 1): obj1 = DELTA if (np.isnan(obj2) or obj2 > 1): obj2 = DELTA if (np.isnan(obj3) or obj3 > 1): obj3 = DELTA obj1 += penalty obj2 += penalty obj3 += penalty return [obj1, obj2, obj3]
def feature_xfoil(cst_u, cst_l, t, Minf: float, Re, AoA, n_crit=0.1, fname='feature-xfoil.txt'): ''' Evaluate by xfoil and extract features. Inputs: --- cst-u, cst-l: list of upper/lower CST coefficients of the airfoil. \n t: airfoil thickness or None \n Minf: free stream Mach number for wall Mach number calculation \n Re, AoA (deg): flight condition (s), float or list, for Xfoil \n n_crit: critical amplification ratio for transition in xfoil \n fname: output file name. If None, then no output \n ### Dependencies: cst-modeling3d, xfoil ''' from cst_modeling.foil import cst_foil from xfoil import XFoil from xfoil.model import Airfoil #TODO: Build foil #! 201 is the maximum amount of points that xfoil can handle #! tail = 0.001 is to avoid point overlap xx, yu, yl, t0, R0 = cst_foil(201, cst_u, cst_l, x=None, t=t, tail=0.001) #! xfoil do not support leading edge of (0,0) on both upper and lower surface x = np.array(list(reversed(xx[1:])) + xx[1:]) y = np.array(list(reversed(yu[1:])) + yl[1:]) foil = Airfoil(x, y) #TODO: Xfoil xf = XFoil() xf.print = False xf.airfoil = foil xf.max_iter = 40 #* Transition by power law xf.n_crit = n_crit #TODO: Xfoil calculation if not isinstance(Re, list): Re = [Re] AoA = [AoA] n = len(Re) for i in range(n): xf.reset_bls() if Re[i] is not None: xf.Re = Re[i] cl, cd, cm, cp = xf.a(AoA[i]) x, cp = xf.get_cp_distribution() print(xf.Re, AoA[i], cl) #* Extract features fF = PhysicalXfoil(Minf, AoA[i], Re[i]) fF.setdata(x, y, cp) fF.extract_features() #* Output if fname is None: continue if i == 0: f = open(fname, 'w') else: f = open(fname, 'a') f.write('\n') f.write('%10s %15.6f \n' % ('Minf', Minf)) f.write('%10s %15.6f \n' % ('AoA', AoA[i])) f.write('%10s %15.6f \n' % ('Re', Re[i] / 1e6)) f.write('%10s %15.6f \n' % ('CL', cl)) f.write('%10s %15.6f \n' % ('Cd', cd)) f.write('%10s %15.6f \n' % ('Cm', cm)) f.close() fF.output_features(fname=fname, append=True)
from xfoil import XFoil from xfoil.test import naca0012 xf = XFoil() xf.airfoil = naca0012 xf.Re = 1e6 xf.max_iter = 40 a, cl, cd, cm, co = xf.aseq(-20, 20, 0.5)
b = Xwing_aero1[:, 1] archive3 = open('lt.txt', 'w') for line in range(len(aa)): aux = [aa[line], b[line]] string = str(aux).replace("[", " ").replace(",", " ").replace("]", " ").replace("'", " ") archive3.writelines(string + '\n') aux.clear # Calculates the aerodynamic coeff using Xfoil archive3.close() xf.load('lt.txt') xf.Re = 1e3 xf.max_iter = 100 ann, cl, cd, cm, co = xf.aseq(1, 11, 1) an = np.linspace(1, 10, 10) desired = np.zeros(31) desired[0:10] = cl desired[10:20] = cd desired[20:30] = cm Surf, Iben, Itor, Xcg, Ycg = Struct.ArfoilProperties(1.0, Xwing_struct1) desired[30] = Xcg #2.Initialize Aero and Structural Models #2.a. Aero Model Elements, Xc, Xn, Xt, DL, A = Aero.InitializeAeroModel(Xwing_aero) AoA, Vnorm = 0.0, 6.0 Vinf = np.array([np.cos(AoA / 57.3), np.sin(AoA / 57.3)]) * Vnorm #wind speed
foil = Airfoil(x, y) #TODO: Xfoil xf = XFoil() xf.print = False xf.max_iter = 40 xf.airfoil = foil xf.xtr = [0.0, 0.0] Minf = 0.2 AoA = 8.0 Re = 1e7 fname = 'feature-xfoil.txt' xf.M = Minf xf.Re = Re cl, cd, cm, cp = xf.a(AoA) x, cp = xf.get_cp_distribution() with open(fname, 'w') as f: f.write('%10s %15.6f \n'%('Minf', Minf)) f.write('%10s %15.6f \n'%('AoA', AoA)) f.write('%10s %15.6f \n'%('Re', Re/1e6)) f.write('%10s %15.6f \n'%('CL', cl)) f.write('%10s %15.6f \n'%('Cd', cd)) f.write('%10s %15.6f \n'%('Cm', cm)) fF = PhysicalXfoil(Minf, AoA, Re) fF.setdata(x,y,cp) fF.extract_features()