def pyAvl_Cf_Cm_FAER(acftpath, x, controlvec, Ixx, Iyy, Izz, Ixz, m, X_cg, rho, g, bspan, cbar, runfileexport): # print(x) # print(controlvec) # Path to aircraft geometry # NOTE: Airfoil file references in the aircraft geometry .avl file must be updated according to your computer's local file system aircraft = avl.FileWrapper(acftpath) # Show the aicraft geometry # session = avl.Session(geometry=aircraft) # if 'gs_bin' in session.config.settings: # img = session.save_geometry_plot()[0] # avl.show_image(img) # else: # session.show_geometry() # Unpack the state variables Vt = float(x[0]) a = float(x[1]) b = float(x[2]) Phi = float(x[3]) The = float(x[4]) Psi = float(x[5]) p = float(x[6]) q = float(x[7]) r = float(x[8]) xE = float(x[9]) yE = float(x[10]) h = float(x[11]) # Unpack the control inputs df = float(controlvec[0]) da = float(controlvec[1]) de = float(controlvec[2]) dr = float(controlvec[3]) current_params = avl.Case(name='Get_Current_Coefficients', alpha=a * r2d, beta=b * r2d, roll_rate=p * bspan / (2 * Vt), pitch_rate=q * cbar / (2 * Vt), yaw_rate=r * bspan / (2 * Vt), velocity=Vt, density=rho, gravity=g, mass=m, Ixx=Ixx, Iyy=Iyy, Izz=Izz, Izx=Ixz, bank=Phi, elevation=The, heading=Psi, flap=df, aileron=da, elevator=de, rudder=dr) session = avl.Session(geometry=aircraft, cases=[current_params]) result = session.run_all_cases() # UNCOMMENT to print out the force and moment coefficients # print("CX = {}".format( # result['Get_Current_Coefficients']['Totals']['CXtot'])) # print("CY = {}".format( # result['Get_Current_Coefficients']['Totals']['CYtot'])) # print("CZ = {}".format( # result['Get_Current_Coefficients']['Totals']['CZtot'])) # print("Cm = {}".format( # result['Get_Current_Coefficients']['Totals']['Cmtot'])) # print("Cn = {}".format( # result['Get_Current_Coefficients']['Totals']['Cntot'])) # print("Cl = {}".format( # result['Get_Current_Coefficients']['Totals']['Cltot'])) ## Export the run file (optional) if runfileexport == True: session.export_run_files() CX = result['Get_Current_Coefficients']['Totals']['CXtot'] CY = result['Get_Current_Coefficients']['Totals']['CYtot'] CZ = result['Get_Current_Coefficients']['Totals']['CZtot'] Cm = result['Get_Current_Coefficients']['Totals']['Cmtot'] Cn = result['Get_Current_Coefficients']['Totals']['Cntot'] Cl = result['Get_Current_Coefficients']['Totals']['Cltot'] return CX, CY, CZ, Cm, Cn, Cl
def get_aero_coefs(data, airfoil_clmax): filedir = os.path.dirname(os.path.abspath(__file__)) # append avlwrapper_io directory to PATH so AVL executables can be found os.environ["PATH"] += os.pathsep + filedir airfoil1_filename = data['airfoil1_name'] + '.dat' airfoil1_filepath = filedir + '/' + airfoil1_filename airfoil2_filename = data['airfoil2_name'] + '.dat' airfoil2_filepath = filedir + '/' + airfoil2_filename airfoil3_filename = data['airfoil3_name'] + '.dat' airfoil3_filepath = filedir + '/' + airfoil3_filename c1 = data['chord1'] c2 = data['chord2'] c3 = data['chord3'] x1 = 0 x2 = 0 x3 = 0 y1 = 0 y2 = data['span1'] y3 = data['span1'] + data['span2'] z1 = 0 z2 = 0 z3 = 0 aerosurface_root_chord = data['chord1'] aerosurface_mid_chord = data['chord2'] aerosurface_tip_chord = data['chord3'] aerosurface_root_le_pnt = avl.Point(x=x1, y=y1, z=z1) aerosurface_mid_le_pnt = avl.Point(x=x2, y=y2, z=z2) aerosurface_tip_le_pnt = avl.Point(x=x3, y=y3, z=z3) root_section = avl.Section(leading_edge_point=aerosurface_root_le_pnt, chord=aerosurface_root_chord, airfoil=avl.FileAirfoil(airfoil1_filepath)) mid_section = avl.Section(leading_edge_point=aerosurface_mid_le_pnt, chord=aerosurface_mid_chord, airfoil=avl.FileAirfoil(airfoil2_filepath)) tip_section = avl.Section(leading_edge_point=aerosurface_tip_le_pnt, chord=aerosurface_tip_chord, airfoil=avl.FileAirfoil(airfoil3_filepath)) # y_duplicate=0.0 duplicates the wing over a XZ-plane at Y=0.0 aerosurface = avl.Surface( name='aerosurface', n_chordwise=8, chord_spacing=avl.Spacing.cosine, n_spanwise=12, span_spacing=avl.Spacing.cosine, y_duplicate=0.0, sections=[root_section, mid_section, tip_section]) mach = 0.01 area_section1 = (c1 + c2) * (y2 - y1) * 0.5 area_section2 = (c2 + c3) * (y3 - y2) * 0.5 aerosurface_area = 2 * (area_section1 + area_section2) MAC_section1 = c1 - (2 * (c1 - c2) * (0.5 * c1 + c2) / (3 * (c1 + c2))) MAC_section2 = c2 - (2 * (c2 - c3) * (0.5 * c2 + c3) / (3 * (c2 + c3))) aerosurface_mac = (MAC_section1 * area_section1 / (area_section1 + area_section2) + MAC_section2 * area_section2 / (area_section1 + area_section2)) aerosurface_span = 2 * (y3 - y1) # calculate the m.a.c. leading edge location # not really sure if this point is correct for the three section surface def mac_le_pnt(root_chord, tip_chord, root_pnt, tip_pnt): pnt = ((2 * root_chord * root_pnt[dim] + root_chord * tip_pnt[dim] + tip_chord * root_pnt[dim] + 2 * tip_chord * tip_pnt[dim]) / (3 * (root_chord + tip_chord)) for dim in range(3)) return avl.Point(*pnt) le_pnt = mac_le_pnt(aerosurface_root_chord, aerosurface_tip_chord, aerosurface_root_le_pnt, aerosurface_tip_le_pnt) ref_pnt = avl.Point(x=le_pnt.x + 0.25 * aerosurface_mac, y=le_pnt.y, z=le_pnt.z) aircraft = avl.Geometry(name='aircraft', reference_area=aerosurface_area, reference_chord=aerosurface_mac, reference_span=aerosurface_span, reference_point=ref_pnt, mach=mach, surfaces=[aerosurface]) alphas = list(range(-10, 26, 1)) results = {} CL_dict = {} CD_dict = {} Cm_dict = {} for alpha in alphas: case = avl.Case(name='sweep', alpha=alpha) session = avl.Session(geometry=aircraft, cases=[case]) results[alpha] = session.run_all_cases()['sweep'] if (max(results[alpha]['StripForces']['aerosurface']['cl']) > airfoil_clmax): break else: CL_dict[float(alpha)] = ( results[alpha]['SurfaceForces']['aerosurface']['CL']) CD_dict[float(alpha)] = ( results[alpha]['SurfaceForces']['aerosurface']['CD']) Cm_dict[float(alpha)] = ( results[alpha]['SurfaceForces']['aerosurface']['Cm'])
print( "The pitch rate for the maximum positive load is {PR:.4f}, at {g:.4f} gs". format(PR=qcby2V, g=nmax)) CL_param = avl.Parameter(name='alpha', setting='CL', value=CLmaxload) PM_param = avl.Parameter(name='pitch_rate', setting='qc/2V', value=qcby2V) current_params = avl.Case(name='Run', alpha=CL_param, beta=b, roll_rate=0, pitch_rate=PM_param, yaw_rate=0, velocity=VNE, density=rho, gravity=g, mass=m, Ixx=Ixx, Iyy=Iyy, Izz=Izz, Izx=Ixz, flap=df, aileron=da, elevator=de, rudder=dr) # Run AVL session = avl.Session(geometry=aircraft, cases=[current_params]) result = session.run_all_cases() # Shear and Moment Diagrams qbar = 0.5 * rho * VNE**2
def run_avl(aircraft, mach, alpha, beta, p, q, r, u, iplot=0): """run Athena Vortex Lattice Method.""" case_name = 'zero_alpha' roll_rate = deg2rad(p) # [rad/s] pitch_rate = deg2rad(q) # [rad/s] yaw_rate = deg2rad(r) # [rad/s] d_aileron = u[0] # deg d_elevator = u[1] # deg d_rudder = -u[2] # deg gains = [-1, 1, 1] wing = aircraft['wing'] ht = aircraft['horizontal'] vt = aircraft['vertical'] wing_aspect_ratio = wing['aspect_ratio'] wing_area = wing['planform'] wing_taper = wing['taper'] wing_root_le_pnt = avl.Point(wing['station'], wing['buttline'], wing['waterline']) ht_aspect_ratio = ht['aspect_ratio'] ht_area = ht['planform'] ht_root_le_pnt = avl.Point(ht['station'], ht['buttline'], ht['waterline']) vt_aspect_ratio = vt['aspect_ratio'] vt_area = vt['planform'] vt_root_le_pnt = avl.Point(vt['station'], vt['buttline'], vt['waterline']) a = Atmosphere(0).speed_of_sound() ref_pnt = avl.Point(aircraft['weight']['cg'][0], aircraft['weight']['cg'][1], aircraft['weight']['cg'][2]) # Wing ------------------------------------------------------------------------------------------------------------- wing_span = span(wing_aspect_ratio, wing_area) wing_mac = mac(wing_aspect_ratio, wing_area, wing_taper) sections = list() if not wing['control_1']['b_2'] == 0: sections.append(avl_section(wing_root_le_pnt[1], 0, wing, 1, [])) sections.append( avl_section(wing_root_le_pnt[1] + wing_span * 0.5 * -wing['control_1']['b_2'], wing['control_1'], wing, 1, 'aileron', duplicate_sign=-1)) sections.append( avl_section(wing_root_le_pnt[1] + wing_span * 0.5 * -wing['control_1']['b_1'], wing['control_1'], wing, 1, 'aileron', duplicate_sign=-1)) if not wing['control_1']['b_1'] == -1: sections.append( avl_section(wing_root_le_pnt[1] + wing_span * 0.5, 0, wing, 1, [])) # y_duplicate=0.0 duplicates the wing over a XZ-plane at Y=0.0 wing = avl.Surface(name='wing', n_chordwise=12, chord_spacing=avl.Spacing.cosine, n_spanwise=20, span_spacing=avl.Spacing.cosine, y_duplicate=0.0, sections=sections) # HT --------------------------------------------------------------------------------------------------------------- ht_span = span(ht_aspect_ratio, ht_area) sections = list() if not ht['control_2']['b_1'] == 0: sections.append(avl_section(ht_root_le_pnt[1], 0, ht, 1, [])) sections.append( avl_section(ht_root_le_pnt[1] + ht_span * 0.5 * ht['control_2']['b_1'], ht['control_2'], ht, 1, 'elevator')) sections.append( avl_section(ht_root_le_pnt[1] + ht_span * 0.5 * ht['control_2']['b_2'], ht['control_2'], ht, 1, 'elevator')) if not ht['control_2']['b_2'] == 1: sections.append( avl_section(ht_root_le_pnt[1] + ht_span * 0.5, 0, ht, 1, [])) horizontal_tail = avl.Surface(name='horizontal_tail', n_chordwise=12, chord_spacing=avl.Spacing.cosine, n_spanwise=20, span_spacing=avl.Spacing.cosine, y_duplicate=0.0, sections=sections) # VT --------------------------------------------------------------------------------------------------------------- vt_span = span(vt_aspect_ratio, vt_area, mirror=0) sections = list() if not vt['control_1']['b_1'] == 0: sections.append(avl_section(vt_root_le_pnt[1], 0, vt, 0, [])) sections.append( avl_section(vt_root_le_pnt[1] + vt_span * vt['control_1']['b_1'], vt['control_1'], vt, 0, 'rudder')) sections.append( avl_section(vt_root_le_pnt[1] + vt_span * vt['control_1']['b_2'], vt['control_1'], vt, 0, 'rudder')) if not vt['control_1']['b_2'] == 1: sections.append(avl_section(vt_root_le_pnt[1] + vt_span, 0, vt, 0, [])) vertical_tail = avl.Surface(name='vertical_tail', n_chordwise=12, chord_spacing=avl.Spacing.cosine, n_spanwise=20, span_spacing=avl.Spacing.cosine, sections=sections) # Setup ------------------------------------------------------------------------------------------------------------ aircraft = avl.Geometry(name='aircraft', reference_area=wing_area, reference_chord=wing_mac, reference_span=wing_span, reference_point=ref_pnt, mach=mach, surfaces=[wing, horizontal_tail, vertical_tail]) def show_treffz(session_1): if 'gs_bin' in session_1.config.settings: images = session_1.save_trefftz_plots() for iimg in images: avl.show_image(iimg) else: for idx, _ in enumerate(session_1.cases): session_1.show_trefftz_plot(idx + 1) # cases start from 1 simple_case = avl.Case(name=case_name, alpha=alpha, beta=beta, aileron=gains[0] * d_aileron, elevator=gains[1] * d_elevator, rudder=gains[2] * d_rudder, roll_rate=roll_rate * wing_span / (2 * mach * a), pitch_rate=pitch_rate * wing_mac / (2 * mach * a), yaw_rate=yaw_rate * wing_span / (2 * mach * a)) session = avl.Session(geometry=aircraft, cases=[simple_case]) if iplot: if 'gs_bin' in session.config.settings: img = session.save_geometry_plot()[0] avl.show_image(img) else: session.show_geometry() show_treffz(session) # results are in a dictionary result = session.run_all_cases() cd = result[case_name]['Totals']['CXtot'] cy = result[case_name]['Totals']['CYtot'] cl = result[case_name]['Totals']['CLtot'] cmr = result[case_name]['Totals']['Cltot'] cmp = result[case_name]['Totals']['Cmtot'] cmy = result[case_name]['Totals']['Cntot'] print("cfm= {}".format([cd, cy, cl, cmr, cmp, cmy])) return [cd, cy, cl, cmr, cmp, cmy]