Beispiel #1
0
    def __init__(self, master, cpacs_path, cpacs_out_path, submodule_list, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)
        self.pack(fill=tk.BOTH)

        self.submodule_list = submodule_list
        self.cpacs_out_path = cpacs_out_path

        # Notebook for tabs
        self.tabs = ttk.Notebook(self)
        self.tabs.grid(row=0, column=0, columnspan=3)  #pack()#expand=1, side=tk.LEFT)

        self.tixi = cpsf.open_tixi(cpacs_path)

        if len(apm.get_aeromap_uid_list(self.tixi)) == 0 :
            log.warning('No AeroMap in this CPACS file')
            aeromap_uid = 'New_AeroMap'
            description = 'AeroMap create by SettingGUI'
            apm.create_empty_aeromap(self.tixi, aeromap_uid, description)

        # Generate AeroMaps Edition tab
        aeromap_tap = AeroMapTab(self.tabs, self.tixi)

        # Generate Auto Tab =============
        self.tab_list = []
        self._update_all()

        # General button
        self.update_button = tk.Button(self, text='Update', command=self._update_all)
        self.update_button.grid(row=1, column=1,sticky='E')
        self.close_button = tk.Button(self, text='Save & Quit', command=self._save_quit)
        self.close_button.grid(row=1, column=2,sticky='W')
Beispiel #2
0
    def __init__(self, master, cpacs_path, cpacs_out_path, submodule_list):

        self.submodule_list = submodule_list
        self.cpacs_out_path = cpacs_out_path

        # GUI =============
        self.master = master
        self.master.title('CEASIOMpy Settings GUI')
        self.master.geometry('600x750+500+200')

        self.tabs = ttk.Notebook(self.master)
        self.tabs.pack(side=tk.TOP, fill='both')
        self.tabs.pack(expand=1, fill='both')

        # CPACS =============
        self.tixi = open_tixi(cpacs_path)

        if len(get_aeromap_uid_list(self.tixi)) == 0 :
            log.warning('No AeroMap in this CPACS file')
            aeromap_uid = 'New_AeroMap'
            description = 'AeroMap create by SettingGUI'
            create_empty_aeromap(self.tixi, aeromap_uid, description)

        # Generate AeroMaps Edition tab
        aeromap_tap = AeroMapTab(self.tabs, self.tixi)

        # # Generate Auto Tab =============
        self.tab_list = []
        self._update_all()

        # General buttons =============
        self.close_button = tk.Button(self.master, text='Save & Quit', command=self._save_quit)
        self.close_button.pack(side=tk.RIGHT)
        self.update_button = tk.Button(self.master, text='Update', command=self._update_all)
        self.update_button.pack(side=tk.RIGHT)
Beispiel #3
0
def one_iteration():
    """
    Compute the objective function.

    Function 'one_iteration' will exectute in order all the module contained
    in '...' and extract the ... value from the last CPACS file, this value will
    be returned to the optimizer CPACSUpdater....

    """
    global counter
    counter += 1

    # Create the parameter in CPACS with 'CPACSUpdater' module
    cpacs_path = mi.get_toolinput_file_path('CPACSUpdater')
    cpacs_out_path = mi.get_tooloutput_file_path('CPACSUpdater')

    tixi = cpsf.open_tixi(cpacs_path)
    wkdir_path = ceaf.create_new_wkdir(Rt.date)
    WKDIR_XPATH = '/cpacs/toolspecific/CEASIOMpy/filesPath/wkdirPath'
    tixi.updateTextElement(WKDIR_XPATH, wkdir_path)

    # TODO: improve this part! (maybe move somewhere else)
    # To delete coef from previous iter
    if opf.get_aeromap_path(Rt.modules) != 'None':
        xpath = opf.get_aeromap_path(Rt.modules)
        aeromap_uid = cpsf.get_value(tixi, xpath + '/aeroMapUID')
        Coef = apmf.get_aeromap(tixi, aeromap_uid)
        apmf.delete_aeromap(tixi, aeromap_uid)
        apmf.create_empty_aeromap(tixi, aeromap_uid, 'test_optim')
        apmf.save_parameters(tixi, aeromap_uid, Coef)
        cpsf.close_tixi(tixi, cpacs_path)

    # Update the CPACS file with the parameters contained in design_var_dict
    update_cpacs_file(cpacs_path, cpacs_out_path, design_var_dict)

    # Save the CPACS file
    if counter % 1 == 0:
        file_copy_from = mi.get_tooloutput_file_path('CPACSUpdater')
        shutil.copy(
            file_copy_from,
            optim_dir_path + '/Geometry/' + 'iter_{}.xml'.format(counter))

    # Run optimisation sub workflow
    wkf.copy_module_to_module('CPACSUpdater', 'out', Rt.modules[0], 'in')
    wkf.run_subworkflow(Rt.modules)
    wkf.copy_module_to_module(Rt.modules[-1], 'out', 'CPACSUpdater', 'in')

    # Extract results  TODO: improve this part
    cpacs_results_path = mi.get_tooloutput_file_path(Rt.modules[-1])
    log.info('Results will be extracted from:' + cpacs_results_path)
    tixi = cpsf.open_tixi(cpacs_results_path)

    # Update the constraints values
    update_res_var_dict(tixi)
    return compute_obj()
Beispiel #4
0
def add_skin_friction(cpacs_path, cpacs_out_path):
    """ Function to add the skin frinction drag coeffienct to aerodynamic coefficients

    Function 'add_skin_friction' add the skin friction drag 'cd0' to  the
    SU2 and pyTornado aeroMap, if their UID is not geven, it will add skin
    friction to all aeroMap. For each aeroMap it creates a new aeroMap where
    the skin friction drag coeffienct is added with the correct projcetions.

    Args:
        cpacs_path (str):  Path to CPACS file
        cpacs_out_path (str): Path to CPACS output file
    """

    tixi = cpsf.open_tixi(cpacs_path)
    tigl = cpsf.open_tigl(tixi)

    wing_area_max, wing_span_max = get_largest_wing_dim(tixi, tigl)

    analyses_xpath = '/cpacs/toolspecific/CEASIOMpy/geometry/analysis'

    # Requiered input data from CPACS
    wetted_area = cpsf.get_value(tixi, analyses_xpath + '/wettedArea')

    # Wing area/span, default values will be calated if no value found in the CPACS file
    wing_area_xpath = analyses_xpath + '/wingArea'
    wing_area = cpsf.get_value_or_default(tixi, wing_area_xpath, wing_area_max)
    wing_span_xpath = analyses_xpath + '/wingSpan'
    wing_span = cpsf.get_value_or_default(tixi, wing_span_xpath, wing_span_max)

    aeromap_uid_list = []

    # Try to get aeroMapToCalculate
    aeroMap_to_clculate_xpath = SF_XPATH + '/aeroMapToCalculate'
    if tixi.checkElement(aeroMap_to_clculate_xpath):
        aeromap_uid_list = cpsf.get_string_vector(tixi,
                                                  aeroMap_to_clculate_xpath)
    else:
        aeromap_uid_list = []

    # If no aeroMap in aeroMapToCalculate, get all existing aeroMap
    if len(aeromap_uid_list) == 0:
        try:
            aeromap_uid_list = apmf.get_aeromap_uid_list(tixi)
        except:
            raise ValueError(
                'No aeroMap has been found in this CPACS file, skin friction cannot be added!'
            )

    # Get unique aeroMap list
    aeromap_uid_list = list(set(aeromap_uid_list))
    new_aeromap_uid_list = []

    # Add skin friction to all listed aeroMap
    for aeromap_uid in aeromap_uid_list:

        log.info('adding skin friction coefficients to: ' + aeromap_uid)

        # Get orignial aeroPerformanceMap
        AeroCoef = apmf.get_aeromap(tixi, aeromap_uid)
        AeroCoef.complete_with_zeros()

        # Create new aeroCoefficient object to store coef with added skin friction
        AeroCoefSF = apmf.AeroCoefficient()
        AeroCoefSF.alt = AeroCoef.alt
        AeroCoefSF.mach = AeroCoef.mach
        AeroCoefSF.aoa = AeroCoef.aoa
        AeroCoefSF.aos = AeroCoef.aos

        # Iterate over all cases
        case_count = AeroCoef.get_count()
        for case in range(case_count):

            # Get parameters for this case
            alt = AeroCoef.alt[case]
            mach = AeroCoef.mach[case]
            aoa = AeroCoef.aoa[case]
            aos = AeroCoef.aos[case]

            # Calculate Cd0 for this case
            cd0 = estimate_skin_friction_coef(wetted_area,wing_area,wing_span, \
                                              mach,alt)

            # Projection of cd0 on cl, cd and cs axis
            #TODO: Should Cd0 be projected or not???
            aoa_rad = math.radians(aoa)
            aos_rad = math.radians(aos)
            cd0_cl = cd0 * math.sin(aoa_rad)
            cd0_cd = cd0 * math.cos(aoa_rad) * math.cos(aos_rad)
            cd0_cs = cd0 * math.sin(aos_rad)

            # Update aerodynamic coefficients
            cl = AeroCoef.cl[case] + cd0_cl
            cd = AeroCoef.cd[case] + cd0_cd
            cs = AeroCoef.cs[case] + cd0_cs

            # Shoud we change something? e.i. if a force is not apply at aero center...?
            if len(AeroCoef.cml):
                cml = AeroCoef.cml[case]
            else:
                cml = 0.0  # Shoud be change, just to test pyTornado
            if len(AeroCoef.cmd):
                cmd = AeroCoef.cmd[case]
            else:
                cmd = 0.0
            if len(AeroCoef.cms):
                cms = AeroCoef.cms[case]
            else:
                cms = 0.0

            # Add new coefficients into the aeroCoefficient object
            AeroCoefSF.add_coefficients(cl, cd, cs, cml, cmd, cms)

        # Create new aeroMap UID
        aeromap_sf_uid = aeromap_uid + '_SkinFriction'
        new_aeromap_uid_list.append(aeromap_sf_uid)

        # Create new description
        description_xpath = tixi.uIDGetXPath(aeromap_uid) + '/description'
        sf_description = cpsf.get_value(
            tixi,
            description_xpath) + ' Skin friction has been add to this AeroMap.'
        apmf.create_empty_aeromap(tixi, aeromap_sf_uid, sf_description)

        # Save aeroCoefficient object Coef in the CPACS file
        apmf.save_parameters(tixi, aeromap_sf_uid, AeroCoefSF)
        apmf.save_coefficients(tixi, aeromap_sf_uid, AeroCoefSF)

    # Get aeroMap list to plot
    plot_xpath = '/cpacs/toolspecific/CEASIOMpy/aerodynamics/plotAeroCoefficient'
    aeromap_to_plot_xpath = plot_xpath + '/aeroMapToPlot'

    if tixi.checkElement(aeromap_to_plot_xpath):
        aeromap_uid_list = cpsf.get_string_vector(tixi, aeromap_to_plot_xpath)
        new_aeromap_to_plot = aeromap_uid_list + new_aeromap_uid_list
        new_aeromap_to_plot = list(set(new_aeromap_to_plot))
        cpsf.add_string_vector(tixi, aeromap_to_plot_xpath,
                               new_aeromap_to_plot)
    else:
        cpsf.create_branch(tixi, aeromap_to_plot_xpath)
        cpsf.add_string_vector(tixi, aeromap_to_plot_xpath,
                               new_aeromap_uid_list)

    log.info('AeroMap "' + aeromap_uid + '" has been added to the CPACS file')

    cpsf.close_tixi(tixi, cpacs_out_path)
Beispiel #5
0
def aeromap_case_gen(modules):
    """
    Generate a CSV file containing a dataset generated with aeromap parameters
    only.

    Args:
        modules (lst) : list of modules to execute.

    Returns:
        file (str) : Path to CSV file.

    """
    file = MODULE_DIR + '/Aeromap_generated.csv'
    infile = mi.get_toolinput_file_path('PredictiveTool')
    outfile = mi.get_tooloutput_file_path('PredictiveTool')

    tixi = cpsf.open_tixi(infile)

    # Inputs
    alt = [0, 0]
    mach = [0.5, 0.5]
    aoa = [-10, 10]
    aos = [0, 0]
    nt = 100
    bounds = np.array([alt, mach, aoa, aos])
    # Sort criterion : ‘center’, ‘maximin’, ‘centermaximin’, ‘correlation’
    crit = 'corr'

    # Generate sample points, LHS or FullFactorial
    sampling = smp.LHS(xlimits=bounds, criterion=crit)
    xd = sampling(nt)
    xd = xd.transpose()
    # Delete the other aeromaps... maybe conserve them ?
    for uid in apmf.get_aeromap_uid_list(tixi):
        apmf.delete_aeromap(tixi, uid)

    # Create new aeromap
    aeromap_uid = 'DoE_Aeromap'
    am_xpath = tls.get_aeromap_path(modules)
    apmf.create_empty_aeromap(tixi, aeromap_uid)
    cpsf.add_string_vector(tixi, am_xpath + '/aeroMapUID', [aeromap_uid])

    # Add parameters to aeromap
    Param = apmf.AeroCoefficient()
    for i in range(0, xd.shape[1]):
        Param.add_param_point(xd[0][i], xd[1][i], xd[2][i], xd[3][i])
    apmf.save_parameters(tixi, aeromap_uid, Param)
    cpsf.close_tixi(tixi, infile)

    wkf.run_subworkflow(modules, cpacs_path_in=infile, cpacs_path_out=outfile)

    # Get Aerocoefficient
    tixi = cpsf.open_tixi(outfile)
    am_xpath = tls.get_aeromap_path(modules)
    aeromap_uid = cpsf.get_value(tixi, am_xpath + '/aeroMapUID')
    AeroCoefficient = apmf.get_aeromap(tixi, aeromap_uid)
    cpsf.close_tixi(tixi, outfile)

    dct = AeroCoefficient.to_dict()

    # Write to CSV
    df = pd.DataFrame(dct)
    df = df.transpose()
    var_type = [
        'obj' if i in objectives else
        'des' if i in ['alt', 'mach', 'aoa', 'aos'] else 'const'
        for i in df.index
    ]
    df.insert(0, 'type', var_type)
    df.to_csv(file, index=True)
    return file
Beispiel #6
0
def generate_su2_config(cpacs_path, cpacs_out_path, wkdir):
    """Function to create SU2 confif file.

    Function 'generate_su2_config' reads data in the CPACS file and generate
    configuration files for one or multible flight conditions (alt,mach,aoa,aos)

    Source:
        * SU2 config template: https://github.com/su2code/SU2/blob/master/config_template.cfg

    Args:
        cpacs_path (str): Path to CPACS file
        cpacs_out_path (str):Path to CPACS output file
        wkdir (str): Path to the working directory

    """

    # Get value from CPACS
    tixi = cpsf.open_tixi(cpacs_path)
    tigl = cpsf.open_tigl(tixi)

    # Get SU2 mesh path
    su2_mesh_xpath = '/cpacs/toolspecific/CEASIOMpy/filesPath/su2Mesh'
    su2_mesh_path = cpsf.get_value(tixi,su2_mesh_xpath)

    # Get reference values
    ref_xpath = '/cpacs/vehicles/aircraft/model/reference'
    ref_len = cpsf.get_value(tixi,ref_xpath + '/length')
    ref_area = cpsf.get_value(tixi,ref_xpath + '/area')
    ref_ori_moment_x = cpsf.get_value_or_default(tixi,ref_xpath+'/point/x',0.0)
    ref_ori_moment_y = cpsf.get_value_or_default(tixi,ref_xpath+'/point/y',0.0)
    ref_ori_moment_z = cpsf.get_value_or_default(tixi,ref_xpath+'/point/z',0.0)

    # Get SU2 settings
    settings_xpath = SU2_XPATH + '/settings'
    max_iter_xpath = settings_xpath + '/maxIter'
    max_iter = cpsf.get_value_or_default(tixi, max_iter_xpath,200)
    cfl_nb_xpath = settings_xpath + '/cflNumber'
    cfl_nb = cpsf.get_value_or_default(tixi, cfl_nb_xpath,1.0)
    mg_level_xpath =  settings_xpath + '/multigridLevel'
    mg_level = cpsf.get_value_or_default(tixi, mg_level_xpath,3)

    # Mesh Marker
    bc_wall_xpath = SU2_XPATH + '/boundaryConditions/wall'
    bc_wall_list = su2f.get_mesh_marker(su2_mesh_path)
    cpsf.create_branch(tixi, bc_wall_xpath)
    bc_wall_str = ';'.join(bc_wall_list)
    tixi.updateTextElement(bc_wall_xpath,bc_wall_str)

    # Fixed CL parameters
    fixed_cl_xpath = SU2_XPATH + '/fixedCL'
    fixed_cl = cpsf.get_value_or_default(tixi, fixed_cl_xpath,'NO')
    target_cl_xpath = SU2_XPATH + '/targetCL'
    target_cl = cpsf.get_value_or_default(tixi, target_cl_xpath,1.0)

    if fixed_cl == 'NO':
        active_aeroMap_xpath = SU2_XPATH + '/aeroMapUID'
        aeromap_uid = cpsf.get_value(tixi,active_aeroMap_xpath)

        log.info('Configuration file for ""' + aeromap_uid + '"" calculation will be created.')

        # Get parameters of the aeroMap (alt,ma,aoa,aos)
        Param = apmf.get_aeromap(tixi,aeromap_uid)
        param_count = Param.get_count()

        if param_count >= 1:
            alt_list = Param.alt
            mach_list =  Param.mach
            aoa_list = Param.aoa
            aos_list = Param.aos
        else:
            raise ValueError('No parametre have been found in the aeroMap!')

    else: # if fixed_cl == 'YES':
        log.info('Configuration file for fixed CL calculation will be created.')

        range_xpath = '/cpacs/toolspecific/CEASIOMpy/ranges'

        # Parameters fixed CL calulation
        param_count = 1

        # These parameters will not be used
        aoa_list = [0.0]
        aos_list = [0.0]

        cruise_mach_xpath= range_xpath + '/cruiseMach'
        mach = cpsf.get_value_or_default(tixi,cruise_mach_xpath,0.78)
        mach_list = [mach]
        cruise_alt_xpath= range_xpath + '/cruiseAltitude'
        alt = cpsf.get_value_or_default(tixi,cruise_alt_xpath,12000)
        alt_list = [alt]

        aeromap_uid = 'aeroMap_fixedCL_SU2'
        description = 'AeroMap created for SU2 fixed CL value of: ' + str(target_cl)
        apmf.create_empty_aeromap(tixi, aeromap_uid, description)
        Parameters = apmf.AeroCoefficient()
        Parameters.alt = alt_list
        Parameters.mach = mach_list
        Parameters.aoa = aoa_list
        Parameters.aos = aos_list
        apmf.save_parameters(tixi,aeromap_uid,Parameters)
        tixi.updateTextElement(SU2_XPATH+ '/aeroMapUID',aeromap_uid)


    # Get and modify the default configuration file
    cfg = su2f.read_config(DEFAULT_CONFIG_PATH)

    # General parmeters
    cfg['REF_LENGTH'] = ref_len
    cfg['REF_AREA'] = ref_area

    cfg['REF_ORIGIN_MOMENT_X'] = ref_ori_moment_x
    cfg['REF_ORIGIN_MOMENT_Y'] = ref_ori_moment_y
    cfg['REF_ORIGIN_MOMENT_Z'] = ref_ori_moment_z


    # Settings
    cfg['INNER_ITER'] = int(max_iter)
    cfg['CFL_NUMBER'] = cfl_nb
    cfg['MGLEVEL'] = int(mg_level)

    # Fixed CL mode (AOA will not be taken into account)
    cfg['FIXED_CL_MODE'] = fixed_cl
    cfg['TARGET_CL'] = target_cl
    cfg['DCL_DALPHA'] = '0.1'
    cfg['UPDATE_AOA_ITER_LIMIT'] = '50'
    cfg['ITER_DCL_DALPHA'] = '80'
    # TODO: correct value for the 3 previous parameters ??

    # Mesh Marker
    bc_wall_str = '(' + ','.join(bc_wall_list) + ')'
    cfg['MARKER_EULER'] = bc_wall_str
    cfg['MARKER_FAR'] = ' (Farfield)' # TODO: maybe make that a variable
    cfg['MARKER_SYM'] = ' (0)'       # TODO: maybe make that a variable?
    cfg['MARKER_PLOTTING'] = bc_wall_str
    cfg['MARKER_MONITORING'] = bc_wall_str
    cfg['MARKER_MOVING'] = '( NONE )'  # TODO: when do we need to define MARKER_MOVING?
    cfg['DV_MARKER'] = bc_wall_str

    # Parameters which will vary for the different cases (alt,mach,aoa,aos)
    for case_nb in range(param_count):

        cfg['MESH_FILENAME'] = su2_mesh_path

        alt = alt_list[case_nb]
        mach = mach_list[case_nb]
        aoa = aoa_list[case_nb]
        aos = aos_list[case_nb]

        Atm = get_atmosphere(alt)
        pressure = Atm.pres
        temp = Atm.temp

        cfg['MACH_NUMBER'] = mach
        cfg['AOA'] = aoa
        cfg['SIDESLIP_ANGLE'] = aos
        cfg['FREESTREAM_PRESSURE'] = pressure
        cfg['FREESTREAM_TEMPERATURE'] = temp

        cfg['ROTATION_RATE'] = '0.0 0.0 0.0'

        config_file_name = 'ConfigCFD.cfg'


        case_dir_name = ''.join(['Case',str(case_nb).zfill(2),
                                 '_alt',str(alt),
                                 '_mach',str(round(mach,2)),
                                 '_aoa',str(round(aoa,1)),
                                 '_aos',str(round(aos,1))])

        case_dir_path = os.path.join(wkdir,case_dir_name)
        if not os.path.isdir(case_dir_path):
            os.mkdir(case_dir_path)

        config_output_path = os.path.join(wkdir,case_dir_name,config_file_name)

        su2f.write_config(config_output_path,cfg)


        # Damping derivatives
        damping_der_xpath = SU2_XPATH + '/options/clalculateDampingDerivatives'
        damping_der = cpsf.get_value_or_default(tixi,damping_der_xpath,False)

        if damping_der:

            rotation_rate_xpath = SU2_XPATH + '/options/rotationRate'
            rotation_rate = cpsf.get_value_or_default(tixi,rotation_rate_xpath,1.0)

            cfg['GRID_MOVEMENT'] = 'ROTATING_FRAME'

            cfg['ROTATION_RATE'] = str(rotation_rate) + ' 0.0 0.0'
            os.mkdir(os.path.join(wkdir,case_dir_name+'_dp'))
            config_output_path = os.path.join(wkdir,case_dir_name+'_dp',config_file_name)
            su2f.write_config(config_output_path,cfg)

            cfg['ROTATION_RATE'] = '0.0 ' + str(rotation_rate) + ' 0.0'
            os.mkdir(os.path.join(wkdir,case_dir_name+'_dq'))
            config_output_path = os.path.join(wkdir,case_dir_name+'_dq',config_file_name)
            su2f.write_config(config_output_path,cfg)

            cfg['ROTATION_RATE'] = '0.0 0.0 ' + str(rotation_rate)
            os.mkdir(os.path.join(wkdir,case_dir_name+'_dr'))
            config_output_path = os.path.join(wkdir,case_dir_name+'_dr',config_file_name)
            su2f.write_config(config_output_path,cfg)

            log.info('Damping derivatives cases directory has been created.')



        # Control surfaces deflections
        control_surf_xpath = SU2_XPATH + '/options/clalculateCotrolSurfacesDeflections'
        control_surf = cpsf.get_value_or_default(tixi,control_surf_xpath,False)

        if control_surf:

            # Get deformed mesh list
            su2_def_mesh_xpath = SU2_XPATH + '/availableDeformedMesh'
            if tixi.checkElement(su2_def_mesh_xpath):
                su2_def_mesh_list = cpsf.get_string_vector(tixi,su2_def_mesh_xpath)
            else:
                log.warning('No SU2 deformed mesh has been found!')
                su2_def_mesh_list = []

            for su2_def_mesh in su2_def_mesh_list:

                mesh_path = os.path.join(wkdir,'MESH',su2_def_mesh)

                config_dir_path = os.path.join(wkdir,case_dir_name+'_'+su2_def_mesh.split('.')[0])
                os.mkdir(config_dir_path)
                cfg['MESH_FILENAME'] = mesh_path

                config_file_name = 'ConfigCFD.cfg'
                config_output_path = os.path.join(wkdir,config_dir_path,config_file_name)
                su2f.write_config(config_output_path,cfg)


    # TODO: change that, but if it is save in tooloutput it will be erease by results...
    cpsf.close_tixi(tixi,cpacs_path)
Beispiel #7
0
def one_optim_iter():
    """Function to evaluate the value to optimize.

    Function 'one_optim_iter' will exectute in order all the module contained
    in '...' and extract the ... value from the last CPACS file, this value will
    be returned to the optimizer
    CPACSUpdater....

    """

    # Create the parameter in CPACS with 'CPACSUpdater' module
    cpacs_path = mi.get_toolinput_file_path('CPACSUpdater')
    cpacs_out_path = mi.get_tooloutput_file_path('CPACSUpdater')

    tixi = cpsf.open_tixi(cpacs_path)
    wkdir_path = ceaf.create_new_wkdir()
    WKDIR_XPATH = '/cpacs/toolspecific/CEASIOMpy/filesPath/wkdirPath'
    tixi.updateTextElement(WKDIR_XPATH, wkdir_path)

    # TODO: improve this part! (maybe move somewhere else)
    # To delete coef from previous iter
    aeromap_uid = cpsf.get_value(tixi, SU2_XPATH + '/aeroMapUID')
    Coef = apmf.get_aeromap(tixi, aeromap_uid)
    apmf.delete_aeromap(tixi, aeromap_uid)
    apmf.create_empty_aeromap(tixi, aeromap_uid, 'test_optim')
    apmf.save_parameters(tixi, aeromap_uid, Coef)
    cpsf.close_tixi(tixi, cpacs_path)

    # Update the CPACS file with the parameters contained in optim_var_dict
    update_cpacs_file(cpacs_path, cpacs_out_path, optim_var_dict)

    # Run optimisation sub workflow
    wkf.copy_module_to_module('CPACSUpdater', 'out', module_optim[0], 'in')
    wkf.run_subworkflow(module_optim)
    wkf.copy_module_to_module(module_optim[-1], 'out', 'CPACSUpdater', 'in')

    # Extract results  TODO: improve this part
    cpacs_results_path = mi.get_tooloutput_file_path(module_optim[-1])
    log.info('Results will be extracted from:' + cpacs_results_path)
    tixi = cpsf.open_tixi(cpacs_results_path)

    mtom = cpsf.get_value(
        tixi,
        '/cpacs/vehicles/aircraft/model/analyses/massBreakdown/designMasses/mTOM/mass'
    )

    aeromap_uid = cpsf.get_value(tixi, SU2_XPATH + '/aeroMapUID')
    Coef = apmf.get_aeromap(tixi, aeromap_uid)

    cl = Coef.cl[0]
    cd = Coef.cd[0]
    cm = Coef.cms[0]

    log.info('=========================')
    for key, (name, listval, minval, maxval,
              command) in optim_var_dict.items():
        log.info(name, ': ', listval[-1])

    log.info('Cl/Cd: ' + str(cl / cd))
    log.info('Cl: ' + str(cl))
    log.info('Cd: ' + str(cd))
    log.info('Cd: ' + str(cm))
    log.info('MTOM:' + str(mtom))
    log.info('(Cl)/MTOM:' + str(cl / mtom))
    log.info('=========================')

    # TODO: add option to choose what will be returned
    # return -mtom
    # return -cl
    # return cd
    # return -cl/cd
    return -cl / cd / mtom