Construction of an aircraft design, analysis and optimization framework: PyADAO

The development of PyADAO has moved to concentrate on optimization methods as I am currently working on this. While there’re many interesting TODO list in model builder, low fidelity solver and APIs, to name a few. PyADAO is planned to be opensource in the near future, there are some issues like installation and docs that are not fully prepared for the release of its 0.1 Version yet. If this projects could fulfil some needs for you or you are also interested in building a similar project, feel free to contact me:)

Motivation&Backgrounds

Besides the introduction in projects page , the construction of PyADAO could also be help of :

Role&Responsibility

As the main (only) developer, currently I am responsible for the whole program.

A survey was conducted to find the exist aircraft design optimization frameworks, some of them are listed in the following tables:

 drawing
NameSUAVEParaPyAirConics/occ-airconicsPyACDT
DeveloperStanfordParaPy IncAndra Sobester; Paul Chamber, etcAAD Lab & MDO lab
Focusesinital designframeworkmodel generatornot known
Code infoPython 2
Heavy develop
PythonPython 3
Develop stopped
Python
Notesopensource on githubCommercialopensource on githubLab use

Why Python

Python.org

PyACDT paper

SUAVE paper

Bruce Eckel

Meanwile, many famous machine learning frameworks like Keras, tensorflow, scikit-learn are written (or at least the top level codes are written) in Python, which offers appleaing chances for implementing related machine learning algorithms in PyADAO

PyADAO capabilities

Moldel Builder

Solver

Numerical Optimization

A benchmark optimization of Rosenbrock function (dimension: 10, variable range: [-10, 10] for each dimension) can be shown:

Capability demonstration:

Instead of giving a lengthy, abstract description about the framwork’s function, here’s a case provided to see how PyADAO’s able to construct the wing geometry of DLR F4 aircraft in an object orientive and robust way:

import sys
from os.path import abspath, join, dirname, pardir

import numpy as np

from Aerodynamics.Aero_Solver import builtin_solvers_lib
from Builtins.Units import Unit
from Flight_Dynamics.Flight_Condition import phase
from Model_Builder.Aircraft_geo import Aircraft_geometry
from Model_Builder.Airfoil.Airfoils import Airfoil
from Model_Builder.Fuselage import Fuselage_Geometry
from Model_Builder.Main import Wing

sys.path.insert(0, abspath(join(dirname(__file__), pardir)))


'''
DLR F4 wing modeling
references:
[1] A Selection of Experimental Test Cases for the Validation of CFD Codes
[2] Drag Predictionfor the DLR-F4Wing/Body usingOVERFLOWandCFL3D on an Overset Mesh
[3] A comparison of Experimental Results for the Transonic Flow around the DFVLR-F-4 Wing Body Configuration: Final Report
'''
# some parameters:
Span = 0.5857 * 2 * Unit['m']   # source: [1]
Ref_area = 0.1454 * Unit['m^2']  # suorce: [1]
MAC = 0.1412  # source: [1]

# define wing geometric parameters:

def Sweep_Func(Epsilon):
    """
    27.1 deg source: [1]
    :param Epsilon:
    :return:
    """
    return 27.1


def Dihedral_Func(Epsilon):
    """
    unit: deg source: [1].Fig 1
    :param Epsilon:
    :return:
    """
    return 4.8


def Airfoil_Func(Epsilon):
    """
    airfoil datas at each loctaion
    source: [1]
    :param Epsilon:
    :return:
    """
    if Epsilon == 0.126:
        return Airfoil(Selig_Airfoil='DLR F4 DEF1')
    if Epsilon == 0.4:
        return Airfoil(Selig_Airfoil='DLR F4 DEF2')
    if Epsilon == 0.7:
        return Airfoil(Selig_Airfoil='DLR F4 DEF3')
    if Epsilon == 1.0:
        return Airfoil(Selig_Airfoil='DLR F4 DEF4')


def Chord_Func(Epsilon):
    """
    chord datas at each soan location
    :param Epsilon:
    :return:
    """
    if Epsilon == 0.126:
        return 202.13777 * Unit['mm']
    if Epsilon == 0.4:
        return 119.81715 * Unit['mm']
    if Epsilon == 0.7:
        return 90.23006 * Unit['mm']
    if Epsilon == 1.0:
        return 60.64112 * Unit['mm']


def Incidence_Angle(Epsilon):
    """
    source [3] Fig. 3
    :param Epsilon:
    :return:
    """
    if Epsilon == 0.126:
        return 4.4
    if Epsilon == 0.4:
        return 1.8
    if Epsilon == 0.7:
        return 0.98
    if Epsilon == 1.0:
        return -0.55


# ===========wing modeling==============
DLR_F4_Wing = Wing(name='DLR_F4_Wing')

# Yahudi break: 0.37
DLR_F4_Wing.Kinks_Position_list = [0.4]

DLR_F4_Wing.Build_Sections_location = np.array([0.126, 0.4, 0.7, 1])
DLR_F4_Wing.dihedral_angle = Dihedral_Func
DLR_F4_Wing.sweep_angle = Sweep_Func
DLR_F4_Wing.Airfoils = Airfoil_Func
DLR_F4_Wing.twist_angle = Incidence_Angle
DLR_F4_Wing.chord_length = Chord_Func
DLR_F4_Wing.Resolve_Wing(span_scale=0.5857, chord_scale=1)
DLR_F4_Wing.Build_Surface()
DLR_F4_Wing.show_surface(high_fidelity=True, duplicate=True)


# ===put the wing in to an aircraft instance===============
DLR_F4 = Aircraft_geometry('Flyxiang')
DLR_F4.add_surface(DLR_F4_Wing, apex=np.array([347, 0, 0]) * Unit['mm']) 
DLR_F4.add_fuselage(DLR_F4_Fuse)
DLR_F4.show_aircraft(high_fidelity=False)

The code:

DLR_F4.show_aircraft(high_fidelity=False)

will provide a low fidelity DLR F4 wing illustrated in the following picture.

drawing

If a high fidelity model is needed, just chang the defualt key word to True:

DLR_F4.show_aircraft(high_fidelity=True)

and you will get a CAD model by PythonOCC:

drawing

After the construction of aircraft model, it can be simply used to calculate the aerodynamic coefficients:

# ===========================Define flight condition(for CFD analysis)=================
DLR_F4_Test_Phase = phase()
DLR_F4_Test_Phase.flight_altitude = 8000 * Unit['m'] 
DLR_F4_Test_Phase.air_speed_kph = 918 * Unit['Km/h']
# =====================================================================================


# ===============================Low fidelity CFD========================================
# =====================AVL========================
solver = builtin_solvers_lib.low_fidelity_solver(DLR_F4, 'AVL')  
solver.set_params2solve(['CL', 'e'])
solver.set_reference_param(Sref=0.1454 * Unit['m^2'], Cref=0.1412 * Unit['m'])
solver.set_flight_condition(DLR_F4_Test_Phase)
solver.init(write_fuselage=True)
solver.run()
CL = solver.post_process('CL')
e = solver.post_process('e')
print('DLR_F4 CL: {}, e: {}'.format(CL, e))
solver.end()

# ==================== A more compact way to do similar work can be written as follows ===================
print('\nThe AVL method is can also be called by the followeing function:\n')
from Aerodynamics.Aero_Solver.solvers import Aircraft_coefficients_solver

CL_, e_ = Aircraft_coefficients_solver(DLR_F4, ['CL', 'e'], Sref=0.1454 * Unit['m^2'], Cref=0.1412 * Unit['m'],
                                       phase=DLR_F4_Test_Phase, write_fuselage=True)
print('DLR_F4 CL: {}, e: {}\n'.format(CL, e))

# ================== PyADAO have also implemented a Static Margin solver using AVL ======================
from Flight_Dynamics.FC_Solver import Get_Trimmed_SM
print('Static Margin is: {}'.format(Get_Trimmed_SM(DLR_F4, DLR_F4_Test_Phase, MAC=0.1412 * Unit['m'])))

Some other images of PyADAO are illustrated here:

drawing drawing drawing

Projects Outcome

Future of PyADAO

Notes: A detailed roadmap of PyADAO has been included in readme on bitbucket. The framework has changed its name to PyADASO, with the hope that Simulation capability is also included (plan to use JSBsim), albiet that this is a long map. Feel free to contact me to get more details if you like this project.