Пример #1
0
def check_cpacs_input_requirements(cpacs_file, cpacs_inout, module_file_name):
    """
    Check if the input CPACS file contains the required nodes
    """

    # log = get_logger(module_file_name.split('.')[0])

    required_inputs = cpacs_inout.inputs
    tixi = open_tixi(cpacs_file)

    missing_nodes = []
    for entry in required_inputs:
        if entry.default_value is not None:
            continue
        if tixi.checkElement(entry.cpacs_path) is False:
            missing_nodes.append(entry.cpacs_path)

    if missing_nodes:
        missing_str = ''
        for missing in missing_nodes:
            missing_str += '==> ' + missing + '\n'

        msg = f"CPACS path required but does not exist\n{missing_str}"
        # log.error(msg)
        raise CPACSRequirementError(msg)
Пример #2
0
def extract_am_data(Tool):
    """Get training data from aeromap.

    Retrieve training dataset from an aeromap. The inputs are [alt, mach, aoa, aos]
    parameters and the outputs are [cl, cd, cs, cml, cmd, cms].

    Args:
        Tool (Prediction_tool): Class containing the user specification.

    Returns:
        xd (4*m numpy array): Set of m points in the 4-dimensionnal design space.
        yd (6*m numpy array): Set of m points in the 6-dimensionnal result space.

    """

    cpacs_path = mif.get_toolinput_file_path('SMTrain')
    tixi = cpsf.open_tixi(cpacs_path)

    Tool.df = gen_df_from_am(tixi)

    Aeromap = apmf.get_aeromap(tixi, Tool.aeromap_uid)
    xd = np.array([Aeromap.alt, Aeromap.mach, Aeromap.aoa, Aeromap.aos])
    yd = np.array([
        Aeromap.cl, Aeromap.cd, Aeromap.cs, Aeromap.cml, Aeromap.cmd,
        Aeromap.cms
    ])

    cpsf.close_tixi(tixi, cpacs_path)

    return xd.transpose(), yd.transpose()
Пример #3
0
def test_aeromap_from_csv():
    """Test the function 'aeromap_from_csv'"""

    tixi = open_tixi(CPACS_IN_PATH)

    aeromap_uid = 'test_aeromap'
    csv_path = os.path.join(MODULE_DIR, 'ToolInput', 'Aeromap_test.csv')
    aeromap_from_csv(tixi, aeromap_uid, csv_path)

    AeroCoef = get_aeromap(tixi, aeromap_uid)

    assert AeroCoef.get_count() == 24

    for i in range(12):
        assert AeroCoef.alt[i] == 0
    for j in range(12, 24):
        print(i)
        assert AeroCoef.alt[j] == 12000

    # Is is useful to test all the value?

# def test_check_aeromap():
    """ Test the function 'check_aeromap'"""

    # def test_get_aeromap ():
    """ Test the function 'get_aeromap'"""

    # def test_save_parameters():
    """ Test the function 'save_parameters'"""

    # def test_save_coefficients():
    """ Test the function 'save_coefficients'"""
Пример #4
0
def test_get_value():
    """Test the function 'get_value'"""

    tixi = cpsf.open_tixi(CPACS_IN_PATH)

    # Check if the correct value (float) is return from an xpath
    xpath = '/cpacs/vehicles/aircraft/model/reference/area'
    value = cpsf.get_value(tixi, xpath)
    assert value == 1.0

    # Check if the correct value (text) is return from an xpath
    xpath = '/cpacs/vehicles/aircraft/model/name'
    value = cpsf.get_value(tixi, xpath)
    assert value == 'Cpacs2Test'

    # Check if boolean are returned from an xpath or default value
    xpath = '/cpacs/toolspecific/testUtils/testCPACSFunctions/testBoolTrue'
    value = cpsf.get_value(tixi, xpath)
    assert value == True

    xpath = '/cpacs/toolspecific/testUtils/testCPACSFunctions/testBoolFalse'
    value = cpsf.get_value(tixi, xpath)
    assert value == False

    # Check if a false xpath raises ValueError
    xpath = '/cpacs/vehicles/aircraft/model/reference/aarreeaa'
    with pytest.raises(ValueError):
        value_error = cpsf.get_value(tixi, xpath)

    # Check if no value in the field raises ValueError
    xpath = '/cpacs/vehicles/aircraft/model'
    with pytest.raises(ValueError):
        value_text = cpsf.get_value(tixi, xpath)
Пример #5
0
def create_xml(cpacs_out, NAME):
    """ Function that creates a copy of the cpacs file, inside the ToolInput
        folder, into the ToolOutput folder

        INPUT
        (char) cpacs_out --Arg.: Relative location of the xml file in the
                                 ToolOutput folder.
        (char) NAME      --Arg.: Aircraft Name.

        OUTPUT
        (char) out_xml    --Out.: Relative location of the xml file in the
                                  ToolOutut folder.
    """

    root = ET.Element('cpacs')
    head = ET.SubElement(root, 'header')
    cp1 = ET.SubElement(head, 'cpacsVersion').text = '3.0'
    name = ET.SubElement(head, 'name').text = NAME
    ups = ET.SubElement(head, 'updates')
    up = ET.SubElement(ups, 'update')
    cp2 = ET.SubElement(up, 'cpacsVersion').text = '3.0'
    veh = ET.SubElement(root, 'vehicles')
    air = ET.SubElement(veh, 'aircraft')
    mod = ET.SubElement(air, 'model')

    tree = ET.ElementTree(root)
    tree.write(cpacs_out)
    tixi = cpf.open_tixi(cpacs_out)
    tixi.saveDocument(cpacs_out)
    cpf.close_tixi(tixi, cpacs_out)

    return (cpacs_out)
    def get_inside_dim(self, cpacs_path):
        """ Get user input from the CPACS file

        The function 'get_inside_dim' extracts from the CPACS file the required
        aircraft inside dimension, the code will use the default value when they are
        missing.

        Args:
            cpacs_path (str): Path to CPACS file

        """

        tixi = open_tixi(cpacs_path)

        # Get inside dimension from the CPACS file if exit
        self.seat_width = get_value_or_default(tixi, GEOM_XPATH + '/seatWidth',
                                               0.525)
        self.seat_length = get_value_or_default(tixi,
                                                GEOM_XPATH + '/seatLength',
                                                self.seat_length)
        self.aisle_width = get_value_or_default(tixi,
                                                GEOM_XPATH + '/aisleWidth',
                                                0.42)
        self.fuse_thick = get_value_or_default(tixi, GEOM_XPATH + '/fuseThick',
                                               6.63)
        self.toilet_length = get_value_or_default(tixi,
                                                  GEOM_XPATH + '/toiletLength',
                                                  self.toilet_length)

        close_tixi(tixi, cpacs_path)
Пример #7
0
    def __init__(self, master, cpacs_path, cpacs_out_path, submodule_list, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)
        self.pack(fill=tk.BOTH)

        self.submodule_list = submodule_list
        self.cpacs_out_path = cpacs_out_path

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

        self.tixi = cpsf.open_tixi(cpacs_path)

        if len(apm.get_aeromap_uid_list(self.tixi)) == 0 :
            aeromap_uid = 'AeroMap_1point'
            csv_path = os.path.join(MODULE_DIR,'..','..','test','AeroMaps','Aeromap_1point.csv')
            apm.aeromap_from_csv(self.tixi, aeromap_uid, csv_path)

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

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

        # General button
        self.update_button = tk.Button(self, text='Update', command=self._update_all)
        self.update_button.grid(row=1, column=1,sticky='E')
        self.close_button = tk.Button(self, text='Save & Quit', command=self._save_quit)
        self.close_button.grid(row=1, column=2,sticky='W')
Пример #8
0
def get_number_of_parts(cpacs_in):
    """ The fuction counts the number of fuselage and wings.

        INPUT
        (char) cpacs_in     --Arg.: Relative position of the xml file.

        OUTPUT
        (int) f_nb          --Out.: Number of fuselages.
        (int) W_nb          --Out.: Number of wings.

    """
    # Opening tixi and tigl
    tixi = cpf.open_tixi(cpacs_in)

    if not tixi.checkElement('/cpacs/vehicles/aircraft\
                             /model/fuselages'):
        f_nb = 0
    else:
        f_nb = tixi.getNamedChildrenCount(
            '/cpacs/vehicles/aircraft\
                                          /model/fuselages', 'fuselage')
    if not tixi.checkElement('/cpacs/vehicles/aircraft\
                             /model/wings'):
        w_nb = 0
    else:
        w_nb = tixi.getNamedChildrenCount(
            '/cpacs/vehicles/aircraft\
                                          /model/wings', 'wing')
    cpf.close_tixi(tixi, cpacs_in)

    return (f_nb, w_nb)
Пример #9
0
def test_copy_branch():
    """Test the function 'copy_branch'"""

    tixi_handle = 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]'
    tixi = create_branch(tixi_handle, xpath_new, True)
    tixi = 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_handle.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_handle.getTextAttribute(xpath_elem_from, 'uID')
    attrib_text_to = tixi.getTextAttribute(xpath_elem_to, 'uID')

    assert attrib_text_from == attrib_text_to
Пример #10
0
    def get_user_inputs(self, cpacs_path):
        """Take user inputs from the GUI."""
        tixi = cpsf.open_tixi(CPACS_OPTIM_PATH)

        # Problem setup
        objectives = cpsf.get_value_or_default(tixi, OPTIM_XPATH + 'objective',
                                               'cl')
        self.objective = objectives.split(';')
        self.minmax = cpsf.get_value_or_default(tixi, OPTIM_XPATH + 'minmax',
                                                'max')

        # Global parameters
        self.driver = cpsf.get_value_or_default(
            tixi, OPTIM_XPATH + 'parameters/driver', 'COBYLA')
        self.max_iter = int(
            cpsf.get_value_or_default(tixi, OPTIM_XPATH + 'iterationNB', 200))
        self.tol = float(
            cpsf.get_value_or_default(tixi, OPTIM_XPATH + 'tolerance', 1e-3))
        self.save_iter = int(
            cpsf.get_value_or_default(tixi, OPTIM_XPATH + 'saving/perIter', 1))

        # Specific DoE parameters
        self.doedriver = cpsf.get_value_or_default(
            tixi, OPTIM_XPATH + 'parameters/DoE/driver', 'uniform')
        self.samplesnb = int(
            cpsf.get_value_or_default(tixi,
                                      OPTIM_XPATH + 'parameters/DoE/sampleNB',
                                      3))

        # User specified configuration file path
        self.user_config = cpsf.get_value_or_default(
            tixi, OPTIM_XPATH + 'Config/filepath',
            '../Optimisation/Default_config.csv')

        cpsf.close_tixi(tixi, CPACS_OPTIM_PATH)
Пример #11
0
def test_estimate_skin_friction_coef():
    """Test function 'estimate_skin_friction_coef' """

    # Test 1
    wetted_area = 1
    wing_area = 1
    wing_span = 1
    mach = 1
    alt = 1

    cd0 = estimate_skin_friction_coef(wetted_area, wing_area, wing_span, mach,
                                      alt)

    assert cd0 == approx(0.005320707210958961)

    # Test 2, with "real values"
    tixi = open_tixi(CPACS_IN_PATH)
    tigl = open_tigl(tixi)
    analysis_xpath = '/cpacs/toolspecific/CEASIOMpy/geometry/analysis'
    wetted_area = get_value(tixi, analysis_xpath + '/wettedArea')
    wing_area, wing_span = get_largest_wing_dim(tixi, tigl)
    mach = 0.78
    alt = 12000

    cd0 = estimate_skin_friction_coef(wetted_area, wing_area, wing_span, mach,
                                      alt)

    assert cd0 == approx(0.01998328842386761)
def transformer(input_file, output_file='output_cpacs.xml', geometry_dict={}):
    """Transforms a CPACS aircraft geometry by rescaling individual sections

    Parameters
    ----------
    input_file : str
        The location of the CPACS file
    output_file : str
        The name of the output file (default output_cpacs.xml)
    geometry_dict : dict
        A dictionary of aircraft geometry parameters with the values
            that the output CPACS file should have
        dict keywords: fuselage_length, wing_span
    """

    fuse_length_change = geometry_dict.get('fuse_length', 'None')

    name = aircraft_name(input_file)
    ag = geometry.geometry_eval(input_file, name)
    fuse_length = ag.fuse_length[0]
    scale = fuse_length_change / fuse_length

    tixi_handle = open_tixi(input_file)
    tixi_handle = section_transformer(tixi_handle, scale, ag.fuse_sec_nb[0])
    tixi_handle = positioning_transformer(tixi_handle, scale)
    close_tixi(tixi_handle, output_file)
    return 'done'
Пример #13
0
def test_add_uid():
    """Test the function 'add_uid'"""

    tixi = cpsf.open_tixi(CPACS_IN_PATH)

    # Update UID
    xpath = '/cpacs/vehicles/aircraft/model'
    new_uid = 'New_aircrat_name'
    cpsf.add_uid(tixi, xpath, new_uid)
    updated_uid = tixi.getTextAttribute(xpath, 'uID')

    assert updated_uid == new_uid

    # Add UID
    xpath = '/cpacs/vehicles/aircraft/model/name'
    new_uid = 'nameUID'
    cpsf.add_uid(tixi, xpath, new_uid)
    added_uid = tixi.getTextAttribute(xpath, 'uID')

    assert added_uid == new_uid

    # Add existing UID (should add "1" at the end of the UID)
    xpath = '/cpacs/vehicles/aircraft/model/name'
    new_uid = 'SimpleFuselage'
    cpsf.add_uid(tixi, xpath, new_uid)
    added_uid = tixi.getTextAttribute(xpath, 'uID')

    assert added_uid == 'SimpleFuselage1'
Пример #14
0
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()
Пример #15
0
def update_cpacs_file(cpacs_path, cpacs_out_path, optim_var_dict):
    """Function to update a CPACS file with value from the optimiser

    This function sets the new values of the design variables given by
    the routine driver to the CPACS file, using the Tigl and Tixi handler.

    Source:
        * See CPACSCreator api function,

    Args:
        cpacs_path (str): Path to CPACS file to update
        cpacs_out_path (str):Path to the updated CPACS file
        optim_var_dict (dict): Dictionary containing all the variable
                               value/min/max and command to modify a CPACS file

    """

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

    aircraft = get_aircraft(tigl)
    # help(aircraft)

    wings = aircraft.get_wings()
    # help(wings)

    fuselage = aircraft.get_fuselages().get_fuselage(1)
    # help(fuselage)

    # Other functions which could be useful

    # help(wings.get_wing(1).get_section(1))
    # uid = wings.get_wing(1).get_section(2).get_uid()
    # help(wings.get_wing(1).get_positioning_transformation(uid))
    # wings.get_wing(1).get_section(2).set_rotation(geometry.CTiglPoint(40,40,-4))
    # airfoil = wings.get_wing(1).get_section(1).get_section_element(1).get_airfoil_uid()
    # help(airfoil)
    # wings.get_wing(1).get_section(1).get_section_element(1).set_airfoil_uid('NACA0006')
    # scal = wings.get_wing(1).get_section(1).get_section_element(1).get_scaling()
    # help(wings.get_wing(1).get_section(2))

    # Perform update of all the variable contained in 'optim_var_dict'
    for name, (val_type, listval, minval, maxval, getcommand, setcommand) in optim_var_dict.items():
        if val_type == 'des' and listval[0] not in ['-', 'True', 'False']:
            if setcommand not in ['-', '']:
                # Define variable (var1,var2,..)
                locals()[str(name)] = listval[-1]
                # Execute the command coresponding to the variable
                if ';' in setcommand: # if more than one command on the line
                    command_split = setcommand.split(';')
                    for setcommand in command_split:
                        eval(setcommand)
                else:
                    eval(setcommand)
            else:
                xpath = getcommand
                tixi.updateTextElement(xpath, str(listval[-1]))
    aircraft.write_cpacs(aircraft.get_uid())
    tigl.close()
    cpsf.close_tixi(tixi, cpacs_out_path)
Пример #16
0
    def __init__(self, master, cpacs_path, cpacs_out_path, submodule_list):

        self.submodule_list = submodule_list
        self.cpacs_out_path = cpacs_out_path

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

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

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

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

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

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

        # General buttons =============
        self.close_button = tk.Button(self.master, text='Save & Quit', command=self._save_quit)
        self.close_button.pack(side=tk.RIGHT)
        self.update_button = tk.Button(self.master, text='Update', command=self._update_all)
        self.update_button.pack(side=tk.RIGHT)
Пример #17
0
def get_number_of_parts(cpacs_in):
    """ The fuction counts the number of fuselage and wings.

    Args:
        cpacs_in (str): Path to the CPACS file.

    Retrurns:
        fus_nb (int): Number of fuselages.
        wing_nb (int) : Number of wings.

    """

    tixi = cpsf.open_tixi(cpacs_in)

    if tixi.checkElement('/cpacs/vehicles/aircraft/model/fuselages'):
        fus_nb = tixi.getNamedChildrenCount(
            '/cpacs/vehicles/aircraft/model/fuselages', 'fuselage')
    else:
        fus_nb = 0

    if tixi.checkElement('/cpacs/vehicles/aircraft/model/wings'):
        wing_nb = tixi.getNamedChildrenCount(
            '/cpacs/vehicles/aircraft/model/wings', 'wing')
    else:
        wing_nb = 0

    cpsf.close_tixi(tixi, cpacs_in)

    return (fus_nb, wing_nb)
Пример #18
0
    def compute(self, inputs, outputs):
        """Compute the objective expression"""
        global counter
        counter += 1
        cpacs_path = mif.get_tooloutput_file_path(Rt.modules[-1])

        # Save the CPACS file for this iteration
        if counter % Rt.save_iter == 0:
            loc = optim_dir_path + '/Geometry/' + 'iter_{}.xml'.format(counter)
            shutil.copy(cpacs_path, loc)

        # Add new variables to dictionnary
        tixi = cpsf.open_tixi(cpacs_path)
        dct.update_dict(tixi, optim_var_dict)

        # Change local wkdir for the next iteration
        tixi.updateTextElement(opf.WKDIR_XPATH,
                               ceaf.create_new_wkdir(Rt.date, Rt.type))

        for obj in Rt.objective:
            var_list = splt('[+*/-]', obj)
            for v in var_list:
                if not v.isdigit() and v != '':
                    exec('{} = inputs["{}"]'.format(v, v))

            result = eval(obj)
            if Rt.minmax == 'min':
                outputs['Objective function ' + obj] = -result
            else:
                outputs['Objective function ' + obj] = result

        cpsf.close_tixi(tixi, cpacs_path)
Пример #19
0
def test_get_value_or_default():
    """Test the function 'get_value_or_default'"""

    tixi = open_tixi(CPACS_IN_PATH)

    # Check if the correct value (float) is return from an xpath
    xpath = '/cpacs/vehicles/aircraft/model/reference/area'
    tixi, value = get_value_or_default(tixi, xpath, 2.0)
    assert value == 1.0

    # Check if the correct value (text) is return from an xpath
    xpath = '/cpacs/vehicles/aircraft/model/name'
    tixi, value = get_value_or_default(tixi, xpath, 'name')
    assert value == 'Cpacs2Test'

    # Check if a non exitant xpath leads to its creation (integer)
    xpath = '/cpacs/vehicles/aircraft/model/reference/newSpan'
    tixi, value = get_value_or_default(tixi, xpath, 100)
    assert value == 100
    new_elem = tixi.getDoubleElement(xpath)
    assert new_elem == 100

    # Check if a non exitant xpath leads to its creation (float)
    xpath = '/cpacs/vehicles/aircraft/model/reference/newArea'
    tixi, value = get_value_or_default(tixi, xpath, 1000.0)
    assert value == 1000.0
    new_elem = tixi.getDoubleElement(xpath)
    assert new_elem == 1000.0

    # Check if a non exitant xpath leads to its creation (text)
    xpath = '/cpacs/vehicles/aircraft/model/reference/newRef'
    tixi, value = get_value_or_default(tixi, xpath, 'test')
    assert value == 'test'
    new_elem = tixi.getTextElement(xpath)
    assert new_elem == 'test'
Пример #20
0
    def __init__(self, master, cpacs_path, cpacs_out_path, submodule_list, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)
        self.pack(fill=tk.BOTH)

        self.submodule_list = submodule_list
        self.cpacs_out_path = cpacs_out_path

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

        self.tixi = cpsf.open_tixi(cpacs_path)

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

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

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

        # General button
        self.update_button = tk.Button(self, text='Update', command=self._update_all)
        self.update_button.grid(row=1, column=1,sticky='E')
        self.close_button = tk.Button(self, text='Save & Quit', command=self._save_quit)
        self.close_button.grid(row=1, column=2,sticky='W')
Пример #21
0
def check_cpacs_input_requirements(cpacs_file, *, submod_name=None, submodule_level=1, cpacs_inout=None):
    """ Check if the input CPACS file contains the required nodes

    Note:
        * The __specs__ file will be located based on the calling module
        * In most cases this function should be called simply as

        ==> check_cpacs_input_requirements(cpacs_file)

    Args:
        cpacs_file (str): Path to the CPACS file to check
        submod_name (str): Name of the submod_name (if None, determined from caller)
        submodule_level (int): Levels up where the CEASIOMpy submodule is located
        cpacs_inout (obj): CPACSInOut() instance

    Raises:
        CPACSRequirementError: If one or more paths are required by calling
                               module but not available in CPACS file
    """

    # log = get_logger(module_file_name.split('.')[0])

    if not isinstance(submodule_level, int) and submodule_level < 1:
        ValueError("'submodule_level' must be a positive integer")

    # If 'cpacs_inout' not provided by caller, we try to determine it
    if cpacs_inout is None:
        if submod_name is None:
            # Get the path of the caller submodule
            frm = inspect.stack()[1]
            mod = inspect.getmodule(frm[0])
            caller_module_path = os.path.dirname(os.path.abspath(mod.__file__))

            # Get the CEASIOM_XPATH submodule name
            parent_path, submod_name = os.path.split(caller_module_path)
            for _ in range(1, submodule_level):
                parent_path, submod_name = os.path.split(parent_path)

        # Load the submodule specifications
        specs_module = get_specs_for_module(submod_name, raise_error=True)
        cpacs_inout = specs_module.cpacs_inout

    tixi = cpsf.open_tixi(cpacs_file)
    missing_nodes = []
    for entry in cpacs_inout.inputs:

        if entry.default_value is not None:
            continue
        if tixi.checkElement(entry.xpath) is False:
            missing_nodes.append(entry.xpath)

    if missing_nodes:
        missing_str = ''
        for missing in missing_nodes:
            missing_str += '==> ' + missing + '\n'

        msg = f"CPACS path required but does not exist\n{missing_str}"
        # log.error(msg)
        raise CPACSRequirementError(msg)
Пример #22
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)
Пример #23
0
    def compute(self, inputs, outputs):
        """Launches the module"""

        # Updating inputs in CPACS file
        cpacs_path = mif.get_toolinput_file_path(self.module_name)
        tixi = cpsf.open_tixi(cpacs_path)
        for name in inputs:
            if name in optim_var_dict:
                xpath = optim_var_dict[name][4]
                # Change only the first vector value for aeromap param
                if name in apmf.XSTATES:
                    size = tixi.getVectorSize(xpath)
                    v = list(tixi.getFloatVector(xpath, size))
                    v.pop(0)
                    v.insert(0, inputs[name])
                    tixi.updateFloatVector(xpath, v, size, '%g')
                else:
                    cpsf.add_float_vector(tixi, xpath, inputs[name])
        cpsf.close_tixi(tixi, cpacs_path)

        # Running the module
        wkf.run_subworkflow([self.module_name])

        # Feeding CPACS file results to outputs
        cpacs_path = mif.get_tooloutput_file_path(self.module_name)
        tixi = cpsf.open_tixi(cpacs_path)
        for name in outputs:
            if name in optim_var_dict:
                xpath = optim_var_dict[name][4]
                if name in apmf.COEF_LIST:
                    val = cpsf.get_value(tixi, xpath)
                    if isinstance(val, str):
                        val = val.split(';')
                        outputs[name] = val[0]
                    else:
                        outputs[name] = val
                else:
                    outputs[name] = cpsf.get_value(tixi, xpath)

        # Copy CPACS to input folder of next module
        index = Rt.modules.index(self.module_name) + 1
        if index != len(Rt.modules):
            cpacs_path = mif.get_toolinput_file_path(Rt.modules[index])
        else:
            cpacs_path = mif.get_toolinput_file_path(Rt.modules[0])
        cpsf.close_tixi(tixi, cpacs_path)
Пример #24
0
def test_fuse_nb():
    '''Test if the number of fuselage is equal to 1'''

    tixi_handle = open_tixi(CPACS_IN_PATH)
    fuse_nb = tixi_handle.getNamedChildrenCount(
        '/cpacs/vehicles/aircraft\
              /model/fuselages', 'fuselage')
    assert fuse_nb == 1
Пример #25
0
def test_wing_nb():
    '''Test if the number of wing is equal to 1'''

    tixi_handle = open_tixi(CPACS_IN_PATH)
    wing_nb = tixi_handle.getNamedChildrenCount(
        '/cpacs/vehicles/aircraft\
              /model/wings', 'wing')
    assert wing_nb == 1
Пример #26
0
def update_cpacs_file(cpacs_path, cpacs_out_path, optim_var_dict):
    """Function to update a CPACS file with value from ...

    Function 'update_cpacs_file' ....

    Source:
        * See CPACSCreator api function,

    Args:
        cpacs_path (str): Path to CPACS file to update
        cpacs_out_path (str):Path to the updated CPACS file
        optim_var_dict (dict): Dictionary containing all the variable
                               value/min/max and command to modify a CPACS file

    """

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

    aircraft = get_aircraft(tigl)
    # help(aircraft)

    wings = aircraft.get_wings()
    # help(wings)

    fuselage = aircraft.get_fuselages().get_fuselage(1)
    # help(fuselage)

    # Other functions which could be useful

    # help(wings.get_wing(1).get_section(1))
    # uid = wings.get_wing(1).get_section(2).get_uid()
    # help(wings.get_wing(1).get_positioning_transformation(uid))
    # wings.get_wing(1).get_section(2).set_rotation(geometry.CTiglPoint(40,40,-4))
    # airfoil = wings.get_wing(1).get_section(1).get_section_element(1).get_airfoil_uid()
    # help(airfoil)
    # wings.get_wing(1).get_section(1).get_section_element(1).set_airfoil_uid('NACA0006')
    # scal = wings.get_wing(1).get_section(1).get_section_element(1).get_scaling()
    # help(wings.get_wing(1).get_section(2))

    # Perform update of all the variable contained in 'optim_var_dict'

    for key, (name, listval, minval, maxval, setcommand,
              getcommand) in optim_var_dict.items():

        # Define variable (var1,var2,..)
        locals()[str(key)] = listval[-1]

        # Execute the command coresponding to the variable
        if ';' in setcommand:  # if more than one command on the line
            command_split = setcommand.split(';')
            for setcommand in command_split:
                eval(setcommand)
        else:
            eval(setcommand)

    aircraft.write_cpacs(aircraft.get_uid())
    tixi.save(cpacs_out_path)
Пример #27
0
def test_get_largest_wing_dim():
    """Test function 'get_largest_wing_dim' """

    tixi = open_tixi(CPACS_IN_PATH)
    tigl = open_tigl(tixi)

    wing_area_max, wing_span_max = get_largest_wing_dim(tixi,tigl)

    assert wing_area_max == approx(122.32551815387066)
    assert wing_span_max == approx(33.915185246594945)
Пример #28
0
def test_add_skin_friction():
    """Test function 'add_skin_friction' """

    add_skin_friction(CPACS_IN_PATH, CPACS_OUT_PATH)

    tixi = open_tixi(CPACS_OUT_PATH)
    cd0_xpath = '/cpacs/toolspecific/CEASIOMpy/aerodynamics/skinFriction/cd0'
    cd0_to_check = tixi.getDoubleElement(cd0_xpath)

    assert cd0_to_check == approx(0.01998328842386761)
Пример #29
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)
Пример #30
0
def check_workflow(cpacs_path, submodule_list):
    """Check if a linear workflow can be exectuted based on given CPACS file

    Note:
        * 'submodule_list' is a list of CEASIOMpy modules to run, example:

        ('PyTornado', 'SkinFriction', 'SU2Run', 'SkinFriction')

        * It is assumed that no XPaths will be deleted in between module, only
          new ones will be created

        * The full workflow will be checked from start to end. If multiple errors
          accumulate all will be shown at the end

    Args:
        cpacs_path (str): CPACS node path
        submodule_list (list): List of CEASIOMpy module names (order matters!)

    Raises:
        TypeError: If input data has invalid type
        ValueError: If a workflow cannot be exectued from start to end
    """

    if not isinstance(cpacs_path, str):
        raise TypeError("'cpacs_path' must be of type str")

    if not isinstance(submodule_list, (list, tuple)):
        raise TypeError("'submodule_list' must be of type list or tuple")

    tixi = cpsf.open_tixi(cpacs_path)
    xpaths_from_workflow = set()
    err_msg = ''
    for i, submod_name in enumerate(submodule_list, start=1):
        specs = get_specs_for_module(submod_name)
        if specs is None or not specs.cpacs_inout:
            log.warning(f"No specs found for {submod_name}")
            continue
        # ----- Required inputs -----
        for entry in specs.cpacs_inout.inputs:
            # The required xpath can either be in the original CPACS file
            # OR in the xpaths produced during the workflow exectution
            if not tixi.checkElement(entry.xpath) and entry.xpath not in xpaths_from_workflow:
                err_msg += \
                    f"==> XPath '{entry.xpath}' required by " \
                    + f"module '{submod_name}' ({i}/{len(submodule_list)}), " \
                    "but not found\n"
            xpaths_from_workflow.add(entry.xpath)
        # ----- Generated output -----
        for entry in specs.cpacs_inout.outputs:
            xpaths_from_workflow.add(entry.xpath)

    if err_msg:
        log.error(err_msg)
        raise ValueError(err_msg)