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 step(self, action): # assert self.action_space.contains(action), "%r (%s) invalid"%(action, type(action)) ''' action 包含 6 個機翼形狀控制參數以及 1 個攻角''' angular = action[6] k = action[0:6] '''將機翼控制座標傳入 airfoil, 並計算翼面之座標''' airfoil = construct_airfoil(*k) x, y = get_coords_plain(airfoil._spline(100)) '''將座標傳入 xfoil ''' self.xf.airfoil = Airfoil(x=x, y=y) # state = self.state self.xf.Re = 1e6 self.xf.M = 0.04 '''計算 cl, cd, cm, cp 當角度為 angular 時''' cl, cd, cm, cp = self.xf.a(angular) '''如果結果不穩定, 有無限大之值, 重設 state''' if np.isnan(cl) or np.isnan(cd) or np.isnan(cm) or np.isnan(cp): reward = -10.0 # self.state = self.reset() done = 0 else: '''如果結果穩定, 結束這個 weight 的計算''' '''升力最佳或升阻比最佳在此設定''' reward = cl / cd # reward = cl '''從機翼座標裡抽取 11 點當作 state''' x1, y1 = get_coords_plain(airfoil._spline(6)) '''state : 22 個機翼形狀值, 1 個角度, 1 個 cl, cd''' # self.state = np.append(np.append(np.append(np.append(x1, y1),angular), cl), cd) # self.state = np.append(np.append(x1, y1),angular) self.state = np.append(x1, y1) done = 1 return np.array(self.state), reward, done, {}
def reset(self): # (.01, .4), (.05, .4), (1, 3), (0.05, 3), (0.4, 8), (1, 10) # 0.08813299, 0.28250898, 2.80168427, 2.56204214, 1.48703742, 8.53824561 '''為了避免 state 有無窮大的值, 所以設定decays範圍''' # decays = [1.0, 0.5, 0.25, 0.125, 0.0625] decays = [1.0, 0.999, 0.995, 0.99, 0.95, 0.9, 0.5] for decay in decays: tmp1 = self.np_random.uniform(low=-1.0, high=1.0, size=(7,)) # tmp = tmp * [0.39, 0.35, 2.0, 2.95, 7.6, 9, 10] + [0.01, 0.05, 1, 0.05, 0.4, 1, 0] # tmp = tmp * [0.01, 0.1, 0.5, 0.5, 0.1, 1.0, 5] + [0.08813299, 0.28250898, 2.50168427, 2.56, 1.487, 8.54, 0] # k = [0.1584, 0.1565, 2.1241, 1.8255, 3.827, 11.6983] '''從標準NACA5410開始找''' tmp1 = tmp1 * decay tmp = tmp1 * [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 5] + [0.1584, 0.1565, 2.1241, 1.8255, 11.6983, 3.827, 6] airfoil = construct_airfoil(*tmp) x, y = get_coords_plain(airfoil._spline(100)) self.xf.airfoil = Airfoil(x=x, y=y) self.xf.Re = 1e6 self.xf.M = 0.04 cl, cd, cm, cp = self.xf.a(tmp[6]) if not np.isnan(cl): break x, y = get_coords_plain(airfoil._spline(6)) self.xf.Re = 1e6 self.xf.M = 0.04 # self.state = np.append(np.append(np.append(np.append(x, y), tmp1[6]), cl), cd) # self.state = np.append(np.append(x, y), tmp1[6]) self.state = np.append(x, y) self.steps_beyond_done = None return np.array(self.state)
def step1(self, action): # assert self.action_space.contains(action), "%r (%s) invalid"%(action, type(action)) angular = action[6] k = action[0:6] airfoil = construct_airfoil(*k) x, y = get_coords_plain(airfoil._spline(100)) x1, y1 = get_coords_plain(airfoil._spline(6)) self.xf.airfoil = Airfoil(x=x, y=y) # state = self.state self.xf.Re = 1e6 self.xf.M = 0.04 cl, cd, cm, cp = self.xf.a(angular) if np.isnan(cl) or np.isnan(cd) or np.isnan(cm) or np.isnan(cp): # reward = np.nan reward = -10 # self.state = self.reset() done = 0 else: # reward = cl/cd reward = cl done = 1 # self.state = np.append(np.append(np.append(np.append(x1, y1),angular), cl), cd) # self.state = np.append(np.append(x1, y1),angular) self.state = np.append(x1, y1) return np.array(self.state), reward, done, x, y
def airfoil(self): """Airfoil: Instance of the Airfoil class.""" n = self._lib.get_n_coords() x = np.asfortranarray(np.zeros(n), dtype=c_float) y = np.asfortranarray(np.zeros(n), dtype=c_float) self._lib.get_airfoil(x.ctypes.data_as(fptr), y.ctypes.data_as(fptr), byref(c_int(n))) return Airfoil(x.astype(float), y.astype(float))
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 __init__(self): self.xf = XFoil() self.min_action = np.array([0.1, 0.05, 1.0, 0.05, 0.4, 1.0, 0.0]) self.max_action = np.array([0.4, 0.4, 3.0, 3.0, 8.0, 10.0, 10.0]) ''' 測試開始, 可省略測試''' # (.01, .4), (.05, .4), (1, 3), (0.05, 3), (0.4, 8), (1, 10) # self.xf.airfoil = naca0012 # k = [0.08813299, 0.28250898, 2.80168427, 2.56204214, 1.48703742, 8.53824561] # k = [0.34422, 0.38976, 1.1, 2.9989, 1.6071, 9.9649] k = [0.1584, 0.1565, 2.1241, 1.8255, 11.6983, 3.827] # org # k = [0.1784, 0.1365, 2.1201, 1.8057, 3.8071, 11.7009] # k = [0.1472, 0.1638, 2.1041, 1.8156, 3.8141, 11.6808] # k = [0.1784, 0.1365, 2.1201, 1.8057, 3.8071, 11.7009] # k = [0.1783, 0.1366, 2.1283, 1.8073, 3.8325, 11.7176] # k = [0.25840, 0.14474, 2.22410, 1.92550, 11.59984, 3.92623] airfoil = construct_airfoil(*k) x, y = get_coords_plain(airfoil._spline(100)) self.xf.airfoil = Airfoil(x=x, y=y) # test_airfoil = NACA4(2, 3, 15) # a = test_airfoil.max_thickness() # self.xf.airfoil = test_airfoil.get_coords() self.xf.Re = 1e6 self.xf.M = 0.04 self.xf.print = False cl, cd, cm, cp = self.xf.a(9) x = np.array(x, dtype='float32') y = np.array(y, dtype='float32') reward = cl / cd # reward = cl ''' 測試結束, 可省略測試''' # cl, cd, cm, cp = self.xf.a(12.2357) # self.action_space = spaces.Discrete(30) self.action_space = spaces.Box(self.min_action, self.max_action, dtype=np.float32) # high = np.array([100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]) high = np.array([ 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0 ]) self.observation_space = spaces.Box( -high, high, dtype=np.float32) #創建state大小(25,f22機翼,b3cl.cd.aoa) self.seed() self.viewer = None self.state = None self.steps_beyond_done = None
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
def aerofoilModelling(self): file_data = self.aerofoilDat() self.aerofoilModel = Airfoil(file_data[:, 0], file_data[:, 1])
def cem(n_iterations=140, max_t=1000, gamma=1.0, print_every=10, pop_size=50, elite_frac=0.2, sigma=0.6, loop_no=10): """PyTorch implementation of the cross-entropy method. Params ====== n_iterations (int): maximum number of training iterations max_t (int): maximum number of timesteps per episode gamma (float): discount rate print_every (int): how often to print average score (over last 100 episodes) pop_size (int): size of population at each iteration elite_frac (float): percentage of top performers to use in update sigma (float): standard deviation of additive noise """ n_elite=int(pop_size*elite_frac) scores_deque = deque(maxlen=100) scores = [] best_weight = sigma*np.random.randn(agent.get_weights_dim()) # 一組 # best_weight = 2*np.random.randn(agent.get_weights_dim()) best_reward = 0 best_state = agent.set_state() g_best_reward = 0 for i_iteration in range(1, n_iterations+1): weights_pop = [best_weight + (sigma*np.random.randn(agent.get_weights_dim())) for i in range(pop_size)] sigma = sigma * 0.975 # sigma = sigma * 0.95 # rewards = np.array([agent.evaluate(weights, gamma, max_t) for weights in weights_pop]) rewards = [] actions = [] states = [] bb_reward = 0 for weights in weights_pop: reward, action, state = agent.evaluate(weights, gamma, max_t, best_state) if reward > bb_reward: bb_reward = reward rewards.append(reward) actions.append(action) states.append(state) rewards = np.asarray(rewards, dtype=np.float32) elite_idxs = rewards.argsort()[-n_elite:] elite_weights = [weights_pop[i] for i in elite_idxs] mean_weight = np.array(elite_weights).mean(axis=0) best_weight = weights_pop[elite_idxs[n_elite-1]] best_action = actions[elite_idxs[n_elite-1]] best_state = states[elite_idxs[n_elite-1]] best_reward = rewards[elite_idxs[n_elite-1]] '''如果將上面 best_state 輸入到最好的類神經網路平均權值, 看看是否有更好的 reward''' reward, action, x, y, state = agent.evaluate_act(mean_weight, gamma=1.0, action=best_action, state=best_state) print(i_iteration, best_reward, reward) best_x = x best_y = y if reward > best_reward: best_action = action best_reward = reward best_x = x best_y = y best_state = state best_weight = np.array(elite_weights).mean(axis=0) if best_reward > g_best_reward: g_best_action = action g_best_reward = best_reward g_best_x = best_x g_best_y = best_y g_best_state = best_state g_best_weight = best_weight # scores_deque.append(reward) # scores.append(reward) scores_deque.append(best_reward) scores.append(best_reward) torch.save(agent.state_dict(), 'checkpoint.pth') if i_iteration % print_every == 0: print('Episode {}\tAverage Score: {:.2f}'.format(i_iteration, np.mean(scores_deque))) if np.mean(scores_deque)>=190.0: print('\nEnvironment solved in {:d} iterations!\tAverage Score: {:.2f}'.format(i_iteration-100, np.mean(scores_deque))) break print (g_best_action) print (g_best_x) print (g_best_y) # np.savetxt(file_name, best_reward) # np.savetxt(file_name, best_reward_list) # np.savetxt(file_name, best_action) env.env.xf.airfoil = Airfoil(x=g_best_x, y=g_best_y) # test_airfoil = NACA4(2, 3, 15) # a = test_airfoil.max_thickness() # self.xf.airfoil = test_airfoil.get_coords() cl, cd, cm, cp = env.env.xf.a(g_best_action[6]) file_name = "reward"+str(loop_no)+".txt" f = open(file_name, 'w') f.write("%5.5f\n\n" % g_best_reward) f.write("%5.5f\n" % cl) f.write("%5.5f\n" % cd) f.write("%5.5f\n" % cm) f.write("%5.5f\n\n" % cp) for i in range(len(g_best_action)): f.write("%5.5f\n" % g_best_action[i]) f.write("\n") for i in range(len(scores)): if np.isnan(scores[i]): f.write("0\n") else: f.write("%5.5f\n" % scores[i]) f.close() # state = self.state return scores
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)
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]
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 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]
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)
import os import math from xfoil import XFoil from xfoil.model import Airfoil import numpy as np import pandas as pd # load .dat files array6409 = np.loadtxt("NACA6409.dat", skiprows=1) array2412 = np.loadtxt("NACA2412.dat", skiprows=1) naca6409 = Airfoil(x=1.155 * array6409[:, 0], y=2.541 * array6409[:, 1]) naca2412 = Airfoil(x=1.155 * array2412[:, 0], y=2.541 * array2412[:, 1]) # xf = XFoil() # xf.airfoil = naca6409 # xf.Re = 1e6 # xf.max_it er = 40 # print(xf.a(10)[0]) # load blade profile - fixed values : pitch, chord_length base_dir = r'C:\Users\USER\dev\mechanics' csv_file = 'blade_profile.csv' csv_dir = os.path.join(base_dir, csv_file) df = pd.read_csv(csv_dir) # df to dict dfdict = df.to_dict(orient="index") density = 1.225 df_collection = []
import os import math from xfoil import XFoil from xfoil.model import Airfoil import numpy as np import pandas as pd # load .dat files array6409 = np.loadtxt("NACA6409.dat", skiprows=1) array2412 = np.loadtxt("NACA2412.dat", skiprows=1) naca6409 = Airfoil(x=array6409[:, 0], y=array6409[:, 1]) naca2412 = Airfoil(x=array2412[:, 0], y=array2412[:, 1]) # naca6409 = Airfoil(x=1.155*array6409[:, 0], y=2.541*array6409[:, 1]) # naca2412 = Airfoil(x=1.155*array2412[:, 0], y=2.541*array2412[:, 1]) # xf = XFoil() # xf.airfoil = naca6409 # xf.Re = 1e6 # xf.max_it er = 40 # print(xf.a(10)[0]) # load blade profile - fixed values : pitch, chord_length base_dir = r'C:\Users\USER\dev\mechanics' csv_file = 'blade_profile_50-8.csv' csv_dir = os.path.join(base_dir, csv_file) df = pd.read_csv(csv_dir) # df to dict dfdict = df.to_dict(orient="index") density = 1.225 # df_collection = []
from xfoil.model import Airfoil from cfdpost.section.physical import PhysicalXfoil if __name__ == "__main__": t0 = time.perf_counter() #TODO: CST airfoil for Xfoil cst_u = [ 0.135283, 0.088574, 0.177210, 0.080000, 0.231590, 0.189572, 0.192000] cst_l = [-0.101390, -0.007993, -0.240000, -0.129790, -0.147840, -0.000050, 0.221251] xx, yu, yl, t0, R0 = cst_foil(101, np.array(cst_u), np.array(cst_l), x=None, t=0.0954, tail=0.002) x = np.concatenate((np.flip(xx[1:]), xx[1:]), axis=0) y = np.concatenate((np.flip(yu[1:]), yl[1:]), axis=0) 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