示例#1
0
文件: smuse.py 项目: mldmnn/CEASIOMpy
def write_inouts(v, inout, tixi):
    """Write inputs or outputs to cpacs.

    Write the specified input or the predicted output of the model to the
    CPACS file.

    Args:
        v (DataFrame): Contains the inout, locations.
        inout (np.array): Values of the inout.

    Returns:
        None.

    """

    tigl = cpsf.open_tigl(tixi)
    aircraft = cpud.get_aircraft(tigl)
    wings = aircraft.get_wings()
    fuselage = aircraft.get_fuselages().get_fuselage(1)

    v.fillna('-', inplace=True)
    for i, name in enumerate(v.index):
        if v.loc[name, 'setcmd'] != '-':
            exec('{} = {}'.format(name, inout[0][i]))
            eval(v.loc[name, 'setcmd'])
        elif v.loc[name, 'getcmd'] != '-':
            xpath = v.loc[name, 'getcmd']
            cpsf.create_branch(tixi, xpath)
            tixi.updateDoubleElement(xpath, inout[0][i], '%g')

    tigl.close()
示例#2
0
def test_copy_branch():
    """Test the function 'copy_branch'"""

    tixi = cpsf.open_tixi(CPACS_IN_PATH)

    # Create a new 'header' branch and copy the original 'header' into it
    xpath_new = '/cpacs/header'
    xpath_from = '/cpacs/header[1]'
    xpath_to = '/cpacs/header[2]'
    cpsf.create_branch(tixi, xpath_new, True)
    cpsf.copy_branch(tixi, xpath_from, xpath_to)

    # Check if a specific element has been copied
    xpath_elem_from = '/cpacs/header[1]/updates/update[1]/timestamp'
    xpath_elem_to = '/cpacs/header[2]/updates/update[1]/timestamp'
    elem_from = tixi.getTextElement(xpath_elem_from)
    elem_to = tixi.getTextElement(xpath_elem_to)

    assert elem_from == elem_to

    # Check if a specific attribute has been copied
    attrib_text_from = tixi.getTextAttribute(xpath_elem_from, 'uID')
    attrib_text_to = tixi.getTextAttribute(xpath_elem_to, 'uID')

    assert attrib_text_from == attrib_text_to
def toolspecific_update(fus_nb, awg, mw, out, cpacs_out_path):
    """ The function that update the cpacs file after the Weight_unc_main
        program.

        Args:
            fus_nb (integer): Number of fuselage [-].
            awg (class): AircraftWingGeometry class.
            mw (class): Masses and Weights class.
            out (class): Output class.
            cpacs_out_path (str): Path of the output file.


    """

    tixi = cpsf.open_tixi(cpacs_out_path)

    # Path definition
    CEASIOM_PATH = '/cpacs/toolspecific/CEASIOMpy'
    WEIGHT_XPATH = CEASIOM_PATH + '/weight'

    CREW_XPATH = WEIGHT_XPATH + '/crew'
    cpsf.create_branch(tixi, CREW_XPATH + '/cabinCrewMembers', False)

    PASS_XPATH = WEIGHT_XPATH + '/passengers'
    cpsf.create_branch(tixi, PASS_XPATH, False)

    # Path update
    if not tixi.checkElement(CREW_XPATH + '/cabinCrewMembers/cabinCrewMemberNb'):
        tixi.createElement(CREW_XPATH + '/cabinCrewMembers', 'cabinCrewMemberNb')
    tixi.updateDoubleElement(CREW_XPATH + '/cabinCrewMembers/cabinCrewMemberNb',\
                             out.cabin_crew_nb, '%g')

    if not tixi.checkElement(PASS_XPATH + '/passNb'):
        tixi.createElement(PASS_XPATH, 'passNb')
    tixi.updateIntegerElement(PASS_XPATH + '/passNb', out.pass_nb, '%i')

    if not tixi.checkElement(PASS_XPATH + '/mass'):
        tixi.createElement(PASS_XPATH, 'mass')
    tixi.updateDoubleElement(PASS_XPATH + '/mass', mw.mass_pass, '%g')

    if not tixi.checkElement(PASS_XPATH + '/toiletNb'):
        tixi.createElement(PASS_XPATH, 'toiletNb')
    tixi.updateIntegerElement(PASS_XPATH + '/toiletNb',int(out.toilet_nb),'%i')

    if not tixi.checkElement(PASS_XPATH + '/fuelMassMaxpass'):
        tixi.createElement(PASS_XPATH, 'fuelMassMaxpass')
    FMP_PATH = PASS_XPATH + '/fuelMassMaxpass'

    if not tixi.checkElement(FMP_PATH + '/description'):
        tixi.createElement(FMP_PATH, 'description')
    tixi.updateTextElement(FMP_PATH + '/description', 'Maximum amount of '\
                           + 'fuel with maximum payload [kg]')

    if not tixi.checkElement(FMP_PATH + '/mass'):
        tixi.createElement(FMP_PATH, 'mass')
    tixi.updateDoubleElement(FMP_PATH + '/mass', mw.mass_fuel_maxpass, '%g')

    cpsf.close_tixi(tixi, cpacs_out_path)

    return()
示例#4
0
def get_wkdir_or_create_new(tixi):
    """ Function get the wkdir path from CPACS or create a new one

    Function 'get_wkdir_or_create_new' checks in the CPACS file if a working
    directory already exit for this run, if not, a new one is created and
    return.

    Args:
        tixi (handle): TIXI handle

    Returns:
        wkdir_path (str): Path to the active working directory

    """

    WKDIR_XPATH = '/cpacs/toolspecific/CEASIOMpy/filesPath/wkdirPath'
    wkdir_path = cpsf.get_value_or_default(tixi, WKDIR_XPATH, '')
    if wkdir_path is '':
        wkdir_path = create_new_wkdir()
        cpsf.create_branch(tixi, WKDIR_XPATH)
        tixi.updateTextElement(WKDIR_XPATH, wkdir_path)
    else:
        # Check if the directory really exists
        if not os.path.isdir(wkdir_path):
            wkdir_path = create_new_wkdir()
            cpsf.create_branch(tixi, WKDIR_XPATH)
            tixi.updateTextElement(WKDIR_XPATH, wkdir_path)

    return wkdir_path
示例#5
0
def write_outputs(y, outputs):
    """Write outputs to cpacs.

    Write the predicted output of the model to the CPACS file.

    Args:
        y (DataFrame): Contains the outputs, locations.
        outputs (np.array): Values of the outputs.

    Returns:
        None.

    """

    tixi = cpsf.open_tixi(cpacs_path)
    tigl = cpsf.open_tigl(tixi)
    aircraft = cpud.get_aircraft(tigl)
    wings = aircraft.get_wings()
    fuselage = aircraft.get_fuselages().get_fuselage(1)

    y.fillna('-', inplace=True)
    for i, name in enumerate(y.index):
        if y.loc[name, 'setcmd'] != '-':
            exec('{} = {}'.format(name, outputs[0][i]))
            eval(y.loc[name, 'setcmd'])
        elif y.loc[name, 'getcmd'] != '-':
            xpath = y.loc[name, 'getcmd']
            cpsf.create_branch(tixi, xpath)
            tixi.updateDoubleElement(xpath, outputs[0][i], '%g')

    tigl.close()
    cpsf.close_tixi(tixi, cpacs_path_out)
示例#6
0
def test_create_branch():
    """Test the function 'create_branch'"""

    tixi_handle = open_tixi(CPACS_IN_PATH)

    update_branch = '/cpacs/header/updates/update'
    new_branch = '/cpacs/header/updates/update[3]/test/test1/test2'

    # This branch should be added
    tixi = create_branch(tixi_handle, update_branch, True)
    # This branch should not be added
    tixi = create_branch(tixi, update_branch, False)
    # 'new_branch' should be added
    tixi = create_branch(tixi, new_branch)

    # Save modified tixi in the output CPACS file
    close_tixi(tixi, CPACS_OUT_PATH)

    # Reopen the output CPACS file to check if branches have been added
    tixi_out = open_tixi(CPACS_OUT_PATH)

    # Check if the number of "update" child is equal to 3
    namedchild_nb = tixi_out.getNamedChildrenCount('/cpacs/header/updates',
                                                   'update')
    assert namedchild_nb == 3

    # Check if 'new_branch' has been added
    branch_check = tixi_out.checkElement(new_branch)
    assert branch_check
示例#7
0
def save_aeromap_from_df(tixi,
                         aeromap_df,
                         aeromap_uid,
                         description='No decription'):
    """ Saves AeroMap DataFrame into a CPACS file.

    Function 'save_aeromap_from_df' will add all the required nodes for a new
    aeroPerformanceMap, no value will be stored but function like 'create_aeromap' and
    '???' could be used to fill it then.

    Args:
        tixi (handles): TIXI Handle of the CPACS file
        aeromap_df (str): UID of the aeroPerformanceMap to create
        aeromap_uid (str): UID of the aeroPerformanceMap to create
        description (str): description of the aeroPerformanceMap to create
        """

    if tixi.uIDCheckExists(aeromap_uid):
        log.warning('This UID already exits! The aeromap will be erase!')
        delete_aeromap(tixi, aeromap_uid)
    else:
        log.info(aeromap_uid + ' aeroMap will be created.')

        # Add the /aeroMap node, or a new child is already exists
    cpsf.create_branch(tixi, AEROPERFORMANCE_XPATH + '/aeroMap', True)
    am_count = tixi.getNamedChildrenCount(AEROPERFORMANCE_XPATH, 'aeroMap')
    aeromap_xpath = AEROPERFORMANCE_XPATH + '/aeroMap[' + str(am_count) + ']'

    # Add UID and sub nodes
    cpsf.add_uid(tixi, aeromap_xpath, aeromap_uid)
    tixi.addTextElement(aeromap_xpath, 'name', aeromap_uid)
    tixi.addTextElement(aeromap_xpath, 'description', description)
    apm_bc_xpath = aeromap_xpath + '/boundaryConditions'
    cpsf.create_branch(tixi, apm_bc_xpath)
    tixi.addTextElement(apm_bc_xpath, 'atmosphericModel', 'ISA')

    # Add /AeroPerformanceMap and sub nodes
    apm_xpath = aeromap_xpath + '/aeroPerformanceMap'
    cpsf.create_branch(tixi, apm_xpath)

    # Add states
    for state, xstate in zip(STATES, XSTATES):
        if not state in aeromap_df:
            raise ValueError('Missing {} value in the AeroMap!'.format(state))
        state_xpath = apm_xpath + '/' + xstate
        cpsf.create_branch(tixi, state_xpath)
        cpsf.add_float_vector(tixi, state_xpath, aeromap_df[state].tolist())

    # Add coefficients
    for coef in COEF_LIST:
        if coef in aeromap_df:
            coef_xpath = apm_xpath + '/' + coef
            cpsf.create_branch(tixi, coef_xpath)
            cpsf.add_float_vector(tixi, coef_xpath, aeromap_df[coef].tolist())
        else:
            log.info(
                'There is no {} coefficient in this AeroMap!'.format(coef))
示例#8
0
def create_routine_folder():
    """Create the working dicrectory of the routine.

    Create a folder in which all CEASIOMpy runs and routine parameters will be
    saved. This architecture may change in the future. For now the architecture
    of the folder is as such :

    > CEASIOMpy_Run_XX-XX-XX
        -> Optim
            --> Geometry
            --> Runs
                ---> Run_XX-XX-XX
        -> Optim2
            |
        -> OptimX
        -> DoE

    Args:
        None.

    """

    global optim_dir_path, Rt

    # Create the main working directory
    tixi = cpsf.open_tixi(opf.CPACS_OPTIM_PATH)
    wkdir = ceaf.get_wkdir_or_create_new(tixi)
    optim_dir_path = os.path.join(wkdir, Rt.type)
    Rt.date = wkdir[-19:]

    # Save the path to the directory in the CPACS
    if tixi.checkElement(opf.OPTWKDIR_XPATH):
        tixi.removeElement(opf.OPTWKDIR_XPATH)
    cpsf.create_branch(tixi, opf.OPTWKDIR_XPATH)
    tixi.updateTextElement(opf.OPTWKDIR_XPATH, optim_dir_path)

    # Add subdirectories
    if not os.path.isdir(optim_dir_path):
        os.mkdir(optim_dir_path)
        os.mkdir(optim_dir_path + '/Geometry')
        os.mkdir(optim_dir_path + '/Runs')
    else:
        index = 2
        optim_dir_path = optim_dir_path + str(index)
        while os.path.isdir(optim_dir_path):
            index += 1
            optim_dir_path = optim_dir_path.split(
                Rt.type)[0] + Rt.type + str(index)
        os.mkdir(optim_dir_path)
        os.mkdir(optim_dir_path + '/Geometry')
        os.mkdir(optim_dir_path + '/Runs')
    tixi.updateTextElement(opf.OPTWKDIR_XPATH, optim_dir_path)
    tixi.updateTextElement(opf.WKDIR_XPATH, optim_dir_path)

    cpsf.close_tixi(tixi, opf.CPACS_OPTIM_PATH)
示例#9
0
def cpacs_engine_update(ui, ed, mw, out_xml):
    """ The function that update the cpacs file after the Weight_unc_main
        program.

        INPUT
        (class) mw          --Arg.: MassesWeihts class.
        (class) ui          --Arg.: UserInputs class.
        (class) ed          --Arg.: EngineData class.
        ##======= Class are defined in the Input_Classes folder =======##
        (char) out_xml      --Arg.: Path of the output file.

        OUTPUT
        (file) cpacs.xml --Out.: Updated cpacs file.
    """
    tixi = cpf.open_tixi(out_xml)
    tigl = cpf.open_tigl(tixi)

    # Path creation ==========================================================
    EN_PATH = '/cpacs/vehicles/engines'
    if tixi.checkElement(EN_PATH):
        tixi.removeElement(EN_PATH)
    for e in range(0, ed.NE):
        EN_PATH = '/cpacs/vehicles/engines/engine' + str(e + 1)
        tixi = cpf.create_branch(tixi, EN_PATH, True)
        EN_UID = 'EngineuID_' + str(e + 1)
        tixi = cpf.add_uid(tixi, EN_PATH, EN_UID)
        tixi.createElement(EN_PATH, 'name')
        if not ed.EN_NAME[e]:
            EN_NAME = 'Engine_' + str(e + 1)
            tixi.updateTextElement(EN_PATH + '/name', EN_NAME)
        else:
            tixi.updateTextElement(EN_PATH + '/name', ed.EN_NAME[e])
        ENA_PATH = EN_PATH + '/analysis/mass'
        tixi = cpf.create_branch(tixi, ENA_PATH, False)
        tixi = cpf.add_uid(tixi, EN_PATH, EN_UID + '_mass')
        tixi.createElement(ENA_PATH, 'mass')
        tixi.updateDoubleElement(ENA_PATH + '/mass', ed.en_mass, '%g')
        ENT_PATH = EN_PATH + '/analysis'
        tixi.createElement(ENT_PATH, 'thrust00')
        tixi.updateDoubleElement(ENT_PATH + '/thrust00', ed.max_thrust, '%g')
    # Saving and closing the new cpacs file inside the ToolOutput folder -----
    tixi.saveDocument(out_xml)
    cpf.close_tixi(tixi, out_xml)

    # Openign and closing again the cpacs file, formatting purpose -----------
    tixi = cpf.open_tixi(out_xml)
    tigl = cpf.open_tigl(tixi)
    tixi.saveDocument(out_xml)
    cpf.close_tixi(tixi, out_xml)

    return ()
示例#10
0
def get_user_fuel(fus_nb, ui, cpacs_in):
    """Function to extract fuel data from a CPACS file

    Function 'get_user_fuel' extracts fuel data from the CPACS file, the code
    will use the default value when they are missing.

    Args:
        fus_nb (int): Number of fuselage.
        ui (class): UserInputs class
        cpacs_in (str): Path to the CPACS file

    Returns:
        ui (class): Modified UserInputs class

    """

    log.info('Starting data extraction from CPACS file')

    tixi = cpsf.open_tixi(cpacs_in)
    FUEL_XPATH = '/cpacs/toolspecific/CEASIOMpy/fuels'
    cpsf.create_branch(tixi, FUEL_XPATH, False)

    if fus_nb:
        for i in range(0, fus_nb):
            if fus_nb > 1:
                F = 'fuelOnCabin' + str(i + 1)
            else:
                F = 'fuelOnCabin'
            if not tixi.checkElement(FUEL_XPATH + '/' + F):
                tixi.createElement(FUEL_XPATH, F)
                tixi.updateDoubleElement(FUEL_XPATH + '/' + F, ui.F_FUEL[i],
                                         '%g')
            else:
                ui.F_FUEL[i] = tixi.getDoubleElement(FUEL_XPATH + '/' + F)
    else:
        if not tixi.checkElement(FUEL_XPATH + '/fuelOnCabin'):
            tixi.createElement(FUEL_XPATH, 'fuelOnCabin')
            tixi.updateDoubleElement(FUEL_XPATH + '/fuelOnCabin',
                                     ui.FUEL_ON_CABIN, '%g')
        else:
            temp = tixi.updateDoubleElement(FUEL_XPATH + '/fuelOnCabin',
                                            ui.FUEL_ON_CABIN, '%g')
            if temp != ui.FUEL_ON_CABIN and temp > 0:
                ui.FUEL_ON_CABIN = temp

    log.info('Data from CPACS file succesfully extracted')

    cpsf.close_tixi(tixi, cpacs_in)

    return (ui)
示例#11
0
def cpacs_engine_update(ui, ed, mw, cpacs_out_path):
    """ The function that update the cpacs file after the Weight_unc_main
        program.

    Args:
        mw (class): MassesWeihts class.
        ui (class): UserInputs class.
        ed (class): EngineData class.
        cpacs_out_path (str): Path of the CPACS output file.

    """

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

    EN_XPATH = '/cpacs/vehicles/engines'

    if tixi.checkElement(EN_XPATH):
        tixi.removeElement(EN_XPATH)
    for e in range(0,ed.NE):

        EN_XPATH = '/cpacs/vehicles/engines/engine' + str(e+1)
        cpsf.create_branch(tixi, EN_XPATH, True)

        EN_UID = 'EngineuID_' + str(e+1)
        cpsf.add_uid(tixi, EN_XPATH, EN_UID)
        tixi.createElement(EN_XPATH, 'name')

        if not ed.EN_NAME[e]:
            EN_NAME = 'Engine_' + str(e+1)
            tixi.updateTextElement(EN_XPATH + '/name', EN_NAME)
        else:
            tixi.updateTextElement(EN_XPATH + '/name', ed.EN_NAME[e])

        ENA_XPATH = EN_XPATH + '/analysis/mass'
        cpsf.create_branch(tixi, ENA_XPATH, False)
        cpsf.add_uid(tixi, EN_XPATH, EN_UID+'_mass')
        tixi.createElement(ENA_XPATH, 'mass')
        tixi.updateDoubleElement(ENA_XPATH + '/mass', ed.en_mass, '%g')

        ENT_XPATH = EN_XPATH + '/analysis'
        tixi.createElement(ENT_XPATH, 'thrust00')
        tixi.updateDoubleElement(ENT_XPATH + '/thrust00', ed.max_thrust, '%g')

    cpsf.close_tixi(tixi, cpacs_out_path)

    return()
示例#12
0
def add_skin_friction(cpacs_path, cpacs_out_path):
    """ Function to add the skin frinction drag coeffienct to the CPACS file

    Function 'add_skin_friction' add the skin friction drag 'cd0' to the CPACS
    file, then it could be added to the drag coeffienct obtain with Euler
    calcualtions or other methods

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

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

    wing_area_max, wing_span_max = get_largest_wing_dim(tixi, tigl)

    analysis_xpath = '/cpacs/toolspecific/CEASIOMpy/geometry/analysis'
    range_xpath = '/cpacs/toolspecific/CEASIOMpy/ranges'

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

    # Not requiered input data (a default value will be used if no
    # value has been found in the CPACS file)
    wing_area_xpath = analysis_xpath + '/wingArea'
    tixi, wing_area = get_value_or_default(tixi, wing_area_xpath,
                                           wing_area_max)
    if wing_area != wing_area_max:
        log.warning('Wing area found in the CPACS file /toolspecific is \
                     different from the one calculated from geometry, \
                     /toolspecific value will be used')

    wing_span_xpath = analysis_xpath + '/wingSpan'
    tixi, wing_span = get_value_or_default(tixi, wing_span_xpath,
                                           wing_span_max)
    if wing_span != wing_span_max:
        log.warning('Wing span found in the CPACS file /toolspecific is \
                    different from the one calculated from geometry, \
                    /toolspecific value will be used')

    cruise_alt_xpath = range_xpath + '/cruiseAltitude'
    tixi, cruise_alt = get_value_or_default(tixi, cruise_alt_xpath, 12000)

    cruise_mach_xpath = range_xpath + '/cruiseMach'
    tixi, cruise_mach = get_value_or_default(tixi, cruise_mach_xpath, 0.78)

    # Calculate Cd0
    cd0 = estimate_skin_friction_coef(wetted_area,wing_area,wing_span, \
                                      cruise_mach,cruise_alt)

    # Save Cd0 in the CPACS file
    cd0_xpath = '/cpacs/toolspecific/CEASIOMpy/aerodynamics/skinFriction/cd0'
    tixi = create_branch(tixi, cd0_xpath)
    tixi.updateDoubleElement(cd0_xpath, cd0, '%g')
    log.info('Skin friction drag coeffienct (cd0) has been saved in the \
              CPACS file')

    close_tixi(tixi, cpacs_out_path)
示例#13
0
    def _save_quit(self):

        # Iterate over all existing tabs
        for tab in self.tab_list:
            # Iterate in Variable dictionary of each tab
            for key, var in tab.var_dict.items():
                # Get the XPath from the GUI setting dictionary and crate a branch
                name = tab.gui_dict[key][0]
                xpath = tab.gui_dict[key][4]
                cpsf.create_branch(self.tixi,xpath)
                if name == '__AEROMAP_CHECHBOX':
                    aeromap_uid_list_str = ''
                    for aeromap_uid, aeromap_bool in tab.aeromap_var_dict.items():
                        if aeromap_bool.get():
                            aeromap_uid_list_str += aeromap_uid + ';'
                    if aeromap_uid_list_str == '':
                        messagebox.showerror('ValueError', 'In the Tab "' + \
                                       tab.module_name + '", no value has been selected for "' + \
                                       name + '" ')
                        raise TypeError('No value has been selected for ' + name + ' !')
                    self.tixi.updateTextElement(xpath, aeromap_uid_list_str)

                # '__AEROMAP_SELECTION' and list Type value will be saved as any other variable
                else:
                    if str(var.get()) == '':
                        # Not working when it expect an 'int' or a 'float'
                        messagebox.showerror('ValueError', 'In the Tab "' + \
                                       tab.module_name + '", no value has been entered for "' + \
                                       name + '" ')
                        raise TypeError('No value has been entered for ' + name + ' !')

                    try:
                        self.tixi.updateTextElement(xpath, str(var.get()))
                    except:

                        messagebox.showerror('TypeError', 'In the Tab "' + \
                                       tab.module_name + '", the value "' + \
                                       name + '" has not the correct type!')
                        raise TypeError(name + ' has not the correct type!')

        cpsf.close_tixi(self.tixi, self.cpacs_out_path)

        self.quit()
示例#14
0
def create_default_toolspecific():
    """Create a default XML /toolspecific based on all __spec__ xpath and
       default values. Two CPACS file are created and saved in /utils/doc/

    """

    CPACS_PATH = './doc/empty_cpacs.xml'

    tixi_in = cpsf.open_tixi(CPACS_PATH)
    tixi_out = cpsf.open_tixi(CPACS_PATH)

    for mod_name, specs in get_all_module_specs().items():
        if specs is not None:
            # Inputs
            for entry in specs.cpacs_inout.inputs:

                xpath = entry.xpath
                if xpath.endswith('/'):
                    xpath = xpath[:-1]

                value_name = xpath.split("/")[-1]
                xpath_parent = xpath[:-(len(value_name)+1)]

                if not tixi_in.checkElement(xpath):
                    cpsf.create_branch(tixi_in,xpath_parent)
                    if entry.default_value is not None:
                        value = str(entry.default_value)
                    else:
                        value = 'No default value'
                    tixi_in.addTextElement(xpath_parent,value_name,value)

            # Outputs
            for entry in specs.cpacs_inout.outputs:
                xpath = entry.xpath
                cpsf.create_branch(tixi_out,xpath)

    TOOLSPECIFIC_INPUT_PATH = './doc/input_toolspecifics.xml'
    TOOLSPECIFIC_OUTPUT_PATH = './doc/output_toolspecifics.xml'
    cpsf.close_tixi(tixi_in,TOOLSPECIFIC_INPUT_PATH)
    cpsf.close_tixi(tixi_out,TOOLSPECIFIC_OUTPUT_PATH)
示例#15
0
def update_am_path(tixi, am_uid):
    """Replace the aeromap uID for each module.

    Update the aeromap uID that is used for by modules in the optimisation loop

    Args:
        tixi (Tixi3 handle): Handle of the current CPACS file.
        am_uid (str): uID of the aeromap that will be used by all modules.

    Return:
        None.

    """

    am_xpath = ['/cpacs/toolspecific/pytornado/aeroMapUID',
                '/cpacs/toolspecific/CEASIOMpy/aerodynamics/su2/aeroMapUID']
    for name in am_xpath:
        if tixi.checkElement(name):
            tixi.updateTextElement(name, am_uid)
        else:
            cpsf.create_branch(tixi, name)
            tixi.updateTextElement(name, am_uid)
示例#16
0
def save_timestamp(tixi, xpath):
    """Function to get start and end time of an SU2 calculation.

    Function 'get_efficiency' the CL/CD ratio in the results file
    (forces_breakdown.dat)

    Args:
        tixi (handles): TIXI Handle of the CPACS file
        xpath (str): XPath where start and end time will be stored

    Returns:
        tixi (handles): Modified TIXI Handle

    """

    logfile_name = __file__.split('.')[0] + '.log'

    start_time = None
    end_time = None

    with open(logfile_name) as f:
        for line in f.readlines():
            if '>>> SU2 End Time' in line:
                start_time = line.split(' - ')[0]
            if '>>> SU2 Start Time' in line:
                end_time = line.split(' - ')[0]

    if start_time == None:
        log.warning("SU2 Start time has not been found in the logfile!")
    if end_time == None:
        log.warning("SU2 End time has not been found in the logfile!")

    tixi = create_branch(tixi, xpath + '/startTime')
    tixi.updateTextElement(xpath + '/startTime', start_time)
    tixit = create_branch(tixi, xpath + '/endTime')
    tixi.updateTextElement(xpath + '/endTime', end_time)

    return tixi
示例#17
0
def get_cl(cpacs_path, cpacs_out_path):
    """ Function to calculate CL requiered as a function of the parameter found
    in the CPACS file.

    Function 'get_cl' find input value in the CPACS file, calculate the
    requiered CL (with calculate_cl) and  save the CL value in
    /cpacs/toolspecific/CEASIOMpy/aerodynamics/su2/targetCL

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

    """

    tixi = open_tixi(cpacs_path)

    # XPath definition
    model_xpath = '/cpacs/vehicles/aircraft/model'
    ref_area_xpath = model_xpath + '/reference/area'
    mtom_xpath = model_xpath + '/analyses/massBreakdown/designMasses/mTOM/mass'
    range_xpath = '/cpacs/toolspecific/CEASIOMpy/ranges'
    cruise_alt_xpath = range_xpath + '/cruiseAltitude'
    cruise_mach_xpath = range_xpath + '/cruiseMach'
    load_fact_xpath = range_xpath + '/loadFactor'
    su2_xpath = '/cpacs/toolspecific/CEASIOMpy/aerodynamics/su2'

    # Requiered input data from CPACS
    ref_area = get_value(tixi, ref_area_xpath)
    mtom = get_value(tixi, mtom_xpath)

    # Requiered input data that could be replace by a default value if missing
    tixi, cruise_alt = get_value_or_default(tixi, cruise_alt_xpath, 12000.0)
    tixi, cruise_mach = get_value_or_default(tixi, cruise_mach_xpath, 0.78)
    tixi, load_fact = get_value_or_default(tixi, load_fact_xpath, 1.05)

    # Get atmosphere from cruise altitude
    Atm = get_atmosphere(cruise_alt)

    # CL calculation
    target_cl = calculate_cl(ref_area, cruise_alt, cruise_mach, mtom,
                             load_fact)

    # Save TargetCL
    tixi = create_branch(tixi, su2_xpath)
    tixi.addDoubleElement(su2_xpath, 'targetCL', target_cl, '%g')
    tixi.addTextElement(su2_xpath, 'fixedCL', 'YES')
    log.info('Target CL has been saved in the CPACS file')

    close_tixi(tixi, cpacs_out_path)
示例#18
0
def save_model(Tool):
    """Save trained surrogate model to a file.

    Create a file to which the class containing the surrogate model and its
    parameters will be saved in order to be re-used using the pickle module.
    The file is saved in the current working directory and the path to it is
    added to the CPACS file.

    Args:
        Tool (Prediction_tool object): Contains the model

    Returns:
        None.

    """

    date = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
    cpacs_path = mif.get_toolinput_file_path('SMTrain')
    cpacs_out_path = mif.get_tooloutput_file_path('SMTrain')
    tixi = cpsf.open_tixi(cpacs_path)

    filename = Tool.wkdir + '/Surrogate_Model_' + date

    cpsf.create_branch(tixi, SMFILE_XPATH)
    tixi.updateTextElement(SMFILE_XPATH, filename)
    cpsf.close_tixi(tixi, cpacs_out_path)

    Tool.df.to_csv(Tool.wkdir + '/Data_setup.csv', index=False, na_rep='-')

    Model = Surrogate_model()
    Model.df = Tool.df
    Model.sm = Tool.sm

    sm_file = open(filename, 'wb')

    pickle.dump(Model, sm_file)
示例#19
0
def create_routine_folder():
    """Create the working dicrectory of the routine.

    Create a folder in which all CEASIOMpy runs and routine parameters will be
    saved. This architecture may change in the future.

    Args:
        None.

    Returns:
        None.

    """
    global optim_dir_path, Rt

    # Create the main working directory
    tixi = cpsf.open_tixi(opf.CPACS_OPTIM_PATH)
    if tixi.checkElement(opf.WKDIR_XPATH):
        tixi.removeElement(opf.WKDIR_XPATH)
    wkdir = ceaf.get_wkdir_or_create_new(tixi)
    optim_dir_path = os.path.join(wkdir, Rt.type)
    Rt.date = wkdir[-19:]

    # Save the path to the directory in the CPACS
    if tixi.checkElement(opf.OPTWKDIR_XPATH):
        tixi.removeElement(opf.OPTWKDIR_XPATH)
    cpsf.create_branch(tixi, opf.OPTWKDIR_XPATH)
    tixi.updateTextElement(opf.OPTWKDIR_XPATH, optim_dir_path)

    # Add subdirectories
    if not os.path.isdir(optim_dir_path):
        os.mkdir(optim_dir_path)
    os.mkdir(optim_dir_path + '/Geometry')
    os.mkdir(optim_dir_path + '/Runs')

    cpsf.close_tixi(tixi, opf.CPACS_OPTIM_PATH)
示例#20
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)
示例#21
0
def get_engine_inputs(ui, ed, cpacs_in):
    """ Function to extract from the xml file the required input data,
        the code will use the default value when they are missing.

        INPUT
        (class) ui     --Arg.: UserInputs class.
        (class) ed     --Arg.: EngineData class.
        ##======= Class ares defined in the InputClasses folder =======##
        (char) cpacs_in  --Arg.: Relative location of the xml file in the
                                 ToolInput folder (cpacs option) or
                                 relative location of the temp. xml file in
                                 the ToolOutput folder (input option).
        OUTPUT
        (class) ed       --Out.: EngineData class.
        (file) cpacs_in  --Out.: Updated cpasc file
    """

    log.info('Starting engine data extraction from CPACS file')

    # Path creation ==========================================================
    tixi = cpf.open_tixi(cpacs_in)
    CEASIOM_PATH = '/cpacs/toolspecific/CEASIOMpy'

    PROP_PATH = CEASIOM_PATH + '/propulsion'
    tixi = cpf.create_branch(tixi, PROP_PATH, False)
    # Propulsion =============================================================
    if not tixi.checkElement(PROP_PATH + '/turboprop'):
        tixi = cpf.create_branch(tixi, PROP_PATH, False)
        tixi.createElement(PROP_PATH, 'turboprop')
        if ed.TURBOPROP:
            tixi.updateTextElement(PROP_PATH + '/turboprop', 'True')
        else:
            tixi.updateTextElement(PROP_PATH + '/turboprop', 'False')
    else:
        temp = tixi.getTextElement(PROP_PATH + '/turboprop')
        if temp == 'False':
            ed.TURBOPROP = False
        else:
            ed.TURBOPROP = True
    if not tixi.checkElement(PROP_PATH + '/auxiliaryPowerUnit'):
        tixi.createElement(PROP_PATH, 'auxiliaryPowerUnit')
        if ed.APU:
            tixi.updateTextElement(PROP_PATH + '/auxiliaryPowerUnit', 'True')
        else:
            tixi.updateTextElement(PROP_PATH + '/auxiliaryPowerUnit', 'False')
    else:
        temp = tixi.getTextElement(PROP_PATH + '/auxiliaryPowerUnit')
        if temp == 'False':
            ed.APU = False
        else:
            ed.APU = True
    if not tixi.checkElement(PROP_PATH + '/engineNumber'):
        tixi.createElement(PROP_PATH, 'engineNumber')
        tixi.updateIntegerElement(PROP_PATH + '/engineNumber', ed.NE, '%i')
    else:
        ed.NE = tixi.getIntegerElement(PROP_PATH + '/engineNumber')

    #Engines
    mp = []
    tp = []
    EN_PATH = '/cpacs/vehicles/engines'
    if tixi.checkElement(EN_PATH):
        for e in range(0,ed.NE-1):
            EN_PATH = '/cpacs/vehicles/engines'
            if ed.NE > 1:
                EN_PATH += '/engine' + str(e+1)
            else:
                EN_PATH += '/engine'
            if not tixi.checkElement(EN_PATH):
                raise Exception('Engine definition inclomplete, missing'\
                                + ' one or more engines in the cpacs file')
            if not tixi.checkElement(EN_PATH + '/name'):
                ed.EN_NAME.append('Engine_' + str(e+1))
                tixi.createElement(EN_PATH, 'name')
                tixi.updateTextElement(EN_PATH + '/name', ed.EN_NAME[e])
            else:
                if e > len(ed.EN_NAME):
                    ed.EN_NAME.append(tixi.getTextElement(EN_PATH + '/name'))
            ENA_PATH = EN_PATH + '/analysis/mass'
            if tixi.checkElement(ENA_PATH + '/mass'):
                ed.en_mass = tixi.getDoubleElement(ENA_PATH + '/mass')
                mp.append(ed.en_mass)
                if e>0 and ed.en_mass != mp[e-1]:
                    raise Exception('The engines have different masses, this'\
                                    + ' can lead to an unbalanced aircraft')
            elif ed.en_mass:
                tixi.createElement(ENA_PATH, 'mass')
                tixi.updateDoubleElement(ENA_PATH + '/mass', ed.en_mass, '%g')
            else:
                raise Exception('Engine definition inclomplete, missing'\
                                + ' engine mass in the cpacs file')
            ENT_PATH = EN_PATH + '/analysis'
            if tixi.checkElement(ENT_PATH + '/thrust00'):
                ed.max_thrust = tixi.getDoubleElement(ENT_PATH + '/thrust00')
                tp.append(ed.max_thrust)
                if e>0 and ed.max_thrust != tp[e-1]:
                    raise Exception('The engines have different thrust, this')
                                    #+ ' can lead to an unbalanced flight')
            elif ed.max_thrust:
                tixi.createElement(ENT_PATH, 'thrust00')
                tixi.updateDoubleElement(ENT_PATH + '/thrust00',
                                         ed.max_thrust, '%g')
            else:
                raise Exception('Engine definition inclomplete, missing'\
                                + ' engine thrust in the cpacs file')
    log.info('Data from CPACS file succesfully extracted')

    # Saving and closing the cpacs file --------------------------------------
    tixi.saveDocument(cpacs_in)
    cpf.close_tixi(tixi, cpacs_in)

    # Openign and closing again the cpacs file -------------------------------
    tixi = cpf.open_tixi(cpacs_in)
    tigl = cpf.open_tigl(tixi)
    tixi.saveDocument(cpacs_in)
    cpf.close_tixi(tixi, cpacs_in)

    return(ed)
示例#22
0
def get_user_inputs(ed, ui, adui, cpacs_in):
    """ Function to extract from the xml file the required input data,
        the code will use the default value when they are missing.

        INPUT
        (class) adui   --Arg.: AdvancedInputs class.
        (class) ed     --Arg.: EngineData class.
        (class) ui     --Arg.: UserInputs class.
        ##======= Classes are defined in the InputClasses folder =======##

        (char) cpacs_in  --Arg.: Relative location of the xml file in the
                                 ToolInput folder (cpacs option) or
                                 relative location of the temp. xml file in
                                 the ToolOutput folder (input option).
        OUTPUT
        (class) adui     --Out.: AdvancedInputs class updated
        (class) ui       --Out.: UserInputs class updated.
        (class) ed       --AOut.:EngineData class updated.
        (file) cpacs_in  --Out.: Updated cpasc file
    """

    log.info('Starting data extraction from CPACS file')
    # Path creation ==========================================================
    tixi = cpf.open_tixi(cpacs_in)
    # toolspecific
    CEASIOM_PATH = '/cpacs/toolspecific/CEASIOMpy'
    GEOM_PATH = CEASIOM_PATH + '/geometry'
    RANGE_PATH = CEASIOM_PATH + '/ranges'
    W_PATH = CEASIOM_PATH + '/weight'
    C_PATH = W_PATH + '/crew'
    PILOTS_PATH = C_PATH + '/pilots'
    CC_PATH = C_PATH + '/cabinCrewMembers'
    PASS_PATH = W_PATH + '/passengers'
    ML_PATH = W_PATH + '/massLimits'
    PROP_PATH = CEASIOM_PATH + '/propulsion'
    FUEL_PATH = '/cpacs/toolspecific/CEASIOMpy/fuels'

    tixi = cpf.create_branch(tixi, FUEL_PATH, False)
    tixi = cpf.create_branch(tixi, GEOM_PATH, False)
    tixi = cpf.create_branch(tixi, RANGE_PATH, False)
    tixi = cpf.create_branch(tixi, PILOTS_PATH, False)
    tixi = cpf.create_branch(tixi, CC_PATH, False)
    tixi = cpf.create_branch(tixi, PASS_PATH, False)
    tixi = cpf.create_branch(tixi, ML_PATH, False)
    tixi = cpf.create_branch(tixi, PROP_PATH, False)

    # cpacs/vehicles
    MC_PATH = '/cpacs/vehicles/aircraft/model/analyses/massBreakdown/'\
              + 'payload/mCargo/massDescription'
    F_PATH = '/cpacs/vehicles/fuels/fuel'

    tixi = cpf.create_branch(tixi, MC_PATH, False)
    tixi = cpf.create_branch(tixi, F_PATH, False)
    tixi = cpf.add_uid(tixi, F_PATH, 'kerosene')
    # Gathering data =========================================================
    # Geometry ===============================================================
    if not tixi.checkElement(GEOM_PATH + '/description'):
        tixi.createElement(GEOM_PATH, 'description')
        tixi.updateTextElement(GEOM_PATH + '/description', 'User '\
                               + 'geometry input')

    # Number of floors.
    if not tixi.checkElement(GEOM_PATH + '/floorsNb'):
        tixi.createElement(GEOM_PATH, 'floorsNb')
        tixi.updateDoubleElement(GEOM_PATH + '/floorsNb',\
                                 ui.FLOORS_NB, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/floorsNb')
        if temp != ui.FLOORS_NB and temp > 0:
            ui.FLOORS_NB = temp

    # Extracting fuselage material data.
    if not tixi.checkElement(GEOM_PATH + '/virtualThick'):
        tixi.createElement(GEOM_PATH, 'virtualThick')
        tixi.updateDoubleElement(GEOM_PATH + '/virtualThick',\
                                 adui.VRT_THICK, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/virtualThick')
        if temp != adui.VRT_THICK and temp > 0:
            adui.VRT_THICK = temp

    if not tixi.checkElement(GEOM_PATH + '/virtualDensity'):
        tixi.createElement(GEOM_PATH, 'virtualDensity')
        tixi.updateDoubleElement(GEOM_PATH + '/virtualDensity',\
                                 adui.VRT_STR_DENSITY, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/virtualDensity')
        if temp != adui.VRT_STR_DENSITY and temp > 0:
            adui.VRT_STR_DENSITY = temp

    if not tixi.checkElement(GEOM_PATH + '/cabinHeight'):
        tixi.createElement(GEOM_PATH, 'cabinHeight')
        tixi.updateDoubleElement(GEOM_PATH + '/cabinHeight',\
                                 ui.H_LIM_CABIN, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/cabinHeight')
        if temp != ui.H_LIM_CABIN and temp > 0:
            ui.H_LIM_CABIN = temp

    # People =================================================================
    # Pilots user input data
    if not tixi.checkElement(PILOTS_PATH + '/pilotNb'):
        tixi.createElement(PILOTS_PATH, 'pilotNb')
        tixi.updateIntegerElement(PILOTS_PATH + '/pilotNb',\
                                 adui.PILOT_NB, '%i')
    else:
        temp = tixi.getIntegerElement(PILOTS_PATH + '/pilotNb')
        if temp != adui.PILOT_NB and temp > 0:
            adui.PILOT_NB = temp

    if not tixi.checkElement(PILOTS_PATH + '/pilotMass'):
        tixi.createElement(PILOTS_PATH, 'pilotMass')
        tixi.updateDoubleElement(PILOTS_PATH + '/pilotMass',\
                                 adui.MASS_PILOT, '%g')
    else:
        temp = tixi.getDoubleElement(PILOTS_PATH + '/pilotMass')
        if temp != adui.MASS_PILOT and temp > 0:
            adui.MASS_PILOT = temp

    # Cabin crew user input data
    if not tixi.checkElement(CC_PATH + '/cabinCrewMemberMass'):
        tixi.createElement(CC_PATH, 'cabinCrewMemberMass')
        tixi.updateDoubleElement(CC_PATH + '/cabinCrewMemberMass',\
                                 adui.MASS_CABIN_CREW, '%g')
    else:
        temp = tixi.getDoubleElement(CC_PATH + '/cabinCrewMemberMass')
        if temp != adui.MASS_CABIN_CREW and temp > 0:
            adui.MASS_CABIN_CREW = temp

    # Passengers user input data
    if not tixi.checkElement(PASS_PATH + '/passMass'):
        tixi.createElement(PASS_PATH, 'passMass')
        tixi.updateDoubleElement(PASS_PATH + '/passMass',\
                                 adui.MASS_PASS, '%g')
    else:
        temp = tixi.getDoubleElement(PASS_PATH+ '/passMass')
        if temp != adui.MASS_PASS and temp > 0:
            adui.MASS_PASS = temp

    if tixi.checkElement(PASS_PATH + '/passNb'):
        temp = tixi.getIntegerElement(PASS_PATH+ '/passNb')
        if temp != ui.MAX_PASS and temp > 0:
            ui.MAX_PASS = temp

    if not tixi.checkElement(PASS_PATH + '/passDensity'):
        tixi.createElement(PASS_PATH, 'passDensity')
        tixi.updateDoubleElement(PASS_PATH + '/passDensity',\
                                 ui.PASS_BASE_DENSITY, '%i')
    else:
        temp = tixi.getDoubleElement(PASS_PATH + '/passDensity')
        if temp != ui.PASS_BASE_DENSITY and temp > 0:
            ui.PASS_BASE_DENSITY = temp

    if not tixi.checkElement(PASS_PATH + '/passPerToilet'):
        tixi.createElement(PASS_PATH, 'passPerToilet')
        tixi.updateIntegerElement(PASS_PATH + '/passPerToilet',\
                                 adui.PASS_PER_TOILET, '%i')
    else:
        temp = tixi.getIntegerElement(PASS_PATH + '/passPerToilet')
        if temp != adui.PASS_PER_TOILET and temp > 0:
            adui.PASS_PER_TOILET = temp

    # Fuel ===================================================================
    if not tixi.checkElement(F_PATH + '/density'):
        tixi.createElement(F_PATH, 'density')
        tixi.updateDoubleElement(F_PATH + '/density',\
                                 adui.FUEL_DENSITY, '%g')
    else:
        temp = tixi.getDoubleElement(F_PATH + '/density')
        if temp != adui.FUEL_DENSITY and temp > 0:
            adui.FUEL_DENSITY = temp

    if not tixi.checkElement(FUEL_PATH + '/resFuelPerc'):
        tixi.createElement(FUEL_PATH, 'resFuelPerc')
        tixi.updateDoubleElement(FUEL_PATH + '/resFuelPerc',\
                                 adui.RES_FUEL_PERC, '%g')
    else:
        temp = tixi.getDoubleElement(FUEL_PATH + '/resFuelPerc')
        if temp != adui.RES_FUEL_PERC and temp > 0:
            adui.RES_FUEL_PERC = temp

    # Weight =================================================================
    # Mass limits data
    if not tixi.checkElement(ML_PATH + '/description'):
        tixi.createElement(ML_PATH, 'description')
        tixi.updateTextElement(ML_PATH + '/description', 'Desired max fuel '\
                               + 'volume [m^3] and payload mass [kg]')
    if not tixi.checkElement(ML_PATH + '/maxPayload'):
        tixi.createElement(ML_PATH, 'maxPayload')
        tixi.updateDoubleElement(ML_PATH + '/maxPayload',\
                                 ui.MAX_PAYLOAD, '%g')
    else:
        temp = tixi.getDoubleElement(ML_PATH + '/maxPayload')
        if temp != ui.MAX_PAYLOAD and temp != 0:
            ui.MAX_PAYLOAD = temp
    if not tixi.checkElement(ML_PATH + '/maxFuelVol'):
        tixi.createElement(ML_PATH, 'maxFuelVol')
        tixi.updateDoubleElement(ML_PATH + '/maxFuelVol',\
                                 ui.MAX_FUEL_VOL, '%g')
    else:
        temp = tixi.getDoubleElement(ML_PATH + '/maxFuelVol')
        if temp != ui.MAX_FUEL_VOL and temp != 0:
            ui.MAX_FUEL_VOL = temp

    if tixi.checkElement(MC_PATH + '/massCargo'):
        temp = tixi.getDoubleElement(MC_PATH + '/massCargo')
        if temp != ui.MASS_CARGO and temp != 0:
            ui.MASS_CARGO = temp
        # If the cargo mass is defined in the UserInputs class will be added
        # in the CPACS file after the analysis.

    # Flight =================================================================
    if not tixi.checkElement(RANGE_PATH + '/lDRatio'):
        tixi.createElement(RANGE_PATH, 'lDRatio')
        tixi.updateDoubleElement(RANGE_PATH + '/lDRatio',\
                                  ui.LD, '%g')
    else:
        temp = tixi.getIntegerElement(RANGE_PATH + '/lDRatio')
        if temp != ui.LD and temp > 0:
            ui.LD = temp

    if not tixi.checkElement(RANGE_PATH + '/cruiseSpeed'):
        tixi.createElement(RANGE_PATH, 'cruiseSpeed')
        tixi.updateDoubleElement(RANGE_PATH + '/cruiseSpeed',\
                                 ui.CRUISE_SPEED, '%g')
    else:
        temp = tixi.getIntegerElement(RANGE_PATH + '/cruiseSpeed')
        if temp != ui.CRUISE_SPEED and temp > 0:
            ui.CRUISE_SPEED = temp

    TSFC_PATH = PROP_PATH + '/tSFC'
    tixi = cpf.create_branch(tixi, TSFC_PATH, False)
    if not tixi.checkElement(TSFC_PATH + '/tsfcCruise'):
        tixi.createElement(TSFC_PATH, 'tsfcCruise')
        tixi.updateDoubleElement(TSFC_PATH + '/tsfcCruise',\
                                 ed.TSFC_CRUISE, '%g')
    else:
        temp = tixi.getDoubleElement(TSFC_PATH + '/tsfcCruise')
        if temp != ed.TSFC_CRUISE and temp > 0:
            ed.TSFC_CRUISE = temp

    if not tixi.checkElement(PROP_PATH + '/userEngineOption'):
        tixi.createElement(PROP_PATH, 'userEngineOption')
        if ui.USER_ENGINES:
            tixi.updateTextElement(PROP_PATH + '/userEngineOption', 'True')
        else:
            tixi.updateTextElement(PROP_PATH + '/userEngineOption', 'False')
    else:
        temp = tixi.getTextElement(PROP_PATH + '/userEngineOption')
        if temp == 'False':
            ui.USER_ENGINES = False
        else:
            ui.USER_ENGINES = True

    if not tixi.checkElement(PROP_PATH + '/singleHydraulics'):
        tixi.createElement(PROP_PATH, 'singleHydraulics')
        if adui.SINGLE_HYDRAULICS:
            tixi.updateTextElement(PROP_PATH + '/singleHydraulics', 'True')
        else:
            tixi.updateTextElement(PROP_PATH + '/singleHydraulics', 'False')
    else:
        temp = tixi.getTextElement(PROP_PATH + '/singleHydraulics')
        if temp == 'False':
            adui.SINGLE_HYDRAULICS = False
        else:
            adui.SINGLE_HYDRAULICS = True

    log.info('Data from CPACS file succesfully extracted')

    # Saving and closing the cpacs file --------------------------------------
    tixi.saveDocument(cpacs_in)
    cpf.close_tixi(tixi, cpacs_in)

    # Openign and closing again the cpacs file -------------------------------
    tixi = cpf.open_tixi(cpacs_in)
    tigl = cpf.open_tigl(tixi)
    tixi.saveDocument(cpacs_in)
    cpf.close_tixi(tixi, cpacs_in)

    return(ed, ui, adui)
def cpacs_mbd_update(out, mw, bi, ms_zpm, out_xml):
    """ The function updates the cpacs file after the Balance
        unconventional program.

        INPUT
        (float) mass_pass   --Arg.: Passenger mass, countig also the
                                          extra mass.
        (class) out         --Arg.: BalanceOutput class.
        (class) mw          --Arg.: MassesWeights class.
        (class) bi          --Arg.: BalanceInput class.
        ##======= Classes are defined in the InputClasses folder =======##
        (cahr) out_xml      --Arg.: Path of the output file.


        OUTPUT
        (file) cpacs.xml --Out.: Updated cpacs file.
    """
    tixi = cpf.open_tixi(out_xml)
    tigl = cpf.open_tigl(tixi)

    # CREATING PATH ==========================================================
    MB_PATH = '/cpacs/vehicles/aircraft/'\
                          + 'model/analyses/massBreakdown'

    MD_PATH = MB_PATH + '/designMasses'
    MTOM_PATH = MD_PATH + '/mTOM'

    MZFM_PATH = MD_PATH + '/mZFM'

    OEM_PATH = MB_PATH + '/mOEM/massDescription'
    J_PATH = OEM_PATH + '/massInertia/J'
    CG_PATH = OEM_PATH + '/location/'

    tixi = cpf.create_branch(tixi, MTOM_PATH + '/location/x', False)
    tixi = cpf.create_branch(tixi, MTOM_PATH + '/location/y', False)
    tixi = cpf.create_branch(tixi, MTOM_PATH + '/location/z', False)
    tixi = cpf.create_branch(tixi, MTOM_PATH + '/massInertia/Jxx', False)
    tixi = cpf.create_branch(tixi, MTOM_PATH + '/massInertia/Jyy', False)
    tixi = cpf.create_branch(tixi, MTOM_PATH + '/massInertia/Jzz', False)
    tixi = cpf.create_branch(tixi, MTOM_PATH + '/massInertia/Jxy', False)
    tixi = cpf.create_branch(tixi, MTOM_PATH + '/massInertia/Jyz', False)
    tixi = cpf.create_branch(tixi, MTOM_PATH + '/massInertia/Jxz', False)

    tixi = cpf.create_branch(tixi, MZFM_PATH + '/location/x', False)
    tixi = cpf.create_branch(tixi, MZFM_PATH + '/location/y', False)
    tixi = cpf.create_branch(tixi, MZFM_PATH + '/location/z', False)
    tixi = cpf.create_branch(tixi, MZFM_PATH + '/massInertia/Jxx', False)
    tixi = cpf.create_branch(tixi, MZFM_PATH + '/massInertia/Jyy', False)
    tixi = cpf.create_branch(tixi, MZFM_PATH + '/massInertia/Jzz', False)
    tixi = cpf.create_branch(tixi, MZFM_PATH + '/massInertia/Jxy', False)
    tixi = cpf.create_branch(tixi, MZFM_PATH + '/massInertia/Jyz', False)
    tixi = cpf.create_branch(tixi, MZFM_PATH + '/massInertia/Jxz', False)

    tixi = cpf.create_branch(tixi, OEM_PATH + '/location/x', False)
    tixi = cpf.create_branch(tixi, OEM_PATH + '/location/y', False)
    tixi = cpf.create_branch(tixi, OEM_PATH + '/location/z', False)
    tixi = cpf.create_branch(tixi, OEM_PATH + '/massInertia/Jxx', False)
    tixi = cpf.create_branch(tixi, OEM_PATH + '/massInertia/Jyy', False)
    tixi = cpf.create_branch(tixi, OEM_PATH + '/massInertia/Jzz', False)
    tixi = cpf.create_branch(tixi, OEM_PATH + '/massInertia/Jxy', False)
    tixi = cpf.create_branch(tixi, OEM_PATH + '/massInertia/Jyz', False)
    tixi = cpf.create_branch(tixi, OEM_PATH + '/massInertia/Jxz', False)

    # DESIGN MASSES ==========================================================
    # MTOM -------------------------------------------------------------------
    tixi.uIDSetToXPath(MTOM_PATH + '/location', 'MTOMloc')

    tixi.updateDoubleElement(MTOM_PATH + '/location'+'/x',\
                             out.center_of_gravity[0], '%g')
    tixi.updateDoubleElement(MTOM_PATH + '/location'+'/y',\
                             out.center_of_gravity[1], '%g')
    tixi.updateDoubleElement(MTOM_PATH + '/location'+'/z',\
                             out.center_of_gravity[2], '%g')

    tixi.updateDoubleElement(MTOM_PATH + '/massInertia' + '/Jxx',\
                             out.Ixx_lump, '%g')
    tixi.updateDoubleElement(MTOM_PATH + '/massInertia' + '/Jyy',\
                             out.Iyy_lump,'%g')
    tixi.updateDoubleElement(MTOM_PATH + '/massInertia' + '/Jzz',\
                             out.Izz_lump, '%g')
    tixi.updateDoubleElement(MTOM_PATH + '/massInertia' + '/Jxy',\
                             out.Ixy_lump, '%g')
    tixi.updateDoubleElement(MTOM_PATH + '/massInertia' + '/Jyz',\
                             out.Iyz_lump,'%g')
    tixi.updateDoubleElement(MTOM_PATH + '/massInertia' + '/Jxz',\
                             out.Ixz_lump, '%g')

    # MZFM -------------------------------------------------------------------
    tixi = cpf.add_uid(tixi, MZFM_PATH + '/location', 'MZFMloc')

    # updating path
    tixi.updateDoubleElement(MZFM_PATH + '/location' + '/x',\
                             out.cg_zpm[0], '%g')
    tixi.updateDoubleElement(MZFM_PATH + '/location' + '/y',\
                             out.cg_zpm[1], '%g')
    tixi.updateDoubleElement(MZFM_PATH + '/location' + '/z',\
                             out.cg_zpm[2], '%g')

    tixi.updateDoubleElement(MZFM_PATH + '/massInertia'\
                             + '/Jxx', out.Ixx_lump_zfm, '%g')
    tixi.updateDoubleElement(MZFM_PATH + '/massInertia'\
                             + '/Jyy', out.Iyy_lump_zfm, '%g')
    tixi.updateDoubleElement(MZFM_PATH + '/massInertia'\
                             + '/Jzz', out.Izz_lump_zfm, '%g')
    tixi.updateDoubleElement(MZFM_PATH + '/massInertia'\
                             + '/Jxy', out.Ixy_lump_zfm, '%g')
    tixi.updateDoubleElement(MZFM_PATH + '/massInertia'\
                             + '/Jyz', out.Iyz_lump_zfm, '%g')
    tixi.updateDoubleElement(MZFM_PATH + '/massInertia'\
                             + '/Jxz', out.Ixz_lump_zfm, '%g')

    # OEM ====================================================================
    tixi = cpf.add_uid(tixi, OEM_PATH + '/location', 'OEMloc')

    tixi.updateDoubleElement((CG_PATH + 'x'), out.cg_oem[0], '%g')
    tixi.updateDoubleElement((CG_PATH + 'y'), out.cg_oem[1], '%g')
    tixi.updateDoubleElement((CG_PATH + 'z'), out.cg_oem[2], '%g')
    tixi.updateDoubleElement((J_PATH + 'xx'), out.Ixx_lump_oem, '%g')
    tixi.updateDoubleElement((J_PATH + 'yy'), out.Iyy_lump_oem, '%g')
    tixi.updateDoubleElement((J_PATH + 'zz'), out.Izz_lump_oem, '%g')
    tixi.updateDoubleElement((J_PATH + 'xy'), out.Ixy_lump_oem, '%g')
    tixi.updateDoubleElement((J_PATH + 'yz'), out.Iyz_lump_oem, '%g')
    tixi.updateDoubleElement((J_PATH + 'xz'), out.Ixz_lump_oem, '%g')

    # ZPM INERTIA ============================================================
    B_PATH = '/cpacs/toolspecific/CEASIOMpy/balance'
    ZPM_PATH = B_PATH + '/mZPM'
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/name', False)
    tixi.updateTextElement(ZPM_PATH + '/name', 'Maximum zero payload mass')
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/description', False)
    tixi.updateTextElement(ZPM_PATH + '/description', 'Maximum '\
                           + 'zero payload mass [kg], CoG coordinate [m] and '\
                           + 'moment of inertia.')
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/mass', False)
    tixi.updateDoubleElement(ZPM_PATH + '/mass',\
                             ms_zpm, '%g')

    tixi = cpf.create_branch(tixi, ZPM_PATH + '/location/x', False)
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/location/y', False)
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/location/z', False)
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/massInertia/Jxx', False)
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/massInertia/Jyy', False)
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/massInertia/Jzz', False)
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/massInertia/Jxy', False)
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/massInertia/Jyz', False)
    tixi = cpf.create_branch(tixi, ZPM_PATH + '/massInertia/Jxz', False)

    LOC_PATH = ZPM_PATH + '/location'
    MOI_PATH = ZPM_PATH + '/massInertia'

    tixi = cpf.add_uid(tixi, ZPM_PATH, 'MZPM')
    tixi = cpf.add_uid(tixi, LOC_PATH, 'MZPMloc')
    tixi.updateDoubleElement((LOC_PATH + '/x'), out.cg_zpm[0], '%g')
    tixi.updateDoubleElement((LOC_PATH + '/y'), out.cg_zpm[1], '%g')
    tixi.updateDoubleElement((LOC_PATH + '/z'), out.cg_zpm[2], '%g')
    tixi.updateDoubleElement((MOI_PATH + '/Jxx'), out.Ixx_lump_zpm, '%g')
    tixi.updateDoubleElement((MOI_PATH + '/Jyy'), out.Iyy_lump_zpm, '%g')
    tixi.updateDoubleElement((MOI_PATH + '/Jzz'), out.Izz_lump_zpm, '%g')
    tixi.updateDoubleElement((MOI_PATH + '/Jxy'), out.Ixy_lump_zpm, '%g')
    tixi.updateDoubleElement((MOI_PATH + '/Jyz'), out.Iyz_lump_zpm, '%g')
    tixi.updateDoubleElement((MOI_PATH + '/Jxz'), out.Ixz_lump_zpm, '%g')

    # USER CASE ==============================================================
    if bi.USER_CASE:
        UC_PATH = '/cpacs/toolspecific/CEASIOMpy/balance/userBalance'
        LOC_PATH = UC_PATH + '/location'
        MOI_PATH = UC_PATH + '/massInertia'

        tixi = cpf.create_branch(tixi, LOC_PATH + '/x', False)
        tixi = cpf.create_branch(tixi, LOC_PATH + '/y', False)
        tixi = cpf.create_branch(tixi, LOC_PATH + '/z', False)
        tixi = cpf.create_branch(tixi, MOI_PATH + '/Jxx', False)
        tixi = cpf.create_branch(tixi, MOI_PATH + '/Jyy', False)
        tixi = cpf.create_branch(tixi, MOI_PATH + '/Jzz', False)
        tixi = cpf.create_branch(tixi, MOI_PATH + '/Jxy', False)
        tixi = cpf.create_branch(tixi, MOI_PATH + '/Jyz', False)
        tixi = cpf.create_branch(tixi, MOI_PATH + '/Jxz', False)

        tixi = cpf.add_uid(tixi, LOC_PATH, 'USERloc')
        tixi.updateDoubleElement((LOC_PATH + '/x'), out.cg_user[0], '%g')
        tixi.updateDoubleElement((LOC_PATH + '/y'), out.cg_user[1], '%g')
        tixi.updateDoubleElement((LOC_PATH + '/z'), out.cg_user[2], '%g')
        tixi.updateDoubleElement((MOI_PATH + '/Jxx'), out.Ixx_lump_user, '%g')
        tixi.updateDoubleElement((MOI_PATH + '/Jyy'), out.Iyy_lump_user, '%g')
        tixi.updateDoubleElement((MOI_PATH + '/Jzz'), out.Izz_lump_user, '%g')
        tixi.updateDoubleElement((MOI_PATH + '/Jxy'), out.Ixy_lump_user, '%g')
        tixi.updateDoubleElement((MOI_PATH + '/Jyz'), out.Iyz_lump_user, '%g')
        tixi.updateDoubleElement((MOI_PATH + '/Jxz'), out.Ixz_lump_user, '%g')

    # Saving and closing the new cpacs file inside the ToolOutput folder -----
    tixi.saveDocument(out_xml)
    cpf.close_tixi(tixi, out_xml)

    # Openign and closing again the cpacs file, formatting purpose -----------
    tixi = cpf.open_tixi(out_xml)
    tigl = cpf.open_tigl(tixi)
    tixi.saveDocument(out_xml)
    cpf.close_tixi(tixi, out_xml)

    return ()
示例#24
0
def plot_aero_coef(cpacs_path, cpacs_out_path):
    """Plot Aero coefficients from the chosen aeroMap in the CPACS file

    Function 'plot_aero_coef' can plot one or several aeromap from the CPACS
    file according to some user option, these option will be shown in the the
    SettingGUI or default values will be used.

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

    # Open TIXI handle
    tixi = cpsf.open_tixi(cpacs_path)
    aircraft_name = cpsf.aircraft_name(tixi)

    # Get aeroMap list to plot
    aeromap_to_plot_xpath = PLOT_XPATH + '/aeroMapToPlot'
    aeromap_uid_list = []

    # Option to select aeromap manualy
    manual_selct = cpsf.get_value_or_default(tixi,
                                             PLOT_XPATH + '/manualSelection',
                                             False)
    if manual_selct:
        aeromap_uid_list = call_select_aeromap(tixi)
        cpsf.create_branch(tixi, aeromap_to_plot_xpath)
        cpsf.add_string_vector(tixi, aeromap_to_plot_xpath, aeromap_uid_list)

    else:
        try:
            aeromap_uid_list = cpsf.get_string_vector(tixi,
                                                      aeromap_to_plot_xpath)
        except:
            # If aeroMapToPlot is not define, select manualy anyway
            aeromap_uid_list = call_select_aeromap(tixi)
            cpsf.create_branch(tixi, aeromap_to_plot_xpath)
            cpsf.add_string_vector(tixi, aeromap_to_plot_xpath,
                                   aeromap_uid_list)

    # Create DataFrame from aeromap(s)
    aeromap_df_list = []
    for aeromap_uid in aeromap_uid_list:
        aeromap_df = apmf.get_datafram_aeromap(tixi, aeromap_uid)
        aeromap_df['uid'] = aeromap_uid
        aeromap_df_list.append(aeromap_df)

    aeromap = pd.concat(aeromap_df_list, ignore_index=True)

    if len(aeromap_uid_list) > 1:
        uid_crit = None
    else:
        uid_crit = aeromap_uid_list[0]

    # Default options
    title = aircraft_name
    criterion = pd.Series([True] * len(aeromap.index))
    groupby_list = ['uid', 'mach', 'alt', 'aos']

    # Get criterion from CPACS
    crit_xpath = PLOT_XPATH + '/criterion'
    alt_crit = cpsf.get_value_or_default(tixi, crit_xpath + '/alt', 'None')
    mach_crit = cpsf.get_value_or_default(tixi, crit_xpath + '/mach', 'None')
    aos_crit = cpsf.get_value_or_default(tixi, crit_xpath + '/aos', 'None')

    cpsf.close_tixi(tixi, cpacs_out_path)

    # Modify criterion and title according to user option
    if len(aeromap['alt'].unique()) == 1:
        title += ' - Alt = ' + str(aeromap['alt'].loc[0])
        groupby_list.remove('alt')
    elif alt_crit not in NONE_LIST:
        criterion = criterion & (aeromap.alt == alt_crit)
        title += ' - Alt = ' + str(alt_crit)
        groupby_list.remove('alt')

    if len(aeromap['mach'].unique()) == 1:
        title += ' - Mach = ' + str(aeromap['mach'].loc[0])
        groupby_list.remove('mach')
    elif mach_crit not in NONE_LIST:
        criterion = criterion & (aeromap.mach == mach_crit)
        title += ' - Mach = ' + str(mach_crit)
        groupby_list.remove('mach')

    if len(aeromap['aos'].unique()) == 1:
        title += ' - AoS = ' + str(aeromap['aos'].loc[0])
        groupby_list.remove('aos')
    elif aos_crit not in NONE_LIST:
        criterion = criterion & (aeromap.aos == aos_crit)
        title += ' - AoS = ' + str(aos_crit)
        groupby_list.remove('aos')

    if uid_crit is not None and len(groupby_list) > 1:
        criterion = criterion & (aeromap.uid == uid_crit)
        title += ' - ' + uid_crit
        groupby_list.remove('uid')

    # Plot settings
    fig, axs = plt.subplots(2, 3)
    fig.suptitle(title, fontsize=14)
    fig.set_figheight(8)
    fig.set_figwidth(15)
    fig.subplots_adjust(left=0.06)
    axs[0, 1].axhline(y=0.0, color='k', linestyle='-')  # Line at Cm=0

    # Plot aerodynamic coerfficients
    for value, grp in aeromap.loc[criterion].groupby(groupby_list):

        legend = write_legend(groupby_list, value)

        axs[0, 0].plot(grp['aoa'], grp['cl'], 'x-', label=legend)
        axs[1, 0].plot(grp['aoa'], grp['cd'], 'x-')
        axs[0, 1].plot(grp['aoa'], grp['cms'], 'x-')
        axs[1, 1].plot(grp['aoa'], grp['cl'] / grp['cd'], 'x-')
        axs[0, 2].plot(grp['cd'], grp['cl'], 'x-')
        axs[1, 2].plot(grp['cl'], grp['cl'] / grp['cd'], 'x-')

    # Set subplot options
    subplot_options(axs[0, 0], 'CL', 'AoA')
    subplot_options(axs[1, 0], 'CD', 'AoA')
    subplot_options(axs[0, 1], 'Cm', 'AoA')
    subplot_options(axs[1, 1], 'CL/CD', 'AoA')
    subplot_options(axs[0, 2], 'CL', 'CD')
    subplot_options(axs[1, 2], 'CL/CD', 'CL')

    fig.legend(loc='upper right')
    plt.show()
示例#25
0
def create_SU2_mesh(cpacs_path, cpacs_out_path):
    """ Function to create a simple SU2 mesh form an SUMO file (.smx)

    Function 'create_mesh' is used to generate an unstructured mesh with  SUMO
    (which integrage Tetgen for the volume mesh) using a SUMO (.smx) geometry
    file as input.
    Meshing option could be change manually (only in the script for now)

    Source :
        * sumo help, tetgen help (in the folder /doc)

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

    """

    tixi = cpsf.open_tixi(cpacs_path)

    wkdir = ceaf.get_wkdir_or_create_new(tixi)
    sumo_dir = os.path.join(wkdir, 'SUMO')
    if not os.path.isdir(sumo_dir):
        os.mkdir(sumo_dir)
    su2_mesh_path = os.path.join(sumo_dir, 'ToolOutput.su2')

    meshdir = os.path.join(wkdir, 'MESH')
    if not os.path.isdir(meshdir):
        os.mkdir(meshdir)

    original_dir = os.getcwd()
    os.chdir(sumo_dir)

    sumo_file_xpath = '/cpacs/toolspecific/CEASIOMpy/filesPath/sumoFilePath'
    sumo_file_path = cpsf.get_value_or_default(tixi, sumo_file_xpath, '')
    if sumo_file_path == '':
        raise ValueError('No SUMO file to use to create a mesh')

    # Set mesh parameters
    log.info('Mesh parameter will be set')
    refine_level_xpath = '/cpacs/toolspecific/CEASIOMpy/mesh/sumoOptions/refinementLevel'
    refine_level = cpsf.get_value_or_default(tixi, refine_level_xpath, 0.0)
    log.info('Refinement level is {}'.format(refine_level))
    add_mesh_parameters(sumo_file_path, refine_level)

    # Check current Operating System
    current_os = platform.system()

    if current_os == 'Darwin':
        log.info('Your OS is Mac\n\n')
        log.info(
            '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
        log.info('On MacOS the mesh has to be generated manually.')
        log.info('To create a SU2Mesh you have to :')
        log.info('Open the .smx geometry that you will find there:')
        log.info(sumo_file_path)
        log.info('Click on the button "Mesh"')
        log.info('Click on "Create Mesh"')
        log.info('Click on "Volume Mesh"')
        log.info('Click on "Run"')
        log.info('When the mesh generation is completed, click on "Close"')
        log.info('Go to the Menu "Mesh" -> "Save volume mesh..."')
        log.info('Chose "SU2 (*.su2)" as File Type"')
        log.info('Copy/Paste the following line as File Name')
        log.info(su2_mesh_path)
        log.info('Click on "Save"')
        log.info('You can now close SUMO, your workflow will continue.')
        log.info(
            'More information: https://ceasiompy.readthedocs.io/en/latest/user_guide/modules/SUMOAutoMesh/index.html'
        )
        log.info(
            '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n'
        )

        # For now, I did not find a way to run "sumo -batch" on Mac...
        # The command just open SUMO GUI, the mesh has to be generate and save manually
        command = ['open', '/Applications/SUMO/dwfsumo.app/']
        os.system(' '.join(command))

    elif current_os == 'Linux':
        log.info('Your OS is Linux')

        # Check if SUMO is installed
        soft_dict = ceaf.get_install_path(['sumo'])

        # Run SUMO in batch
        output = '-output=su2'
        options = '-tetgen-options=pq1.16VY'  # See Tetgen help for more options, maybe transform that as an input
        # Command line to run: sumo -batch -output=su2 -tetgen-options=pq1.16VY ToolOutput.smx
        command = [
            soft_dict['sumo'], '-batch', output, options, sumo_file_path
        ]
        os.system(' '.join(command))

    elif current_os == 'Windows':
        log.info('Your OS is Windows')
        # TODO: develop this part

        log.warning('OS not supported yet by SUMOAutoMesh!')
        raise OSError('OS not supported yet!')

    else:
        raise OSError('OS not recognize!')

    # Copy the mesh in the MESH directory
    aircraft_name = cpsf.aircraft_name(tixi)
    su2_mesh_name = aircraft_name + '_baseline.su2'
    su2_mesh_new_path = os.path.join(meshdir, su2_mesh_name)
    shutil.copyfile(su2_mesh_path, su2_mesh_new_path)

    if os.path.isfile(su2_mesh_new_path):
        log.info('An SU2 Mesh has been correctly generated.')
        su2_mesh_xpath = '/cpacs/toolspecific/CEASIOMpy/filesPath/su2Mesh'
        cpsf.create_branch(tixi, su2_mesh_xpath)
        tixi.updateTextElement(su2_mesh_xpath, su2_mesh_new_path)
        os.remove(su2_mesh_path)

    else:
        raise ValueError('No SU2 Mesh file has been generated!')

    cpsf.close_tixi(tixi, cpacs_out_path)
    os.chdir(original_dir)
示例#26
0
def save_aero_coef(tixi,apm_xpath,Coef):
    """ Get aerodynamic coefficients from SU2 resutls

    Function 'get_su2_aero_coef' ....TODO

    Source :
        * ...CPACS Documentation?

    Args:
        tixi (handles): TIXI Handle of the CPACS file
        apm_xpath (str): XPath to the aeroMap to fill
        Coef (object): Object containing aerodynamic coefficients

    Returns::
        tixi (handles): Modified Handle of the CPACS file
    """

    create_branch(tixi,apm_xpath+'/cl')
    tixi.updateDoubleElement(apm_xpath+'/cl',Coef.cl,'%g')

    create_branch(tixi,apm_xpath+'/cd')
    tixi.updateDoubleElement(apm_xpath+'/cd',Coef.cd,'%g')

    create_branch(tixi,apm_xpath+'/cs')
    tixi.updateDoubleElement(apm_xpath+'/cs',Coef.cs,'%g')

    create_branch(tixi,apm_xpath+'/cml')
    tixi.updateDoubleElement(apm_xpath+'/cml',Coef.cml,'%g')

    create_branch(tixi,apm_xpath+'/cmd')
    tixi.updateDoubleElement(apm_xpath+'/cmd',Coef.cmd,'%g')

    create_branch(tixi,apm_xpath+'/cms')
    tixi.updateDoubleElement(apm_xpath+'/cms',Coef.cms,'%g')

    return tixi


# def merge_aeroPerfomanceMap(aeromap1_uid,aeromap2_uid,aeromap_new_uid):
    """ Merge two existing aeroPerformanceMap into a new one """

# def add_point(alt,mach,aoa,aos)
    """ Add a calculation point to an existing aeroPerformanceMap """

# def add_points(alt_list,mach_list,aoa_list,aos_list)
    """ Add a calculation point to an existing aeroPerformanceMap """

# def add_coefficient(alt,mach,aoa,aos,cl,cd,cs): ???
    """ Add a calculation point to an existing aeroPerformanceMap """
示例#27
0
def cpacs_weight_update(out, mw, out_xml):
    """ The function updates the cpacs file after the Weight analysis.

        INPUT
        (class) out         --Arg.: WeightOutput class.
        (class) mw          --Arg.: MassesWeights class.
        (char) out_xml      --Arg.: Path of the output file.
        ##======= Classes are defined in the classes folder =======##

        OUTPUT
        (file) cpacs.xml --Out.: Updated cpacs file.
    """
    tixi = cpf.open_tixi(out_xml)
    tigl = cpf.open_tigl(tixi)

    # Path creation ==========================================================
    MB_PATH = '/cpacs/vehicles/aircraft/model/analyses/massBreakdown'
    if tixi.checkElement(MB_PATH):
        tixi.removeElement(MB_PATH)

    MD_PATH = MB_PATH + '/designMasses'
    MTOM_PATH = MD_PATH + '/mTOM'
    MZFM_PATH = MD_PATH + '/mZFM'
    MF_PATH = MB_PATH + '/fuel/massDescription'
    OEM_PATH = MB_PATH + '/mOEM/massDescription'
    PAY_PATH = MB_PATH + '/payload/massDescription'
    MC_PATH = MB_PATH + '/payload/mCargo'
    OIM_PATH = MB_PATH + '/mOEM/mOperatorItems/mCrewMembers'\
               + '/massDescription'

    tixi = cpf.create_branch(tixi, MTOM_PATH + '/mass', False)
    tixi = cpf.create_branch(tixi, MZFM_PATH + '/mass', False)
    tixi = cpf.create_branch(tixi, MF_PATH + '/mass', False)
    tixi = cpf.create_branch(tixi, OEM_PATH + '/mass', False)
    tixi = cpf.create_branch(tixi, PAY_PATH + '/mass', False)
    tixi = cpf.create_branch(tixi, MC_PATH, False)
    tixi = cpf.create_branch(tixi, OIM_PATH + '/mass', False)

    # DESIGN MASSES ==========================================================
    tixi = cpf.add_uid(tixi, MTOM_PATH, 'MTOM')
    tixi.createElement(MTOM_PATH, 'name')
    tixi.updateTextElement(MTOM_PATH + '/name', 'Maximum take-off mass')
    tixi.createElement(MTOM_PATH, 'description')
    tixi.updateTextElement(MTOM_PATH + '/description', 'Maximum '\
                           + 'take off mass [kg], CoG coordinate [m] and '\
                           + 'moment of inertia.')
    tixi.updateDoubleElement(MTOM_PATH + '/mass',\
                             mw.maximum_take_off_mass, '%g')

    # MZFM -------------------------------------------------------------------
    tixi = cpf.add_uid(tixi, MZFM_PATH, 'MZFM')
    tixi.createElement(MZFM_PATH, 'name')
    tixi.updateTextElement(MZFM_PATH + '/name', 'Maximum zero fuel mass')
    tixi.createElement(MZFM_PATH, 'description')
    tixi.updateTextElement(MZFM_PATH + '/description', 'Maximum '\
                           + 'zero fuel mass [kg] and corresponding CoG '\
                           + 'coordinate [m], moment of inertia.')
    tixi.updateDoubleElement(MZFM_PATH + '/mass', mw.zero_fuel_mass, '%g')


    # FUEL MASS ==============================================================
    tixi = cpf.add_uid(tixi, MF_PATH, 'MFM')
    tixi.createElement(MF_PATH, 'name')
    tixi.updateTextElement(MF_PATH + '/name', 'Max fuel mass')
    tixi.createElement(MF_PATH, 'description')
    tixi.updateTextElement(MF_PATH + '/description', 'Maximum '\
                           + 'fuel mass [kg].')
    tixi.updateDoubleElement(MF_PATH + '/mass', mw.mass_fuel_max, '%g')

    # OEM ====================================================================
    tixi = cpf.add_uid(tixi, OEM_PATH, 'OEM')
    tixi.createElement(OEM_PATH, 'name')
    tixi.updateTextElement(OEM_PATH + '/name', 'Operating empty mass')
    tixi.createElement(OEM_PATH, 'description')
    tixi.updateTextElement(OEM_PATH + '/description', 'Operating empty'\
                           + ' mass [kg] and related inertia [kgm^2].')
    tixi.updateDoubleElement(OEM_PATH + '/mass', mw.operating_empty_mass, '%g')

    tixi.updateDoubleElement(OIM_PATH + '/mass', mw.mass_crew, '%g')
    tixi = cpf.add_uid(tixi, OIM_PATH, 'massCrew')

    # PAYLOAD MASS AND FUEL WITH MAX PAYLOAD =================================
    tixi = cpf.add_uid(tixi, PAY_PATH, 'MPM')
    tixi.createElement(PAY_PATH, 'name')
    tixi.updateTextElement(PAY_PATH + '/name', 'Max payload mass')
    tixi.createElement(PAY_PATH, 'description')
    tixi.updateTextElement(PAY_PATH + '/description', 'Maximum '\
                           + 'payload mass [kg].')
    tixi.updateDoubleElement(PAY_PATH + '/mass', mw.mass_payload, '%g')

    if mw.mass_cargo:
        tixi.createElement(MC_PATH, 'massCargo')
        tixi.updateDoubleElement(MC_PATH + '/massCargo', mw.mass_cargo, '%g')
    # Saving and closing the new cpacs file inside the ToolOutput folder -----
    tixi.saveDocument(out_xml)
    cpf.close_tixi(tixi, out_xml)

    # Openign and closing again the cpacs file, formatting purpose -----------
    tixi = cpf.open_tixi(out_xml)
    tigl = cpf.open_tigl(tixi)
    tixi.saveDocument(out_xml)
    cpf.close_tixi(tixi, out_xml)

    return()
示例#28
0
def get_data(ui, bi, mw, ed, cpacs_in):
    """ The function extracts from the xml file the required input data,
        the code will use the default value when they are missing.

        INPUT
        (class) ui       --Arg.: UserInputs class.
        (class) bi       --Arg.: BalanceInputs class.
        (class) mw       --Arg.: MassesWeight class.
        (class) ed       --Arg.: EngineData class.
        ##======= Classes are defined in the InputClasses folder =======##

        (char) cpacs_in  --Arg.: Relative location of the xml file in the
                                 ToolInput folder (cpacs option) or
                                 relative location of the temp. xml file in
                                 the ToolOutput folder (input option).
        OUTPUT
        (class) mw       --Out.: MassesWeight class updated.
        (class) ed       --Out.: EngineData class updated.
        (file) cpacs_in  --Out.: Updated cpasc file.
    """
    log.info('CPACS file path check')

    # path definition ========================================================
    # Opening CPACS file
    tixi = open_tixi(cpacs_in)

    TSPEC_PATH = '/cpacs/toolspecific/CEASIOMpy'

    GEOM_PATH = TSPEC_PATH + '/geometry'
    FMP_PATH = TSPEC_PATH + '/weight/passengers/fuelMassMaxpass/mass'
    PROP_PATH = TSPEC_PATH + '/propulsion'

    MASS_PATH = '/cpacs/vehicles/aircraft/model/analyses/massBreakdown'
    MTOM_PATH = MASS_PATH + '/designMasses/mTOM/mass'
    F_PATH = MASS_PATH + '/fuel/massDescription/mass'
    OEM_PATH = MASS_PATH + '/mOEM/massDescription/mass'
    PAY_PATH = MASS_PATH + '/payload/massDescription/mass'

    EN_PATH = '/cpacs/vehicles/engines/engine1/analysis/mass/mass'

    BC_PATH = TSPEC_PATH + '/balance/userBalance'
    create_branch(tixi, BC_PATH, False)
    # Compulsory path checks =================================================

    if not tixi.checkElement(TSPEC_PATH):
        raise Exception('Missing required toolspecific path. Run '\
                        + 'Weight_unc_main.py,'\
                        + ' in the 4Weight_unc_module folder.')
    elif not tixi.checkElement(MASS_PATH):
        raise Exception('Missing required massBreakdown path. Run '\
                        + 'Weight_unc_main.py,'\
                        + ' in the 4Weight_unc_module folder.')
    elif not tixi.checkElement(MTOM_PATH):
        raise Exception('Missing required mTOM/mass path. Run '\
                        + 'Weight_unc_main.py,'\
                        + ' in the 4Weight_unc_module folder.')
    elif not tixi.checkElement(FMP_PATH):
        raise Exception('Missing required fuelMassMaxpass/mass path. Run '\
                        + 'Weight_unc_main.py,'\
                        + ' in the 4Weight_unc_module folder.')
    elif not tixi.checkElement(OEM_PATH):
        raise Exception('Missing required mOEM/massDescription/mass '\
                        + 'path. Run Weight_unc_main.py,'\
                        + ' in the 4Weight_unc_module folder.')
    elif not tixi.checkElement(PAY_PATH):
        raise Exception('Missing required payload/massDescription/mass '\
                        + 'path. Run Weight_unc_main.py,'\
                        + ' in the 4Weight_unc_module folder.')
    elif not tixi.checkElement(F_PATH):
        raise Exception('Missing required /fuel/massDescription/mass '\
                        + 'path. Run Weight_unc_main.py,'\
                        + ' in the 4Weight_unc_module folder.')
    elif not tixi.checkElement(EN_PATH):
        raise Exception('Missing required /cpacs/vehicles/engines/engine1'\
                        + '/analysis/mass path. Run Weight_unc_main.py,'\
                        + ' in the 4Weight_unc_module folder.')
    else:
        log.info('All path correctly defined in the toolinput.xml file, '\
                 + 'beginning data extracction.')

    # Gathering data =========================================================
    ## Geometry Data

    if not tixi.checkElement(GEOM_PATH + '/floorsNb'):
        tixi.createElement(GEOM_PATH, 'floorsNb')
        tixi.updateDoubleElement(GEOM_PATH + '/floorsNb',\
                                 ui.FLOORS_NB, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/floorsNb')
        if temp != ui.FLOORS_NB and temp > 0:
            ui.FLOORS_NB = temp

    if not tixi.checkElement(GEOM_PATH + '/cabinHeight'):
        tixi.createElement(GEOM_PATH, 'cabinHeight')
        tixi.updateDoubleElement(GEOM_PATH + '/cabinHeight',\
                                 ui.H_LIM_CABIN, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/cabinHeight')
        if temp != ui.H_LIM_CABIN and temp > 0:
            ui.H_LIM_CABIN = temp

    ## User Case Balance
    if not tixi.checkElement(BC_PATH + '/userCase'):
        tixi.createElement(BC_PATH, 'userCase')
        if bi.USER_CASE:
            tixi.updateTextElement(BC_PATH + '/userCase', 'True')
        else:
            tixi.updateTextElement(BC_PATH + '/userCase', 'False')
    else:
        temp = tixi.getTextElement(BC_PATH + '/userCase')
        if temp == 'False':
            bi.USER_CASE = False
        else:
            bi.USER_CASE = True

    if bi.USER_CASE:
        if tixi.checkElement(BC_PATH + '/fuelPercentage'):
            bi.F_PERC = tixi.getDoubleElement(BC_PATH + '/fuelPercentage')
        elif bi.F_PERC:
            tixi.createElement(BC_PATH, 'fuelPercentage')
            tixi.updateDoubleElement(BC_PATH + '/fuelPercentage',\
                                     bi.F_PERC, '%g')
        else:
            raise Exception('User balance option defined'\
                            + ' True but no fuel percentage data in the'\
                            + ' CPACS file or in th BalanceInput class.')
        if tixi.checkElement(BC_PATH + '/payloadPercentage'):
            bi.P_PERC = tixi.getDoubleElement(BC_PATH + '/payloadPercentage')
        elif bi.P_PERC:
            tixi.createElement(BC_PATH, 'payloadPercentage')
            tixi.updateDoubleElement(BC_PATH + '/payloadPercentage',\
                                     bi.P_PERC, '%g')
        else:
            raise Exception('User balance option defined'\
                            + ' True but no payload percentage data in'\
                            + ' the CPACS file or in th BalanceInput class.')
    ## Engines Data
    ed.en_mass = tixi.getDoubleElement(EN_PATH)

    if not tixi.checkElement(PROP_PATH + '/wingMountedEngine'):
        create_branch(tixi, PROP_PATH, False)
        tixi.createElement(PROP_PATH, 'wingMountedEngine')
        if ed.WING_MOUNTED:
            tixi.updateTextElement(PROP_PATH + '/wingMountedEngine', 'True')
        else:
            tixi.updateTextElement(PROP_PATH + '/wingMountedEngine', 'False')
    else:
        temp = tixi.getTextElement(PROP_PATH + '/wingMountedEngine')
        if temp == 'False':
            ed.WING_MOUNTED = False
        else:
            ed.WING_MOUNTED = True

    if not tixi.checkElement(PROP_PATH + '/userEnginePlacement'):
        tixi.createElement(PROP_PATH, 'userEnginePlacement')
        if bi.USER_EN_PLACEMENT:
            tixi.updateTextElement(PROP_PATH + '/userEnginePlacement', 'True')
        else:
            tixi.updateTextElement(PROP_PATH + '/userEnginePlacement', 'False')
    else:
        temp = tixi.getTextElement(PROP_PATH + '/userEnginePlacement')
        if temp == 'False':
            bi.USER_EN_PLACEMENT = False
        else:
            bi.USER_EN_PLACEMENT = True

    if not tixi.checkElement(PROP_PATH + '/engineNumber'):
        create_branch(tixi, PROP_PATH, False)
        tixi.createElement(PROP_PATH, 'engineNumber')
        tixi.updateIntegerElement(PROP_PATH + '/engineNumber', ed.NE, '%i')
    else:
        ed.NE = tixi.getIntegerElement(PROP_PATH + '/engineNumber')

    ## User Engine Placement
    tp = []
    ed.EN_NAME = []
    if tixi.checkElement(EN_PATH):
        for e in range(0, ed.NE):
            EN_PATH = '/cpacs/vehicles/engines'
            if ed.NE > 1:
                EN_PATH += '/engine' + str(e + 1)
            else:
                EN_PATH += '/engine'
            if not tixi.checkElement(EN_PATH):
                raise Exception('Engine definition inclomplete, missing'\
                                + ' one or more engines in the cpacs file')
            if not tixi.checkElement(EN_PATH + '/name'):
                ed.EN_NAME.append('Engine_' + str(e + 1))
            else:
                ed.EN_NAME.append(tixi.getTextElement(EN_PATH + '/name'))
            ENA_PATH = EN_PATH + '/analysis/mass'
            if tixi.checkElement(ENA_PATH):
                ed.en_mass = tixi.getDoubleElement(ENA_PATH + '/mass')
                tp.append(ed.en_mass)
                if e > 0 and ed.en_mass != tp[e - 1]:
                    log.warning('The engines have different masses,'\
                                + 'this can lead to an unbalanced aircraft')
            elif ed.en_mass:
                tixi.createElement(ENA_PATH, 'mass')
                tixi.updateDoubleElement(ENA_PATH + '/mass', ed.en_mass, '%g')
            else:
                raise Exception('Engine definition inclomplete, missing'\
                                + ' engine mass in the cpacs file')

    s = np.shape(ed.EN_PLACEMENT)
    warn = False
    if not ed.NE:
        raise Exception('No engine defined for the aircraft')
    elif s[0] < ed.NE or s[1] < 3 or np.any(ed.EN_PLACEMENT) == False:
        warn = True
    else:
        log.info('EngineData class defined correctly.')

    s = ed.EN_PLACEMENT
    if bi.USER_EN_PLACEMENT:
        ed.EN_PLACEMENT = []
        for e in range(1, ed.NE + 1):
            if ed.NE > 1:
                ENLOC_PATH = '/cpacs/vehicles/engines/engine' + str(
                    e) + '/analysis/mass/location'
            else:
                ENLOC_PATH = '/cpacs/vehicles/engines/engine/analysis/mass/location'
            if not tixi.checkElement(ENLOC_PATH) and warn:
                raise Exception('User engine Placement option defined'\
                                + ' True but no engine placement data in the'\
                                + ' CPACS file.')
            if not tixi.checkElement(ENLOC_PATH) and not warn:
                create_branch(tixi, ENLOC_PATH, False)
                tixi.createElement(ENLOC_PATH, 'x')
                tixi.createElement(ENLOC_PATH, 'y')
                tixi.createElement(ENLOC_PATH, 'z')
                tixi.updateDoubleElement(ENLOC_PATH + '/x', s[e - 1][0], '%g')
                tixi.updateDoubleElement(ENLOC_PATH + '/y', s[e - 1][1], '%g')
                tixi.updateDoubleElement(ENLOC_PATH + '/z', s[e - 1][2], '%g')
                ed.EN_PLACEMENT.append([s[e - 1][0], s[e - 1][1], s[e - 1][2]])
            else:
                x = tixi.getDoubleElement(ENLOC_PATH + '/x')
                y = tixi.getDoubleElement(ENLOC_PATH + '/y')
                z = tixi.getDoubleElement(ENLOC_PATH + '/z')
                ed.EN_PLACEMENT.append([x, y, z])
        ed.EN_PLACEMENT = np.array(ed.EN_PLACEMENT)

    ## REQUIRED TOOLSPECIFIC DATA ============================================
    # Fuel
    mw.mass_fuel_maxpass = tixi.getDoubleElement(FMP_PATH)

    ## REQUIRED MASSBREAKDOWN DATA ===========================================

    mw.maximum_take_off_mass = tixi.getDoubleElement(MTOM_PATH)
    mw.operating_empty_mass = tixi.getDoubleElement(OEM_PATH)
    mw.mass_payload = tixi.getDoubleElement(PAY_PATH)
    mw.mass_fuel_tot = tixi.getDoubleElement(F_PATH)

    log.info('Data from CPACS file succesfully extracted')

    # # Saving and closing the cpacs file ======================================
    # tixi.saveDocument(cpacs_in)
    # close_tixi(tixi, cpacs_in)
    #
    # # Openign and closing again the cpacs file ===============================
    # tixi = open_tixi(cpacs_in)
    # tigl = open_tigl(tixi)
    # tixi.saveDocument(cpacs_in)
    close_tixi(tixi, cpacs_in)

    return (mw, ed)
示例#29
0
def get_user_fuel(fus_nb, ui, cpacs_in):
    """ Function to extract from the xml file the required input data,
        the code will use the default value when they are missing.

        INPUT
        (int) fus_nb     --Arg.: Number of fuselage.
        (class) ui     --Arg.: UserInputs class.
        ##======= Classes are defined in the InputClasses folder =======##

        (char) cpacs_in  --Arg.: Relative location of the xml file in the
                                 ToolInput folder (cpacs option) or
                                 relative location of the temp. xml file in
                                 the ToolOutput folder (input option).
        OUTPUT
        (class) ui       --Out.: UserInputs class.
        (file) cpacs_in  --Out.: Updated cpasc file
    """

    log.info('Starting data extraction from CPACS file')

    # Path creation ==========================================================
    tixi = open_tixi(cpacs_in)
    FUEL_PATH = '/cpacs/toolspecific/CEASIOMpy/fuels'
    create_branch(tixi, FUEL_PATH, False)

    if fus_nb:
        for i in range(0, fus_nb):
            if fus_nb > 1:
                F = 'fuelOnCabin' + str(i + 1)
            else:
                F = 'fuelOnCabin'
            if not tixi.checkElement(FUEL_PATH + '/' + F):
                tixi.createElement(FUEL_PATH, F)
                tixi.updateDoubleElement(FUEL_PATH + '/' + F,\
                                         ui.F_FUEL[i], '%g')
            else:
                ui.F_FUEL[i] = tixi.getDoubleElement(FUEL_PATH + '/' + F)
    else:
        if not tixi.checkElement(FUEL_PATH + '/fuelOnCabin'):
            tixi.createElement(FUEL_PATH, 'fuelOnCabin')
        tixi.updateDoubleElement(FUEL_PATH + '/fuelOnCabin', ui.FUEL_ON_CABIN,
                                 '%g')

        # Modif Aidan: this code seems useless
        # else:
        #     temp = tixi.updateDoubleElement(FUEL_PATH + '/fuelOnCabin',\
        #                                     ui.FUEL_ON_CABIN, '%g')
        #     if temp != ui.FUEL_ON_CABIN and temp > 0:
        #         ui.FUEL_ON_CABIN = temp

    log.info('Data from CPACS file succesfully extracted')
    # # Saving and closing the cpacs file --------------------------------------
    # tixi.saveDocument(cpacs_in)
    # close_tixi(tixi, cpacs_in)
    #
    # # Openign and closing again the cpacs file -------------------------------
    # tixi = open_tixi(cpacs_in)
    # tigl = open_tigl(tixi)
    # tixi.saveDocument(cpacs_in)
    close_tixi(tixi, cpacs_in)

    return (ui)
示例#30
0
def create_config(cpacs_path, cpacs_out_path, su2_mesh_path,
                  config_output_path):
    """ Function to create configuration file for SU2 calculation

    Function 'create_config' create an SU2 configuration file from SU2 mesh data
    (marker) and CPACS file specific related parameter (/toolSpecific).
    For all other infomation the value from the default SU2 configuration file
    are used. A new configuration file will be saved in
    /ToolOutput/ToolOutput.cfg

    Source:
       * SU2 configuration file  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
        su2_mesh_path (str): Path to SU2 mesh
        config_output_path (str): Path to the output configuration file

    """

    DEFAULT_CONFIG_PATH = MODULE_DIR + '/files/DefaultConfig_v6.cfg'

    # Get value from CPACS
    tixi = open_tixi(cpacs_path)

    su2_xpath = '/cpacs/toolspecific/CEASIOMpy/aerodynamics/su2'

    # Reference values
    ref_xpath = '/cpacs/vehicles/aircraft/model/reference'
    ref_len = get_value(tixi, ref_xpath + '/length')
    ref_area = get_value(tixi, ref_xpath + '/area')

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

    if fixed_cl == 'NO':
        # Get value from the aeroMap (1 point)
        active_aeroMap_xpath = su2_xpath + '/aeroMapUID'
        aeroMap_uid = get_value(tixi, active_aeroMap_xpath)
        aeroMap_path = tixi.uIDGetXPath(aeroMap_uid)
        apm_path = aeroMap_path + '/aeroPerformanceMap'

        #State = get_states(tixi,apm_path)

        #alt = State.alt_list
        alt = get_value(tixi, apm_path + '/altitude')
        mach = get_value(tixi, apm_path + '/machNumber')
        aoa = get_value(tixi, apm_path + '/angleOfAttack')
        aos = get_value(tixi, apm_path + '/angleOfSideslip')

    else:
        range_xpath = '/cpacs/toolspecific/CEASIOMpy/ranges'
        cruise_alt_xpath = range_xpath + '/cruiseAltitude'
        cruise_mach_xpath = range_xpath + '/cruiseMach'

        # value corresponding to fix CL calulation
        aoa = 0.0  # Will not be used
        aos = 0.0
        tixi, mach = get_value_or_default(tixi, cruise_mach_xpath, 0.78)
        tixi, alt = get_value_or_default(tixi, cruise_alt_xpath, 12000)

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

    # Settings
    settings_xpath = '/cpacs/toolspecific/CEASIOMpy/aerodynamics/su2/settings'
    max_iter_xpath = settings_xpath + '/maxIter'
    cfl_nb_xpath = settings_xpath + '/cflNumber'
    mg_level_xpath = settings_xpath + '/multigridLevel'

    tixi, max_iter = get_value_or_default(tixi, max_iter_xpath, 200)
    tixi, cfl_nb = get_value_or_default(tixi, cfl_nb_xpath, 1.0)
    tixi, mg_level = get_value_or_default(tixi, mg_level_xpath, 3)

    # Mesh Marker
    bc_wall_xpath = '/cpacs/toolspecific/CEASIOMpy/aerodynamics/su2/boundaryConditions/wall'

    bc_wall_list = get_mesh_marker(su2_mesh_path)
    tixi = create_branch(tixi, bc_wall_xpath)
    bc_wall_str = ';'.join(bc_wall_list)
    tixi.updateTextElement(bc_wall_xpath, bc_wall_str)

    close_tixi(tixi, cpacs_out_path)

    # Open default configuration file
    try:
        config_file_object = open(DEFAULT_CONFIG_PATH, 'r')
        config_file_lines = config_file_object.readlines()
        config_file_object.close()
        log.info('Default configuration file has been found and read')
    except Exception:
        log.exception('Problem to open or read default configuration file')

    # Create a dictionary with all the parameters from the default config file
    config_dict = {}
    for line in config_file_lines:
        if '=' in line:
            (key, val) = line.split('=')
            if val.endswith('\n'):
                val = val[:-1]
            config_dict[key] = val

    config_dict_modif = config_dict

    # General parmeters
    config_dict_modif['MESH_FILENAME'] = su2_mesh_path

    config_dict_modif['REF_LENGTH'] = ref_len
    config_dict_modif['REF_AREA'] = ref_area

    # Settings
    config_dict_modif['EXT_ITER'] = int(max_iter)
    config_dict_modif['CFL_NUMBER'] = cfl_nb
    config_dict_modif['MGLEVEL'] = int(mg_level)

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

    # If calculation at CL fix (AOA will not be taken into account)
    config_dict_modif['FIXED_CL_MODE'] = fixed_cl
    config_dict_modif['TARGET_CL'] = target_cl
    config_dict_modif['DCL_DALPHA'] = '0.1'
    config_dict_modif['UPDATE_ALPHA'] = '8'
    config_dict_modif['ITER_DCL_DALPHA'] = '80'

    # Mesh Marker
    bc_wall_str = '(' + ','.join(bc_wall_list) + ')'
    config_dict_modif['MARKER_EULER'] = bc_wall_str
    config_dict_modif['MARKER_FAR'] = ' (Farfield)'
    config_dict_modif['MARKER_SYM'] = ' (0)'
    config_dict_modif['MARKER_PLOTTING'] = bc_wall_str
    config_dict_modif['MARKER_MONITORING'] = bc_wall_str
    config_dict_modif['MARKER_MOVING'] = bc_wall_str

    # Change value if needed or add new parameters in the config file
    for key, value in config_dict_modif.items():
        line_nb = 0
        # Double loop! There is probably a possibility to do something better.
        for i, line in enumerate(config_file_lines):
            if '=' in line:
                (key_def, val_def) = line.split('=')
                if key == key_def:
                    line_nb = i
                    break
        if not line_nb:
            config_file_lines.append(str(key) + ' = ' + str(value) + '\n')
        else:
            if val_def != config_dict_modif[key]:
                config_file_lines[line_nb] = str(key) + ' = ' \
                                           + str(config_dict_modif[key]) + '\n'

    config_file_new = open(config_output_path, 'w')
    config_file_new.writelines(config_file_lines)
    config_file_new.close()
    log.info('ToolOutput.cfg has been written in /ToolOutput.')