Esempio n. 1
0
def test_open_tigl():
    """Test the function 'open_tigl'"""

    # Create TIGL handle for a valid TIXI handles
    tixi_handle = open_tixi(CPACS_IN_PATH)
    tigl_handle = open_tigl(tixi_handle)

    assert tigl_handle

    # Raise error for an invalid TIXI handles
    with pytest.raises(AttributeError):
        tixi_handle = open_tigl('invalid_TIGL_handle')
Esempio n. 2
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 ()
Esempio n. 3
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)
Esempio n. 4
0
def init_geom_var_dict(tixi):
    """Create design variable dictionary

    Return the dictionary of the design variables using the TIGL library.
    Add design variables and constrains relative to the aircraft fuselages to
    the dictionnary.

    Args:
        tixi (handle) : Handle of the CPACS file

    Returns:
        geom_var_dict (dict) : dictionary with the geometric parameters of
        the routine.

    """
    tigl = cpsf.open_tigl(tixi)
    aircraft = cpud.get_aircraft(tigl)

    fuse_nb = aircraft.get_fuselage_count()
    if fuse_nb:
        init_fuse_param(aircraft, fuse_nb)

    wing_nb = aircraft.get_wing_count()
    if wing_nb:
        init_wing_param(aircraft, wing_nb)

    return geom_var_dict
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)
    analyses_xpath = '/cpacs/toolspecific/CEASIOMpy/geometry/analyses'
    wetted_area = get_value(tixi,analyses_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)
Esempio n. 6
0
def init_design_var_dict(tixi):
    """
    Return the dictionary of the design variables using the TIGL library.

    Parameters
    ----------
    tigl : tigl3_handler

    Returns
    -------
    design_var_dict : TYPE

    """
    tigl = cpsf.open_tigl(tixi)
    aircraft = cpud.get_aircraft(tigl)

    # fuse_nb = aircraft.get_fuselage_count()
    # if fuse_nb:
    #     init_fuse_param(aircraft, fuse_nb)

    wing_nb = aircraft.get_wing_count()
    if wing_nb:
        init_wing_param(aircraft, wing_nb)

    init_specials(tixi)

    return design_var_dict
Esempio n. 7
0
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()
Esempio n. 8
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)
Esempio n. 9
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)
Esempio n. 10
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)
Esempio n. 11
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)
Esempio n. 12
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()
Esempio n. 13
0
def aeromap_calculation(sm, tixi):
    """Make a prediction using only the aeromap entries.

    By using only the aeromap functions this module is way faster to execute. Only
    works  with the aeromap as the other values of the CPACs are not vectors and
    have to be evaluated with a different CPACS every time.

    Args:
        sm (Surrogate model object): Surrogate used to predict the function output.
        tixi (Tixi handle): Handle of the current CPACS.

    Returns:
        None.

    """

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

    aeromap_uid = apmf.get_current_aeromap_uid(tixi, 'SMUse')
    log.info('Using aeromap :'+aeromap_uid)
    Coef = apmf.get_aeromap(tixi, aeromap_uid)

    inputs = np.array([Coef.alt, Coef.mach, Coef.aoa, Coef.aos]).T

    outputs = sm.predict_values(inputs)

    # Re-initiates the values of the results to write the new ones
    Coef.cl = []
    Coef.cd = []
    Coef.cs = []
    Coef.cml = []
    Coef.cmd = []
    Coef.cms = []

    for i in range(outputs.shape[0]):
        Coef.add_coefficients(outputs[i, 0], outputs[i, 1], outputs[i, 2],
                              outputs[i, 3], outputs[i, 4], outputs[i, 5])
    Coef.print_coef_list()
    apmf.save_coefficients(tixi, aeromap_uid, Coef)

    tigl.close()
Esempio n. 14
0
def get_inputs(x):
    """Get input for the surrogate model.

    Retrieve the inputs from the cpacs and return them as a numpy array.

    Args:
        x (DataFrame): Contains the inputs locations.

    Returns:
        inputs (np.array): Array of floats.

    """

    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)

    inputs = []
    am_uid = apmf.get_current_aeromap_uid(tixi, 'SMUse')
    am_index = apmf.get_aeromap_index(tixi, am_uid)
    xpath = apmf.AEROPERFORMANCE_XPATH + '/aeroMap' + am_index + '/aeroPerformanceMap/'

    x.set_index('Name', inplace=True)
    for name in x.index:
        if x.loc[name, 'setcmd'] != '-':
            inputs.append(eval(x.loc[name, 'getcmd']))
        else:
            if name in apmf.COEF_LIST + apmf.XSTATES:
                x.loc[name, 'getcmd'] = xpath + name
            inputs.append(tixi.getDoubleElement(x.loc[name, 'getcmd']))

    tigl.close()
    cpsf.close_tixi(tixi, cpacs_path)

    inputs = np.array([inputs])
    return inputs
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 ()
Esempio n. 16
0
def generate_su2_config(cpacs_path, cpacs_out_path, wkdir):
    """Function to create SU2 confif file.

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

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

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

    """

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

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

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

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

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

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

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

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

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

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

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

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

        # Parameters fixed CL calulation
        param_count = 1

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

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

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


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

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

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


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

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

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

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

        cfg['MESH_FILENAME'] = su2_mesh_path

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

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

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

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

        config_file_name = 'ConfigCFD.cfg'


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

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

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

        su2f.write_config(config_output_path,cfg)


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

        if damping_der:

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

            cfg['GRID_MOVEMENT'] = 'ROTATING_FRAME'

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

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

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

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



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

        if control_surf:

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

            for su2_def_mesh in su2_def_mesh_list:

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

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

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


    # TODO: change that, but if it is save in tooloutput it will be erease by results...
    cpsf.close_tixi(tixi,cpacs_path)
Esempio n. 17
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)
Esempio n. 18
0
def get_user_fuel(f_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) f_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 = cpf.open_tixi(cpacs_in)
    FUEL_PATH = '/cpacs/toolspecific/CEASIOMpy/fuels'
    tixi = cpf.create_branch(tixi, FUEL_PATH, False)

    if f_nb:
        for i in range(0, f_nb):
            if f_nb > 1:
                F = 'fuelOnCabin' + str(i+1)
            else:
                F = 'fuelOnCabin'
            print((FUEL_PATH + '/' + F))
            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')
        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)
    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(ui)
def geom_eval(w_nb, awg, cpacs_in):
    """ Main function to evaluate the wings geometry.

    ARGUMENTS
    (integer) w_nb     --Arg.: Number of wings [-].
    (class) awg        --Arg.: AircraftWingGeometry class look at
                               aircraft_geometry_class.py in the
                               classes folder for explanation.
    (char) cpacs_in    -- Arg.: Cpacs xml file location.

    RETURN
    (class) awg  --Out.: AircraftWingGeometry class updated.
    """

    ##===========================================================================##
    log.info('-----------------------------------------------------------')
    log.info('---------- Analysing wing geometry ------------------------')
    log.info('-----------------------------------------------------------')

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

    ## ----------------------------------------------------------------------------
    ## INITIALIZATION 1 -----------------------------------------------------------
    ## ----------------------------------------------------------------------------

    awg.w_nb = w_nb
    awg.wing_nb = w_nb

    wing_plt_area_xz = []
    wing_plt_area_yz = []
    wingUID = []

    ## ----------------------------------------------------------------------------
    ## COUNTING 2 -----------------------------------------------------------------
    ## Counting sections and segments----------------------------------------------
    ## ----------------------------------------------------------------------------

    for i in range(1, awg.w_nb + 1):
        double = 1
        awg.wing_sym.append(tigl.wingGetSymmetry(i))
        if awg.wing_sym[i - 1] != 0:
            double = 2  # To consider the real amount of wing
            # when they are defined using symmetry
            awg.wing_nb += 1
        awg.wing_sec_nb.append(tigl.wingGetSectionCount(i))
        awg.wing_seg_nb.append(tigl.wingGetSegmentCount(i))
        awg.wing_vol.append(tigl.wingGetVolume(i) * double)
        # x-y plane
        awg.wing_plt_area.append(tigl.wingGetReferenceArea(i, 1) * double)
        # x-z plane
        wing_plt_area_xz.append(tigl.wingGetReferenceArea(i, 2) * double)
        # y-z plane
        wing_plt_area_yz.append(tigl.wingGetReferenceArea(i, 3) * double)
        if (awg.wing_plt_area[i-1] > wing_plt_area_xz[i-1]\
            and awg.wing_plt_area[i-1] > wing_plt_area_yz[i-1]):
            awg.is_horiz.append(True)
            if awg.wing_sym[i - 1] != 0:
                awg.is_horiz.append(True)
        else:
            awg.is_horiz.append(False)
            if awg.wing_sym[i - 1] != 0:
                awg.is_horiz.append(False)
        awg.wing_tot_vol += awg.wing_vol[i - 1]

## Checking segment and section connection and reordering them
    (awg.wing_sec_nb, start_index, seg_sec, wing_sec_index)\
      = check_segment_connection(wing_plt_area_xz, wing_plt_area_yz,\
                                 awg, tigl)

    ## ----------------------------------------------------------------------------
    ## INITIALIZATION 2 -----------------------------------------------------------
    ## ----------------------------------------------------------------------------

    max_wing_sec_nb = np.amax(awg.wing_sec_nb)
    max_wing_seg_nb = np.amax(awg.wing_seg_nb)
    wing_center_section_point = np.zeros((max_wing_sec_nb, awg.w_nb, 3))
    awg.wing_center_seg_point = np.zeros((max_wing_seg_nb, awg.wing_nb, 3))
    awg.wing_seg_vol = np.zeros((max_wing_seg_nb, awg.w_nb))
    awg.wing_mac = np.zeros((4, awg.w_nb))
    awg.wing_sec_thicknes = np.zeros((max_wing_sec_nb, awg.w_nb))

    ##===========================================================================##
    ## ----------------------------------------------------------------------------
    ## WING ANALYSIS --------------------------------------------------------------
    ## ----------------------------------------------------------------------------
    ## Wing: MAC,chords,thicknes,span,plantform area ------------------------------

    b = 0
    for i in range(1, awg.w_nb + 1):
        wingUID.append(tigl.wingGetUID(i))
        mac = tigl.wingGetMAC(wingUID[i - 1])
        (wpx, wpy, wpz) = tigl.wingGetChordPoint(i, 1, 0.0, 0.0)
        (wpx2, wpy2, wpz2) = tigl.wingGetChordPoint(i, 1, 0.0, 1.0)
        awg.wing_max_chord.append(np.sqrt((wpx2-wpx)**2 + (wpy2-wpy)**2\
                                 + (wpz2-wpz)**2))
        (wpx, wpy, wpz) = tigl.wingGetChordPoint(i, awg.wing_seg_nb[i - 1],
                                                 1.0, 0.0)
        (wpx2,wpy2,wpz2) = tigl.wingGetChordPoint(i,awg.wing_seg_nb[i-1],\
                                                  1.0,1.0)
        awg.wing_min_chord.append(np.sqrt((wpx2-wpx)**2 + (wpy2-wpy)**2\
                                 + (wpz2-wpz)**2) )
        for k in range(1, 5):
            awg.wing_mac[k - 1][i - 1] = mac[k - 1]
        for jj in range(1, awg.wing_seg_nb[i - 1] + 1):
            j = int(seg_sec[jj - 1, i - 1, 2])
            cle = tigl.wingGetChordPoint(i, j, 0.0, 0.0)
            awg.wing_seg_vol[j - 1][i - 1] = tigl.wingGetSegmentVolume(i, j)
            lp = tigl.wingGetLowerPoint(i, j, 0.0, 0.0)
            up = tigl.wingGetUpperPoint(i, j, 0.0, 0.0)
            if np.all(cle == lp):
                L = 0.25
            else:
                L = 0.75
            if np.all(cle == up):
                U = 0.25
            else:
                U = 0.75
            (wplx, wply, wplz) = tigl.wingGetLowerPoint(i, j, 0.0, L)
            (wpux, wpuy, wpuz) = tigl.wingGetUpperPoint(i, j, 0.0, U)
            wing_center_section_point[j - 1][i - 1][0] = (wplx + wpux) / 2
            wing_center_section_point[j - 1][i - 1][1] = (wply + wpuy) / 2
            wing_center_section_point[j - 1][i - 1][2] = (wplz + wpuz) / 2
            awg.wing_sec_thicknes[j-1][i-1] = np.sqrt((wpux-wplx)**2\
                + (wpuy-wply)**2 + (wpuz-wplz)**2)
        j = int(seg_sec[awg.wing_seg_nb[i - 1] - 1, i - 1, 2])
        (wplx, wply, wplz) = tigl.wingGetLowerPoint(\
            i,awg.wing_seg_nb[i-1],1.0,L)
        (wpux, wpuy, wpuz) = tigl.wingGetUpperPoint(\
            i,awg.wing_seg_nb[i-1],1.0,U)
        awg.wing_sec_thicknes[j][i-1] = np.sqrt((wpux-wplx)**2\
            + (wpuy-wply)**2 + (wpuz-wplz)**2)
        wing_center_section_point[awg.wing_seg_nb[i -
                                                  1]][i -
                                                      1][0] = (wplx + wpux) / 2
        wing_center_section_point[awg.wing_seg_nb[i -
                                                  1]][i -
                                                      1][1] = (wply + wpuy) / 2
        wing_center_section_point[awg.wing_seg_nb[i -
                                                  1]][i -
                                                      1][2] = (wplz + wpuz) / 2
        awg.wing_sec_mean_thick.append(np.mean(\
            awg.wing_sec_thicknes[0:awg.wing_seg_nb[i-1]+1,i-1]))
        # Wing Span Evaluation, Considering symmetry
        awg.wing_span.append(round(tigl.wingGetSpan(wingUID[i - 1]), 3))
        a = np.amax(awg.wing_span)
        ## Evaluating the index that corresponds to the main wing
        if a > b:
            awg.main_wing_index = i
            b = a

    # Main wing plantform area
    awg.wing_plt_area_main = awg.wing_plt_area[awg.main_wing_index - 1]
    # Wing segment length evaluatin function
    awg = getwingsegmentlength(awg, wing_center_section_point)
    awg.w_seg_sec = seg_sec

    # Wings wetted area
    for i in range(1, awg.w_nb + 1):
        a = str(wingUID[i - 1])
        s = tigl.wingGetSurfaceArea(i)
        if awg.wing_sym[i - 1] != 0:
            s *= 2
        if i == awg.main_wing_index:
            awg.main_wing_surface = s
        else:
            awg.tail_wings_surface.append(s)
        awg.total_wings_surface += s

    # Evaluating the point at the center of each segment, the center
    # is placed at 1/4 of the chord, symmetry is considered.
    a = 0
    c = False
    for i in range(1, int(awg.wing_nb) + 1):
        if c:
            c = False
            continue
        for jj in range(1, awg.wing_seg_nb[i - a - 1] + 1):
            j = int(seg_sec[jj - 1, i - a - 1, 2])
            awg.wing_center_seg_point[j-1][i-1][0]\
                = (wing_center_section_point[j-1][i-a-1][0]\
                + wing_center_section_point[j][i-a-1][0])/2
            awg.wing_center_seg_point[j-1][i-1][1]\
                = (wing_center_section_point[j-1][i-a-1][1]\
                + wing_center_section_point[j][i-a-1][1])/2
            awg.wing_center_seg_point[j-1][i-1][2]\
                = (wing_center_section_point[j-1][i-a-1][2]\
                + wing_center_section_point[j][i-a-1][2])/2
        if awg.wing_sym[i - 1 - a] != 0:
            if awg.wing_sym[i - 1 - a] == 1:
                symy = 1
                symx = 1
                symz = -1
            if awg.wing_sym[i - 1 - a] == 2:
                symy = -1
                symx = 1
                symz = 1
            if awg.wing_sym[i - 1 - a] == 3:
                symy = 1
                symx = -1
                symz = 1
            awg.wing_center_seg_point[:,i,0]\
                = awg.wing_center_seg_point[:,i-1,0] * symx
            awg.wing_center_seg_point[:,i,1]\
                = awg.wing_center_seg_point[:,i-1,1] * symy
            awg.wing_center_seg_point[:,i,2]\
                = awg.wing_center_seg_point[:,i-1,2] * symz
            c = True
            a += 1

    cpf.close_tixi(tixi, cpacs_in)

    # log info display ------------------------------------------------------------
    log.info('-----------------------------------------------------------')
    log.info('---------- Wing Results -----------------------------------')
    log.info('Number of Wings [-]: ' + str(awg.wing_nb))
    log.info('Wing symmetry plane [-]: ' + str(awg.wing_sym))
    log.info('Number of wing sections (not counting symmetry) [-]: '\
             + str(awg.wing_sec_nb))
    log.info('Number of wing segments (not counting symmetry) [-]: '\
            + str(awg.wing_seg_nb))
    log.info('Wing Span (counting symmetry)[m]: \n' + str(awg.wing_span))
    log.info('Wing MAC length [m]: ' + str(awg.wing_mac[0, ]))
    log.info('Wing MAC x,y,z coordinate [m]: \n' + str(awg.wing_mac[1:4, ]))
    log.info('Wings sections thicknes [m]: \n' + str(awg.wing_sec_thicknes))
    log.info('Wings sections mean thicknes [m]: \n'\
             + str(awg.wing_sec_mean_thick))
    log.info('Wing segments length [m]: \n' + str(awg.wing_seg_length))
    log.info('Wing max chord length [m]: \n' + str(awg.wing_max_chord))
    log.info('Wing min chord length [m]: \n' + str(awg.wing_min_chord))
    log.info('Main wing plantform area [m^2]: ' + str(awg.wing_plt_area_main))
    log.info('Main wing wetted surface [m^2]: '\
             + str(awg.main_wing_surface))
    log.info('Tail wings wetted surface [m^2]: \n'\
             + str(awg.tail_wings_surface))
    log.info('Total wings wetted surface [m^2]: \n'\
             + str(awg.total_wings_surface))
    log.info('Wings plantform area [m^2]: \n'\
             + str(awg.wing_plt_area))
    log.info('Volume of each wing [m^3]: ' + str(awg.wing_vol))
    log.info('Total wing volume [m^3]: ' + str(awg.wing_tot_vol))
    log.info('-----------------------------------------------------------')

    return (awg)
Esempio n. 20
0
def fuselage_inertia(SPACING, center_of_gravity, mass_seg_i, afg,\
                     cpacs_in):
    """Thefunction evaluates the inertia of the fuselage using the lumped
       masses method.

       INPUT
       (float) SPACING  --Arg.: Maximum distance between fuselage nodes [m].
       (float_array) center_of_gravity --Arg.: x,y,z coordinates of the CoG.
       (float_array) mass_seg_i        --Arg.: Mass of each segment of each
                                               component of the aircraft.
       (class) afg      --Arg.: AircraftFuseGeometry class.
        ##======= Class is defined in the InputClasses folder =======##
       (char) cpacs_in --Arg.: Cpacs xml file location.

       OUTPUT
       (float) sfx --Out.: Lumped nodes x-coordinate [m].
       (float) sfy --Out.: Lumped nodes y-coordinate [m].
       (float) sfz --Out.: Lumped nodes z-coordinate [m].
       (float) Ixx --Out.: Moment of inertia respect to the x-axis [kgm^2].
       (float) Iyy --Out.: Moment of inertia respect to the y-axis [kgm^].
       (float) Izz --Out.: Moment of inertia respect to the z-axis [kgm^2].
    """

    tixi = open_tixi(cpacs_in)
    tigl = open_tigl(tixi)

    sfx = []
    sfy = []
    sfz = []
    Ixx = 0
    Iyy = 0
    Izz = 0
    Ixy = 0
    Iyz = 0
    Ixz = 0
    log.info('-------------------------------------------------------------')
    log.info('---- Evaluating fuselage nodes for lumped masses inertia ----')
    log.info('-------------------------------------------------------------')
    for f in range(1, afg.fus_nb + 1):
        for i in afg.f_seg_sec[:, f - 1, 2]:
            fx = []
            fy = []
            fz = []
            #Number of subdivisions along the longitudinal axis
            subd_l = math.ceil(
                (afg.fuse_seg_length[int(i) - 1][f - 1] / SPACING))
            #Number of subdivisions along the perimeter
            SUBD_C0 = math.ceil(
                (afg.fuse_sec_per[int(i) - 1][f - 1] / SPACING))
            #Number of subdivisions along the radial axis
            subd_r = math.ceil(
                ((afg.fuse_sec_width[int(i) - 1][f - 1] / 2) / SPACING))
            if subd_l == 0:
                subd_l = 1.0
            if SUBD_C0 == 0:
                SUBD_C0 = 1.0
            if subd_r == 0:
                subd_r = 1.0
            eta = 1.0 / (subd_l)
            zeta = 1.0 / (SUBD_C0)
            D0 = np.sqrt(np.arange(subd_r * SUBD_C0) / float(subd_r * SUBD_C0))
            D = np.array([t for t in (D0 - (D0[-1] - 0.98)) if not t < 0])
            (xc, yc, zc) = afg.fuse_center_section_point[int(i) - 1][f - 1][:]
            for j in range(int(subd_l) + 1):
                et = j * eta
                for k in range(int(SUBD_C0) + 1):
                    ze = k * zeta
                    (x0, y0, z0) = tigl.fuselageGetPoint(f, int(i), et, ze)
                    fx.append(x0)
                    fy.append(y0)
                    fz.append(z0)
                    sfx.append(x0)
                    sfy.append(y0)
                    sfz.append(z0)
                if subd_r > 0.0:
                    deltar = np.sqrt((y0 - yc)**2 + (z0 - zc)**2) * D
                    theta = np.pi * (3 - np.sqrt(5)) * np.arange(len(D))
                    x = np.zeros(np.shape(deltar)) + x0
                    y = yc + deltar * np.cos(theta)
                    z = zc + deltar * np.sin(theta)
                    fx.extend(x)
                    fy.extend(y)
                    fz.extend(z)
                    sfx.extend(x)
                    sfy.extend(y)
                    sfz.extend(z)
            M = mass_seg_i[int(i) - 1, f - 1] / np.max(np.shape(fx))
            fcx = (fx - (np.zeros((np.shape(fx))) + center_of_gravity[0]))
            fcy = (fy - (np.zeros((np.shape(fx))) + center_of_gravity[1]))
            fcz = (fz - (np.zeros((np.shape(fx))) + center_of_gravity[2]))
            Ixx += np.sum(M * np.add(fcy**2, fcz**2))
            Iyy += np.sum(M * np.add(fcx**2, fcz**2))
            Izz += np.sum(M * np.add(fcx**2, fcy**2))
            Ixy += np.sum(M * fcx * fcy)
            Iyz += np.sum(M * fcy * fcz)
            Ixz += np.sum(M * fcx * fcz)

    return (sfx, sfy, sfz, Ixx, Iyy, Izz, Ixy, Iyz, Ixz)
Esempio n. 21
0
def wing_inertia(subd_c, SPACING, fuse, center_of_gravity, mass_seg_i, awg,
                 cpacs_in):
    """The function evaluates the inertia of the wings using the lumped
       masses method.

       INPUT
       (float) subd_c   --Arg.:  Number of subdivisions along the perimeter
                                 on each surface, total number of points for
                                 each section subd_c * 2
       (float) SPACING  --Arg.: Maximum distance between wing nodes along
                                the span [m].
       (float) fuse     --Arg.: Number of fuselages.
       (float_array) center_of_gravity --Arg.: x,y,z coordinates of the CoG.
       (float_array) mass_seg_i        --Arg.: Mass of each segment of each
                                               component of the aircraft.
       (class) awg      --Arg.: AircraftWingGeometry class.
        ##======= Class is defined in the InputClasses folder =======##
       (char) cpacs_in --Arg.: Cpacs xml file location.

       OUTPUT
       (float) swx --Out.: Lumped nodes x-coordinate [m].
       (float) swy --Out.: Lumped nodes y-coordinate [m].
       (float) swz --Out.: Lumped nodes z-coordinate [m].
       (float) Ixx --Out.: Moment of inertia respect to the x-axis [kgm^2].
       (float) Iyy --Out.: Moment of inertia respect to the y-axis [kgm^].
       (float) Izz --Out.: Moment of inertia respect to the z-axis [kgm^2].

    """
    tixi = open_tixi(cpacs_in)
    tigl = open_tigl(tixi)

    log.info('-------------------------------------------------------------')
    log.info('------ Evaluating wing nodes for lumped masses inertia ------')
    log.info('-------------------------------------------------------------')

    Ixx = 0
    Iyy = 0
    Izz = 0
    Ixy = 0
    Iyz = 0
    Ixz = 0
    swx = []
    swy = []
    swz = []
    a = 0
    for w in range(1, awg.w_nb + 1):
        DEN = 0.0
        for d in range(int(subd_c + 2)):
            DEN = DEN + d
        zeta = 1.0 / DEN
        for i in awg.w_seg_sec[:, w - 1, 2]:
            if i == 0.0:
                break
            wx = []
            wy = []
            wz = []
            #Number of subdivisions along the longitudinal axis
            subd_l = math.ceil(
                (awg.wing_seg_length[int(i) - 1][w + a - 1] / SPACING))
            if subd_l == 0:
                subd_l = 1
            eta = 1.0 / subd_l
            et = 0.0
            (xc, yc, zc) = awg.wing_center_seg_point[int(i) - 1][w + a - 1][:]
            for j in range(int(subd_l) + 1):
                et = j * eta
                (xle, yle, zle) = tigl.wingGetLowerPoint(w, int(i), et, 0.0)
                (xle2, yle2, zle2) = tigl.wingGetLowerPoint(w, int(i), et, 1.0)
                if xle < xle2:
                    ZLE = 0.0
                    ze = 0.0
                else:
                    ZLE = 1.0
                    ze = 1.0
                wx.extend((xle, xle2))
                wy.extend((yle, yle2))
                wz.extend((zle, zle2))
                swx.extend((xle, xle2))
                swy.extend((yle, yle2))
                swz.extend((zle, zle2))
                for k in range(int(subd_c) + 1):
                    if ZLE == 0.0:
                        ze += float(k) * zeta
                    elif ZLE == 1.0:
                        ze -= float(k) * zeta
                    (xl, yl, zl) = tigl.wingGetLowerPoint(w, int(i), et, ze)
                    (xu, yu, zu) = tigl.wingGetUpperPoint(w, int(i), et, ze)
                    wx.extend((xl, xu))
                    wy.extend((yl, yu))
                    wz.extend((zl, zu))
                    swx.extend((xl, xu))
                    swy.extend((yl, yu))
                    swz.extend((zl, zu))
            M = mass_seg_i[int(i) - 1, fuse + w + a - 1] / np.max(np.shape(wx))
            wcx = (wx - (np.zeros((np.shape(wx))) + center_of_gravity[0]))
            wcy = (wy - (np.zeros((np.shape(wy))) + center_of_gravity[1]))
            wcz = (wz - (np.zeros((np.shape(wz))) + center_of_gravity[2]))
            Ixx += np.sum(M * np.add(wcy**2, wcz**2))
            Iyy += np.sum(M * np.add(wcx**2, wcz**2))
            Izz += np.sum(M * np.add(wcx**2, wcy**2))
            Ixy += np.sum(M * wcx * wcy)
            Iyz += np.sum(M * wcy * wcz)
            Ixz += np.sum(M * wcx * wcz)
            if awg.wing_sym[int(w) - 1] != 0:
                if awg.wing_sym[int(w) - 1] == 1:  # x-y plane
                    symy = 1 + np.zeros(np.shape(wy))
                    symx = 1 + np.zeros(np.shape(wx))
                    symz = -1 + np.zeros(np.shape(wz))
                elif awg.wing_sym[int(w) - 1] == 2:  # x-z plane
                    symy = -1 + np.zeros(np.shape(wy))
                    symx = 1 + np.zeros(np.shape(wx))
                    symz = 1 + np.zeros(np.shape(wz))
                elif awg.wing_sym[int(w) - 1] == 3:  # y-z plane
                    symy = 1 + np.zeros(np.shape(wy))
                    symx = -1 + np.zeros(np.shape(wx))
                    symz = 1 + np.zeros(np.shape(wz))
                wx_t = wx * symx
                wy_t = wy * symy
                wz_t = wz * symz
                [swx.append(x) for x in wx_t]
                [swy.append(y) for y in wy_t]
                [swz.append(z) for z in wz_t]
                M = mass_seg_i[int(i) - 1, fuse + w + a - 1] / np.max(
                    np.shape(wx_t))
                wcx_t = (wx_t - (np.zeros(
                    (np.shape(wx_t))) + center_of_gravity[0]))
                wcy_t = (wy_t - (np.zeros(
                    (np.shape(wy_t))) + center_of_gravity[1]))
                wcz_t = (wz_t - (np.zeros(
                    (np.shape(wz_t))) + center_of_gravity[2]))
                Ixx += np.sum(M * np.add(wcy_t**2, wcz_t**2))
                Iyy += np.sum(M * np.add(wcx_t**2, wcz_t**2))
                Izz += np.sum(M * np.add(wcx_t**2, wcy_t**2))
                Ixy += np.sum(M * wcx_t * wcy_t)
                Iyz += np.sum(M * wcy_t * wcz_t)
                Ixz += np.sum(M * wcx_t * wcz_t)
        if awg.wing_sym[int(w) - 1] != 0:
            a += 1

    return (swx, swy, swz, Ixx, Iyy, Izz, Ixy, Iyz, Ixz)
Esempio n. 22
0
def fuse_geom_eval(ag, cpacs_in):
    """ Main function to evaluate the fuselage geometry.

    INPUT
    (class) ag    --Arg.: AircraftGeometry class.
    ##======= Class is defined in the InputClasses folder =======##
    (char) cpacs_in  -- Arg.: Cpacs xml file location
    OUTPUT
    (class) ag  --Out.: AircraftGeometry class updated .
    """

    ##===========================================================================##
    log.info('---------------------------------------------')
    log.info('-------- Analysing fuselage geometry --------')
    log.info('---------------------------------------------')

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

    ## ----------------------------------------------------------------------------
    ## COUNTING 1 -----------------------------------------------------------------
    ## Counting fuselage number ---------------------------------------------------
    ## ----------------------------------------------------------------------------

    f_nb = tixi.getNamedChildrenCount(
        '/cpacs/vehicles/aircraft\
                                      /model/fuselages', 'fuselage')
    ## ----------------------------------------------------------------------------
    ## INITIALIZATION 1 -----------------------------------------------------------
    ## ----------------------------------------------------------------------------

    ag.f_nb = f_nb
    ag.fuse_nb = f_nb
    i = ag.f_nb

    ## ----------------------------------------------------------------------------
    ## COUNTING 2 -----------------------------------------------------------------
    ## Counting sections and segments----------------------------------------------
    ## ----------------------------------------------------------------------------

    double = 1
    ag.fuse_sym.append(tigl.fuselageGetSymmetry(i))
    if ag.fuse_sym[i - 1] != 0:
        ag.fuse_nb += 1
        double = 2
    ag.fuse_sec_nb.append(tigl.fuselageGetSectionCount(i))
    ag.fuse_seg_nb.append(tigl.fuselageGetSegmentCount(i))
    ag.fuse_vol.append(tigl.fuselageGetVolume(i) * double)

    ## Checking segment and section connection and reordering them
    (ag.fuse_sec_nb, start_index, seg_sec, fuse_sec_index)\
      = check_segment_connection(f_nb, ag.fuse_seg_nb,\
                                 ag.fuse_sec_nb, tigl)

    ## ----------------------------------------------------------------------------
    ## INITIALIZATION 2 -----------------------------------------------------------
    ## ----------------------------------------------------------------------------

    max_sec_nb = np.amax(ag.fuse_sec_nb)
    max_seg_nb = np.amax(ag.fuse_seg_nb)
    ag.fuse_sec_circ = np.zeros((max_sec_nb, f_nb))
    ag.fuse_sec_width = np.zeros((max_sec_nb, f_nb))
    ag.fuse_sec_rel_dist = np.zeros((max_sec_nb, f_nb))
    ag.fuse_seg_index = np.zeros((max_sec_nb, f_nb))
    ag.fuse_seg_length = np.zeros((max_seg_nb, f_nb))
    fuse_center_section_point = np.zeros((max_sec_nb, f_nb, 3))
    ag.fuse_center_seg_point = np.zeros((max_seg_nb, ag.fuse_nb, 3))
    ag.fuse_center_sec_point = np.zeros((max_sec_nb, ag.fuse_nb, 3))
    ag.fuse_seg_vol = np.zeros((max_seg_nb, f_nb))

    ##===========================================================================##
    ## ----------------------------------------------------------------------------
    ## FUSELAGE ANALYSIS ----------------------------------------------------------
    ## ----------------------------------------------------------------------------
    ## Aircraft total length ------------------------------------------------------

    ag.tot_length = tigl.configurationGetLength()

    ## Evaluating fuselage: sections circumference, segments volume and length ---
    (ag.fuse_sec_rel_dist[:,i-1],ag.fuse_seg_index[:,i-1])\
        = rel_dist(i,ag.fuse_sec_nb[i-1],ag.fuse_seg_nb[i-1],\
                   tigl,seg_sec[:,i-1,:],start_index[i-1])
    ag.fuse_length.append(ag.fuse_sec_rel_dist[-1, i - 1])
    for j in range(1, ag.fuse_seg_nb[i - 1] + 1):
        k = int(ag.fuse_seg_index[j][i - 1])
        ag.fuse_sec_circ[j][i-1]\
            = tigl.fuselageGetCircumference(i,k,1.0)
        (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 1.0, 0.0)
        (fpx2, fpy2, fpz2) = tigl.fuselageGetPoint(i, k, 1.0, 0.5)
        ag.fuse_seg_vol[j - 1][i - 1] = abs(tigl.fuselageGetSegmentVolume(
            i, k))
        fuse_center_section_point[j][i - 1][0] = (fpx + fpx2) / 2
        fuse_center_section_point[j][i - 1][1] = (fpy + fpy2) / 2
        fuse_center_section_point[j][i - 1][2] = (fpz + fpz2) / 2
        hw1 = 0
        hw2 = 0
        for zeta in np.arange(0.0, 1.0, 0.001):
            (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 1.0, zeta)
            if abs(fpz - fuse_center_section_point[j][i - 1][2]) < 0.01:
                if (fpy > fuse_center_section_point[j][i - 1][1] and hw1 == 0):
                    hw1 = abs(fpy - fuse_center_section_point[j][i - 1][1])
                elif (fpy < fuse_center_section_point[j][i - 1][1]
                      and hw2 == 0):
                    hw2 = abs(fpy - fuse_center_section_point[j][i - 1][1])
                    break
        ag.fuse_sec_width[j][i - 1] = hw1 + hw2
        (fslpx, fslpy, fslpz) = tigl.fuselageGetPoint(1, k, 0.0, 0.0)
        (fslpx2, fslpy2, fslpz2) = tigl.fuselageGetPoint(1, k, 1.0, 0.0)
        ag.fuse_seg_length[j - 1][i - 1] = abs(fslpx2 - fslpx)
    k = int(ag.fuse_seg_index[1][i - 1])
    ag.fuse_sec_circ[0][i - 1] = tigl.fuselageGetCircumference(i, k, 0.0)
    (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 0.0, 0.0)
    (fpx2, fpy2, fpz2) = tigl.fuselageGetPoint(i, k, 0.0, 0.5)
    fuse_center_section_point[0][i - 1][0] = (fpx + fpx2) / 2
    fuse_center_section_point[0][i - 1][1] = (fpy + fpy2) / 2
    fuse_center_section_point[0][i - 1][2] = (fpz + fpz2) / 2
    hw1 = 0
    hw2 = 0
    for zeta in np.arange(0.0, 1.0, 0.001):
        (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 0.0, zeta)
        if abs(fpz - fuse_center_section_point[0][i - 1][2]) < 0.01:
            if (fpy > fuse_center_section_point[0][i - 1][1] and hw1 == 0):
                hw1 = abs(fpy - fuse_center_section_point[0][i - 1][1])
            elif (fpy < fuse_center_section_point[0][i - 1][1] and hw2 == 0):
                hw2 = abs(fpy - fuse_center_section_point[0][i - 1][1])
                break
    ag.fuse_sec_width[0][i - 1] = hw1 + hw2
    ag.fuse_mean_width.append(np.mean(ag.fuse_sec_width[:, i - 1]))

    ## Evaluating the point at the center of each segment, symmetry is considered

    a = 0
    cs = False
    for i in range(int(ag.fuse_nb)):
        if cs:
            cs = False
            continue
        for j in range(1, ag.fuse_seg_nb[i - a - 1] + 1):
            ag.fuse_center_seg_point[j-1][i-1][0]\
                = (fuse_center_section_point[j-1][i-a-1][0]\
                   + fuse_center_section_point[j][i-a-1][0])/2
            ag.fuse_center_seg_point[j-1][i-1][1]\
                = (fuse_center_section_point[j-1][i-a-1][1]\
                   + fuse_center_section_point[j][i-a-1][1])/2
            ag.fuse_center_seg_point[j-1][i-1][2]\
                = (fuse_center_section_point[j-1][i-a-1][2]\
                   + fuse_center_section_point[j][i-a-1][2])/2
            ag.fuse_center_sec_point[j-1][i-1][:]\
                = fuse_center_section_point[j-1][i-a-1][:]
        if ag.fuse_sym[i - 1 - a] != 0:
            if ag.fuse_sym[i - 1 - a] == 1:
                symy = 1
                symx = 1
                symz = -1
            if ag.fuse_sym[i - 1 - a] == 2:
                symy = -1
                symx = 1
                symz = 1
            if ag.fuse_sym[i - 1 - a] == 3:
                symy = 1
                symx = -1
                symz = 1
            ag.fuse_center_seg_point[:,i,0]\
                = ag.fuse_center_seg_point[:,i-1,0] * symx
            ag.fuse_center_seg_point[:,i,1]\
                = ag.fuse_center_seg_point[:,i-1,1] * symy
            ag.fuse_center_seg_point[:,i,2]\
                = ag.fuse_center_seg_point[:,i-1,2] * symz
            ag.fuse_center_sec_point[j-1][i][:]\
                = fuse_center_section_point[j-1][i-a-1][:]
            cs = True
            a += 1

# Evaluating cabin length and volume, nose length and tail_length ------------
    ex = False
    corr = 1.25 + np.zeros((1, f_nb))
    c = False
    cabin_nb = np.zeros((1, f_nb))
    cabin_seg = np.zeros((max_seg_nb, f_nb))
    cabin_length = 0
    cabin_volume = 0
    nose_length = 0
    tail_length = 0
    for j in range(1, ag.fuse_seg_nb[i - 1] + 1):
        if (round(ag.fuse_sec_width[j][i-1],3)\
            == round(np.amax(ag.fuse_sec_width[:,i-1]),3)):
            cabin_length += ag.fuse_seg_length[j - 1, i - 1]
            cabin_volume += ag.fuse_seg_vol[j - 1, i - 1]
            cabin_seg[j - 1][i - 1] = 1
            c = True
        elif not c:
            nose_length += ag.fuse_seg_length[j - 1, i - 1]
    if cabin_length >= 0.65 * ag.fuse_length[i - 1]:
        # If the aircraft is designed with 1 or more sections with
        # maximum width and the sun of their length is greater the 65%
        # of the total length, the cabin will be considered only in those
        # sections
        tail_length = ag.fuse_length[i - 1] - cabin_length - nose_length
        cabin_nb[i - 1] = 1
        ex = True
    while ex is False:
        c = False
        cabin_seg = np.zeros((max_seg_nb, f_nb))
        nose_length = 0
        tail_length = 0
        cabin_length = 0
        cabin_volume = 0
        for j in range(1, ag.fuse_seg_nb[i - 1] + 1):
            if (ag.fuse_sec_width[j][i-1] >= (corr[i-1]\
                * ag.fuse_mean_width[i-1])):
                cabin_length += ag.fuse_seg_length[j - 1, i - 1]
                cabin_volume += ag.fuse_seg_vol[j - 1, i - 1]
                cabin_seg[j - 1][i - 1] = 1
                c = True
            elif c:
                tail_length += ag.fuse_seg_length[j - 1, i - 1]
            else:
                nose_length += ag.fuse_seg_length[j - 1, i - 1]
        if corr[i - 1] > 0.0 and cabin_length < (0.20 * ag.fuse_length[i - 1]):
            corr[i - 1] -= 0.05
        else:
            ex = True

    ag.fuse_nose_length.append(nose_length)
    ag.fuse_tail_length.append(tail_length)
    ag.fuse_cabin_length.append(cabin_length)
    ag.fuse_cabin_vol.append(cabin_volume)
    ag.f_seg_sec = seg_sec
    ag.cabin_nb = cabin_nb
    ag.cabin_seg = cabin_seg
    ag.fuse_mean_width = ag.fuse_mean_width[0]

    cpf.close_tixi(tixi, cpacs_in)

    # log info display ------------------------------------------------------------

    log.info('---------------------------------------------')
    log.info('---------- Geometry Evaluations -------------')
    log.info('---------- USEFUL INFO ----------------------\n'\
             + 'If fuselage or wing number is greater than 1 the '\
             + 'informations\nof each part is listed in an '\
             + 'array ordered per column progressively')
    log.info('Symmetry output: 0 = no symmetry, 1 =  x-y, '\
             + '2 = x-z, 3 = y-z planes')
    log.info('---------------------------------------------')
    log.info('---------- Fuselage Results -----------------')
    log.info('Number of fuselage [-]: ' + str(ag.fuse_nb))
    log.info('Fuselage symmetry plane [-]: ' + str(ag.fuse_sym))
    log.info('Number of fuselage sections (not counting symmetry) [-]: '\
             + str(ag.fuse_sec_nb))
    log.info('Number of fuselage segments (not counting symmetry) [-]: '\
             + str(ag.fuse_seg_nb))
    log.info('Cabin segments array [-]: ' + str(cabin_seg))
    log.info('Fuse Length [m]: ' + str(ag.fuse_length))
    log.info('Fuse nose Length [m]: ' + str(ag.fuse_nose_length))
    log.info('Fuse cabin Length [m]: ' + str(ag.fuse_cabin_length))
    log.info('Fuse tail Length [m]: ' + str(ag.fuse_tail_length))
    log.info('Aircraft Length [m]: ' + str(ag.tot_length))
    log.info('Circumference of each section of each fuselage [m]: \n'\
             + str(ag.fuse_sec_circ))
    log.info('Relative distance of each section of each fuselage [m]: \n'\
             + str(ag.fuse_sec_rel_dist))
    log.info('Length of each segment of each fuselage [m]: \n'\
             + str(ag.fuse_seg_length))
    log.info('Mean fuselage width [m]: ' + str(ag.fuse_mean_width))
    log.info('Width of each section of each fuselage [m]: \n'\
             + str(ag.fuse_sec_width))
    log.info('Volume of all the segmetns of each fuselage [m^3]: \n'\
             + str(ag.fuse_seg_vol))
    log.info('Volume of each cabin [m^3]: ' + str(ag.fuse_cabin_vol))
    log.info('Volume of each fuselage [m^3]: ' + str(ag.fuse_vol))
    log.info('---------------------------------------------')

    return (ag)
Esempio n. 23
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)
Esempio n. 24
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()
Esempio n. 25
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)
Esempio n. 26
0
def toolspecific_update(mw, out, out_xml):
    """ The function updates the cpacs file after the Weight analysis.

        INPUT
        (class) mw         --Arg.: MassesWeights class.
        (class) out        --Arg.: WeightOutput class.
        ##======= Classes are defined in the 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)

    # Path creation ==========================================================
    CEASIOM_PATH = '/cpacs/toolspecific/CEASIOMpy'

    W_PATH = CEASIOM_PATH + '/weight'
    C_PATH = W_PATH + '/crew'

    PASS_PATH = W_PATH + '/passengers'

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

    if not tixi.checkElement(PASS_PATH + '/passNb'):
        tixi.createElement(PASS_PATH, 'passNb')
    tixi.updateIntegerElement(PASS_PATH + '/passNb', out.pass_nb, '%i')
    if not tixi.checkElement(PASS_PATH + '/rowNb'):
        tixi.createElement(PASS_PATH, 'rowNb')
    tixi.updateIntegerElement(PASS_PATH + '/rowNb', out.row_nb, '%i')
    if not tixi.checkElement(PASS_PATH + '/aisleNb'):
        tixi.createElement(PASS_PATH, 'aisleNb')
    tixi.updateIntegerElement(PASS_PATH + '/aisleNb', out.aisle_nb, '%i')
    if not tixi.checkElement(PASS_PATH + '/toiletNb'):
        tixi.createElement(PASS_PATH, 'toiletNb')
    tixi.updateIntegerElement(PASS_PATH + '/toiletNb', out.toilet_nb, '%i')
    if not tixi.checkElement(PASS_PATH + '/abreastNb'):
        tixi.createElement(PASS_PATH, 'abreastNb')
    tixi.updateIntegerElement(PASS_PATH + '/abreastNb', out.abreast_nb, '%i')

    if not tixi.checkElement(PASS_PATH + '/fuelMassMaxpass'):
        tixi.createElement(PASS_PATH, 'fuelMassMaxpass')
    FMP_PATH = PASS_PATH + '/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')

    # 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()
Esempio n. 27
0
def wing_geom_eval(ag, cpacs_in):
    """ Main function to evaluate the wings geometry

    ARGUMENTS
    (class) ag         --Arg.: AircraftGeometry class.
    ##======= Class are defined in the InputClasses folder =======##
    (char) cpacs_in    -- Arg.: Cpacs xml file location.

    RETURN
    (class) ag  --Out.: AircraftGeometry class updated.
    """

    ##===========================================================================##
    log.info('---------------------------------------------')
    log.info('---------- Analysing wing geometry ----------')
    log.info('---------------------------------------------')

    # Opening tixi and tigl
    tixi = open_tixi(cpacs_in)
    tigl = open_tigl(tixi)

    ## ----------------------------------------------------------------------------
    ## COUNTING 1 -----------------------------------------------------------------
    ## Counting wing number without symmetry --------------------------------------
    ## ----------------------------------------------------------------------------

    w_nb = tixi.getNamedChildrenCount(
        '/cpacs/vehicles/aircraft\
                                      /model/wings', 'wing')

    ## ----------------------------------------------------------------------------
    ## INITIALIZATION 1 -----------------------------------------------------------
    ## ----------------------------------------------------------------------------

    ag.w_nb = w_nb
    ag.wing_nb = w_nb
    wing_plt_area_xz = []
    wing_plt_area_yz = []
    wingUID = []

    ## ----------------------------------------------------------------------------
    ## COUNTING 2 -----------------------------------------------------------------
    ## Counting sections and segments----------------------------------------------
    ## ----------------------------------------------------------------------------

    b = 0
    for i in range(1, w_nb + 1):
        double = 1
        ag.wing_sym.append(tigl.wingGetSymmetry(i))
        if ag.wing_sym[i - 1] != 0:
            double = 2  # To consider the real amount of wing
            # when they are defined using symmetry
            ag.wing_nb += 1
        ag.wing_sec_nb.append(tigl.wingGetSectionCount(i))
        ag.wing_seg_nb.append(tigl.wingGetSegmentCount(i))
        ag.wing_vol.append(tigl.wingGetVolume(i) * double)
        # x-y plane
        ag.wing_plt_area.append(tigl.wingGetReferenceArea(i, 1) * double)
        # x-z plane
        wing_plt_area_xz.append(tigl.wingGetReferenceArea(i, 2) * double)
        # y-z plane
        wing_plt_area_yz.append(tigl.wingGetReferenceArea(i, 3) * double)
        ag.wing_tot_vol = ag.wing_tot_vol + ag.wing_vol[i - 1]
        wingUID.append(tigl.wingGetUID(i))
        ag.wing_span.append(tigl.wingGetSpan(wingUID[i - 1]))
        a = np.amax(ag.wing_span)
        # Evaluating the index that corresponds to the main wing
        if a > b:
            ag.main_wing_index = i
            b = a

## Checking segment and section connection and reordering them
    (ag.wing_sec_nb, start_index, seg_sec, wing_sec_index)\
      = check_segment_connection(wing_plt_area_xz, wing_plt_area_yz,\
                                 ag, tigl)

    ## ----------------------------------------------------------------------------
    ## INITIALIZATION 2 -----------------------------------------------------------
    ## ----------------------------------------------------------------------------

    max_wing_sec_nb = np.amax(ag.wing_sec_nb)
    max_wing_seg_nb = np.amax(ag.wing_seg_nb)
    wing_center_section_point = np.zeros((max_wing_sec_nb, w_nb, 3))
    ag.wing_center_seg_point = np.zeros((max_wing_seg_nb, ag.wing_nb, 3))
    ag.wing_seg_vol = np.zeros((max_wing_seg_nb, w_nb))
    ag.wing_fuel_seg_vol = np.zeros((max_wing_seg_nb, w_nb))
    ag.wing_fuel_vol = 0
    ag.wing_mac = np.zeros((4, w_nb))
    ag.wing_sec_thicknes = np.zeros((max_wing_sec_nb + 1, w_nb))

    ##===========================================================================##
    ## ----------------------------------------------------------------------------
    ## WING ANALYSIS --------------------------------------------------------------
    ## ----------------------------------------------------------------------------
    # Main wing plantform area

    ag.wing_plt_area_main = ag.wing_plt_area[ag.main_wing_index - 1]

    ## Wing: MAC,chords,thicknes,span,plantform area ------------------------------

    for i in range(1, w_nb + 1):
        mac = tigl.wingGetMAC(wingUID[i - 1])
        (wpx, wpy, wpz) = tigl.wingGetChordPoint(i, 1, 0.0, 0.0)
        (wpx2, wpy2, wpz2) = tigl.wingGetChordPoint(i, 1, 0.0, 1.0)
        ag.wing_max_chord.append(np.sqrt((wpx2-wpx)**2 + (wpy2-wpy)**2\
                                 + (wpz2-wpz)**2))
        (wpx, wpy, wpz) = tigl.wingGetChordPoint(i, ag.wing_seg_nb[i - 1], 1.0,
                                                 0.0)
        (wpx2,wpy2,wpz2) = tigl.wingGetChordPoint(i,ag.wing_seg_nb[i-1],\
                                                  1.0,1.0)
        ag.wing_min_chord.append(np.sqrt((wpx2-wpx)**2 + (wpy2-wpy)**2\
                                 + (wpz2-wpz)**2) )
        for k in range(1, 5):
            ag.wing_mac[k - 1][i - 1] = mac[k - 1]
        for jj in range(1, ag.wing_seg_nb[i - 1] + 1):
            j = int(seg_sec[jj - 1, i - 1, 2])
            cle = tigl.wingGetChordPoint(i, j, 0.0, 0.0)
            ag.wing_seg_vol[j - 1][i - 1] = tigl.wingGetSegmentVolume(i, j)
            lp = tigl.wingGetLowerPoint(i, j, 0.0, 0.0)
            up = tigl.wingGetUpperPoint(i, j, 0.0, 0.0)
            if np.all(cle == lp) == True:
                L = 0.25
            else:
                L = 0.75
            if np.all(cle == up) == True:
                U = 0.25
            else:
                U = 0.75
            (wplx, wply, wplz) = tigl.wingGetLowerPoint(i, j, 0.0, L)
            (wpux, wpuy, wpuz) = tigl.wingGetUpperPoint(i, j, 0.0, U)
            wing_center_section_point[j - 1][i - 1][0] = (wplx + wpux) / 2
            wing_center_section_point[j - 1][i - 1][1] = (wply + wpuy) / 2
            wing_center_section_point[j - 1][i - 1][2] = (wplz + wpuz) / 2
            ag.wing_sec_thicknes[j-1][i-1] = np.sqrt((wpux-wplx)**2\
                + (wpuy-wply)**2 + (wpuz-wplz)**2)
        j = int(seg_sec[ag.wing_seg_nb[i - 1] - 1, i - 1, 2])
        (wplx, wply, wplz) = tigl.wingGetLowerPoint(\
            i,ag.wing_seg_nb[i-1],1.0,L)
        (wpux, wpuy, wpuz) = tigl.wingGetUpperPoint(\
            i,ag.wing_seg_nb[i-1],1.0,U)
        ag.wing_sec_thicknes[j][i-1] = np.sqrt((wpux-wplx)**2\
            + (wpuy-wply)**2 + (wpuz-wplz)**2)
        wing_center_section_point[ag.wing_seg_nb[i -
                                                 1]][i -
                                                     1][0] = (wplx + wpux) / 2
        wing_center_section_point[ag.wing_seg_nb[i -
                                                 1]][i -
                                                     1][1] = (wply + wpuy) / 2
        wing_center_section_point[ag.wing_seg_nb[i -
                                                 1]][i -
                                                     1][2] = (wplz + wpuz) / 2
        ag.wing_sec_mean_thick.append(np.mean(\
            ag.wing_sec_thicknes[0:ag.wing_seg_nb[i-1]+1,i-1]))
        # Evaluating wing fuel tank volume in the main wings
        if abs(round(ag.wing_plt_area[i-1],3) - ag.wing_plt_area_main)\
           < 0.001:
            tp_ratio = ag.wing_min_chord[i - 1] / ag.wing_max_chord[i - 1]
            ratio = round(tp_ratio * ag.wing_plt_area[i - 1] / 100, 1)
            if ratio >= 1.0:
                ag.wing_fuel_vol = round(ag.wing_vol[i - 1] * 0.8, 2)
            elif ratio >= 0.5:
                ag.wing_fuel_vol = round(ag.wing_vol[i - 1] * 0.72, 2)
            else:
                ag.wing_fuel_vol = round(ag.wing_vol[i - 1] * 0.5, 2)
            for j in seg_sec[:, i - 1, 2]:
                if j == 0.0:
                    break
                ag.wing_fuel_seg_vol[int(j)-1][i-1]\
                    = round((ag.wing_seg_vol[int(j)-1][i-1]\
                            /(sum(ag.wing_vol))) * ag.wing_fuel_vol,2)
        if ag.wing_plt_area[i-1] > wing_plt_area_xz[i-1] and\
            ag.wing_plt_area[i-1] > wing_plt_area_yz[i-1]:
            ag.is_horiz.append(True)
            if ag.wing_sym[i - 1] != 0:
                ag.is_horiz.append(True)
        else:
            ag.is_horiz.append(False)
            if ag.wing_sym[i - 1] != 0:
                ag.is_horiz.append(False)

    # Wing segment length evaluatin function
    ag = get_wing_segment_length(ag, wing_center_section_point)

    # Evaluating the point at the center of each segment, the center
    # is placed at 1/4 of the chord, symmetry is considered.

    a = 0
    c = False
    for i in range(1, int(ag.wing_nb) + 1):
        if c:
            c = False
            continue
        for jj in range(1, ag.wing_seg_nb[i - a - 1] + 1):
            j = int(seg_sec[jj - 1, i - a - 1, 2])
            ag.wing_center_seg_point[j-1][i-1][0]\
                = (wing_center_section_point[j-1][i-a-1][0]\
                + wing_center_section_point[j][i-a-1][0])/2
            ag.wing_center_seg_point[j-1][i-1][1]\
                = (wing_center_section_point[j-1][i-a-1][1]\
                + wing_center_section_point[j][i-a-1][1])/2
            ag.wing_center_seg_point[j-1][i-1][2]\
                = (wing_center_section_point[j-1][i-a-1][2]\
                + wing_center_section_point[j][i-a-1][2])/2
        if ag.wing_sym[i - 1 - a] != 0:
            if ag.wing_sym[i - 1 - a] == 1:
                symy = 1
                symx = 1
                symz = -1
            if ag.wing_sym[i - 1 - a] == 2:
                symy = -1
                symx = 1
                symz = 1
            if ag.wing_sym[i - 1 - a] == 3:
                symy = 1
                symx = -1
                symz = 1
            ag.wing_center_seg_point[:,i,0]\
                = ag.wing_center_seg_point[:,i-1,0] * symx
            ag.wing_center_seg_point[:,i,1]\
                = ag.wing_center_seg_point[:,i-1,1] * symy
            ag.wing_center_seg_point[:,i,2]\
                = ag.wing_center_seg_point[:,i-1,2] * symz
            c = True
            a += 1

    ag.w_seg_sec = seg_sec
    close_tixi(tixi, cpacs_in)

    # log info display ------------------------------------------------------------
    log.info('---------------------------------------------')
    log.info('--------------- Wing Results ----------------')
    log.info('Number of Wings [-]: ' + str(ag.wing_nb))
    log.info('Wing symmetry plane [-]: ' + str(ag.wing_sym))
    log.info('Number of wing sections (not counting symmetry) [-]: '\
             + str(ag.wing_sec_nb))
    log.info('Number of wing segments (not counting symmetry) [-]: '\
             + str(ag.wing_seg_nb))
    log.info('Wing Span [m]: ' + str(ag.wing_span))
    log.info('Wing MAC length [m]: ' + str(ag.wing_mac[0, ]))
    log.info('Wing MAC x,y,z coordinate [m]: \n' + str(ag.wing_mac[1:4, ]))
    log.info('Wings sections thicknes [m]: ' + str(ag.wing_sec_thicknes))
    log.info('Wings sections mean thicknes [m]: '\
            + str(ag.wing_sec_mean_thick))
    log.info('Wing segments length [m]: ' + str(ag.wing_seg_length))
    log.info('Wing max chord length [m]: ' + str(ag.wing_max_chord))
    log.info('Wing min chord length [m]: ' + str(ag.wing_min_chord))
    log.info('Main wing plantform area [m^2]: ' + str(ag.wing_plt_area_main))
    log.info('Wings plantform area [m^2]: '\
             + str(ag.wing_plt_area))
    log.info('Volume of each wing [m^3]: ' + str(ag.wing_vol))
    log.info('Total wing volume [m^3]: ' + str(ag.wing_tot_vol))
    log.info('Wing volume for fuel storage [m^3]: '\
             + str(ag.wing_fuel_vol))
    log.info('---------------------------------------------')

    return (ag)
Esempio n. 28
0
def wing_check_thickness(h_min, awg, cpacs_in, TP, FUEL_ON_CABIN=0):
    """ The fuction subdivides the main wing into nodes and defines
        the fuel and cabin volumes.

        INPUT
        (float) h_min    --Arg.: Minimum height for the fuselage [m].
        (class) awg      --Arg.: AircraftWingGeometry class look at
                                 aircraft_geometry_class.py in the
                                 classes folder for explanation.

        (char) cpacs_in  --Arg.: Relative position of the xml file.
        (boolean) TP            --Arg.: True if the aircraft is a turboprop.
        (float) FUEL_ON_CABIN --Arg.: Percentage of the cabin volume
                                      used for fuel storaging instead
                                      for passengers. (default 0%)
        OUTPUT
        (float-array) wing_nodes    --Out.: 3D array containing the
                                            nodes coordinates (x,y,z)
                                            [m,m,m].
        (class) awg      --Arg.: AircraftWingGeometry class look at
                                 aircraft_geometry_class.py in the
                                 classes folder for explanation.
    """

    log.info('-----------------------------------------------------------')
    log.info('----------- Evaluating fuselage and wing volume -----------')
    log.info('-----------------------------------------------------------')

    tixi = cpf.open_tixi(cpacs_in)
    tigl = cpf.open_tigl(tixi)

    SPACING = 0.1
    subd_c = 30  # Number of subdivisions along the perimeter
    # on eachsurface, total number of points for each section
    # subd_c * 2
    DEN = 0.0
    w = awg.main_wing_index - 1
    wing_nodes = 0
    c = False

    for d in range(1, subd_c + 2):
        DEN += d
    zeta = 1.0 / DEN
    for i in awg.w_seg_sec[:, w, 2]:
        if i == 0.0:
            break
        w_temp = np.zeros((2, subd_c + 2, 3))
        #Number of subdivisions along the longitudinal axis
        subd_l = math.ceil((awg.wing_seg_length[int(i) - 1][w] / SPACING))
        if subd_l == 0:
            subd_l = 1
        eta = 1.0 / subd_l
        et = 0.0
        (xc, yc, zc) = awg.wing_center_seg_point[int(i) - 1][w][:]
        for j in range(0, int(subd_l) - 1):
            (xle, yle, zle) = tigl.wingGetLowerPoint(w + 1, int(i), et, 0.0)
            (xle2, yle2, zle2) = tigl.wingGetLowerPoint(w + 1, int(i), et, 1.0)
            if xle < xle2:
                ZLE = 0.0
                ze = 0.0
            else:
                ZLE = 1.0
                ze = 1.0
            for k in range(0, subd_c + 2):
                if ZLE == 0.0:
                    ze += float(k) * zeta
                elif ZLE == 1.0:
                    ze -= float(k) * zeta
                (xl, yl, zl) = tigl.wingGetLowerPoint(w + 1, int(i), et, ze)
                (xu, yu, zu) = tigl.wingGetUpperPoint(w + 1, int(i), et, ze)
                w_temp[0, k, :] = (xu, yu, zu)
                w_temp[1, k, :] = (xl, yl, zl)
            if c is False:
                wing_nodes = w_temp
                c = True
            else:
                wing_nodes = np.concatenate((wing_nodes, w_temp), axis=0)
            et = j * eta
    (rows, columns, pages) = wing_nodes.shape

    # wing_nodes 3D matrix: the even rows and the zero row correspond
    # to the upper profile of the wing, while all the odd rows correspond
    # to the lower profile. The columns contain the coordinates of each nodes.
    # The page 0,1 and 2 contain respectively the x,y and z coordinate.
    h_max = []
    h_mean = []
    y_sec = []

    for r in range(0, rows - 1, 2):
        h_max_temp = 0
        z_min = 9999
        z_max = 0
        h = []
        for c in range(0, columns):
            (xu, yu, zu) = wing_nodes[r, c, :]
            (xl, yl, zl) = wing_nodes[r + 1, c, :]
            h.append(abs(zu - zl))
            if abs(zu - zl) > h_max_temp:
                h_max_temp = abs(zu - zl)
            if r == 0:
                if zl < z_min:
                    (x13, y13, z13) = (xl, yl, zl)
                    z_min = zl
                if zu > z_max:
                    (x14, y14, z14) = (xu, yu, zu)
                    z_max = zu
            else:
                if zl < z_min:
                    (x23_t, y23_t, z23_t) = (xl, yl, zl)
                    z_min = zl
                if zu > z_max:
                    (x24_t, y24_t, z24_t) = (xu, yu, zu)
                    z_max = zu
        h_max.append(h_max_temp)
        h_mean.append(np.mean(h))
        y_sec.append(yl)
        if np.mean(h) >= h_min:
            h_mean_cabin = np.mean(h_mean)
            awg.y_max_cabin = yl
            seg = r
            if r != 0:
                (x23, y23, z23) = (x23_t, y23_t, z23_t)
                (x24, y24, z24) = (x24_t, y24_t, z24_t)
        else:
            (x11, y11, z11) = wing_nodes[0, 0, :]
            (x12, y12, z12) = wing_nodes[0, -1, :]
            (x21, y21, z21) = wing_nodes[seg, 0, :]
            (x22, y22, z22) = wing_nodes[seg, -1, :]
            break

    for c in range(0, columns):
        (xu, yu, zu) = wing_nodes[0, c, :]
        (xl, yl, zl) = wing_nodes[1, c, :]
        if abs(zu - zl) >= h_min:
            xs1 = xu
            zs1u = zu
            zs1l = zl
            yse1 = yl
            break
    for c in range(0, columns):
        (xu, yu, zu) = wing_nodes[seg, c, :]
        (xl, yl, zl) = wing_nodes[seg + 1, c, :]
        if abs(zu - zl) >= h_min:
            xs2 = xu
            zs2u = zu
            zs2l = zl
            yse2 = yl
            break
    for c in range(columns - 1, -1, -1):
        (xu, yu, zu) = wing_nodes[0, c, :]
        (xl, yl, zl) = wing_nodes[1, c, :]
        if abs(zu - zl) >= h_min:
            xe1 = xu
            ze1u = zu
            ze1l = zl
            break
    for c in range(columns - 1, -1, -1):
        (xu, yu, zu) = wing_nodes[seg, c, :]
        (xl, yl, zl) = wing_nodes[seg + 1, c, :]
        if abs(zu - zl) >= h_min:
            xe2 = xu
            ze2u = zu
            ze2l = zl
            break

    awg.cabin_area = 0.5 * abs(xs1*yse2 + xs2*yse2 + xe2*yse1 + xe1*yse1\
                               - xs2*yse1 - xe2*yse2 - xe1*yse2 - xs1*yse1)
    fuse_plt_area = 0.5 * abs(x11*y21 + x21*y22 + x22*y12 + x12*y11\
                              - x21*y11 - x22*y21 - x12*y22 - x11*y12)
    fuse_frontal_area = 0.5 * abs(y24*z23 + y23*z13 + y13*z14 + y14*z24\
                                  - z24*y23 - z23*y13 - z13*y14 -z14*y24)
    c1 = math.sqrt((x11 - x12)**2 + (y11 - y12)**2 + (z11 - z12)**2)
    c2 = math.sqrt((x21 - x22)**2 + (y21 - y22)**2 + (z21 - z22)**2)

    awg.cabin_span = abs(awg.y_max_cabin - y11)

    awg.fuse_vol = (0.95 * fuse_frontal_area) * (fuse_plt_area/(awg.cabin_span))\
                    / (math.sqrt(1+(c2/c1)))

    if awg.wing_sym[w - 1] != 0:
        awg.fuse_vol *= 2
        awg.cabin_area *= 2

    awg.cabin_vol = (awg.cabin_area * h_min)
    delta_vol = (awg.fuse_vol - awg.cabin_vol)
    awg.fuse_fuel_vol = (float(FUEL_ON_CABIN) / 100.0) * delta_vol
    if TP:
        t = 0.5
    else:
        t = 0.55
    awg.wing_fuel_vol = t * (awg.wing_vol[w] - awg.fuse_vol)
    awg.fuel_vol_tot = awg.fuse_fuel_vol + awg.wing_fuel_vol

    # log info display ------------------------------------------------------------
    log.info('--------------------- Main wing Volumes -------------------')
    log.info('Wing volume [m^3]: ' + str(awg.wing_vol[w]))
    log.info('Cabin volume [m^3]: ' + str(awg.cabin_vol))
    log.info('Volume of the wing as fuselage [m^3]: ' + str(awg.fuse_vol))
    log.info('Volume of the remaining portion of the wing [m^3]: '\
             + str(awg.wing_vol[w] - awg.fuse_vol))
    log.info('Fuel volume in the fuselage [m^3]: ' + str(awg.fuse_fuel_vol))
    log.info('Fuel volume in the wing [m^3]: ' + str(awg.wing_fuel_vol))
    log.info('Total fuel Volume [m^3]: ' + str(awg.fuel_vol_tot))
    log.info('-----------------------------------------------------------')

    return (awg, wing_nodes)
Esempio n. 29
0
def get_user_inputs(ind, ui, ag, cpacs_in, cpacs):
    """ The function to extracts from the XML file the required input data,
        the code will use the default value when they are missing.

        INPUT
        (class) ind  --Arg.: InsideDimensions class.
        (class) ui   --Arg.: UserInputs class.
        ##======= Classes are defined in the InputClasses folder =======##

        (class) ag   --Arg.: AircraftGeometry 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).
        (char) cpacs       --Arg.: cpacs True or False option

        OUTPUT
        (class) ind  --Out.: InsideDimensions class updated
        (class) ui   --Out.: UserInputs class updated.
        ##======  Classes are defined in the InputClasses folder ======##

        (file) cpacs_in  --Out.: Updated cpasc file
    """

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

    # Path creation ==========================================================
    tixi = cpf.open_tixi(cpacs_in)
    CESAIOM_PATH = '/cpacs/toolspecific/CEASIOMpy'
    GEOM_PATH = CESAIOM_PATH + '/geometry'
    FUEL_PATH = CESAIOM_PATH + '/fuels'
    W_PATH = CESAIOM_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 = CESAIOM_PATH + '/propulsion'
    F_PATH = '/cpacs/vehicles/fuels/fuel'
    MC_PATH = '/cpacs/vehicles/aircraft/model/analyses/massBreakdown/'\
              + 'payload/mCargo/massDescription'

    tixi = cpf.create_branch(tixi, MC_PATH, False)
    tixi = cpf.create_branch(tixi, FUEL_PATH, False)
    tixi = cpf.create_branch(tixi, GEOM_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)
    tixi = cpf.create_branch(tixi, F_PATH, False)

    tixi = cpf.add_uid(tixi, F_PATH, 'kerosene')
    ### Geometry =============================================================
    if not tixi.checkElement(GEOM_PATH + '/description'):
        tixi.createElement(GEOM_PATH, 'description')
        tixi.updateTextElement(GEOM_PATH + '/description', 'User '\
                               + 'geometry input')
    # Extracting geometry input data (Double Floor)
    if not tixi.checkElement(GEOM_PATH + '/isDoubleFloor'):
        tixi.createElement(GEOM_PATH, 'isDoubleFloor')
        tixi.updateIntegerElement(GEOM_PATH + '/isDoubleFloor',\
                                 ui.IS_DOUBLE_FLOOR, '%i')
    else:
        temp = tixi.getIntegerElement(GEOM_PATH + '/isDoubleFloor')
        if temp != ui.IS_DOUBLE_FLOOR:
            ui.IS_DOUBLE_FLOOR = temp
    # Extracting geometry input data (seatWidth)
    if not tixi.checkElement(GEOM_PATH + '/seatWidth'):
        tixi.createElement(GEOM_PATH, 'seatWidth')
        tixi.updateDoubleElement(GEOM_PATH + '/seatWidth',\
                                 ind.seat_width, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/seatWidth')
        if temp != ind.seat_width and temp > 0:
            ind.seat_width = temp
    # Extracting geometry input data (seatLength)
    if not tixi.checkElement(GEOM_PATH + '/seatLength'):
        tixi.createElement(GEOM_PATH, 'seatLength')
        tixi.updateDoubleElement(GEOM_PATH + '/seatLength',\
                                 ind.seat_length, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/seatLength')
        if temp != ind.seat_length and temp > 0:
            ind.seat_length = temp
    # Extracting geometry input data (aisleWidth)
    if not tixi.checkElement(GEOM_PATH + '/aisleWidth'):
        tixi.createElement(GEOM_PATH, 'aisleWidth')
        tixi.updateDoubleElement(GEOM_PATH + '/aisleWidth',\
                                 ind.aisle_width, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/aisleWidth')
        if temp != ind.aisle_width and temp > 0:
            ind.aisle_width = temp
    # Extracting geometry input data (fuseThick)
    if not tixi.checkElement(GEOM_PATH + '/fuseThick'):
        tixi.createElement(GEOM_PATH, 'fuseThick')
        tixi.updateDoubleElement(GEOM_PATH + '/fuseThick',\
                                 ind.fuse_thick, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/fuseThick')
        if temp != ind.fuse_thick and temp > 0:
            ind.fuse_thick = temp
    # Extracting geometry input data (toiletLength)
    if not tixi.checkElement(GEOM_PATH + '/toiletLength'):
        tixi.createElement(GEOM_PATH, 'toiletLength')
        tixi.updateDoubleElement(GEOM_PATH + '/toiletLength',\
                                 ind.toilet_length, '%g')
    else:
        temp = tixi.getDoubleElement(GEOM_PATH + '/toiletLength')
        if temp != ind.toilet_length and temp > 0:
            ind.toilet_length = temp

    ### Weight ===============================================================
    # Pilots user input data
    if not tixi.checkElement(pilots_path + '/pilotNb'):
        tixi.createElement(pilots_path, 'pilotNb')
        tixi.updateIntegerElement(pilots_path + '/pilotNb',\
                                 ui.PILOT_NB, '%i')
    else:
        temp = tixi.getIntegerElement(pilots_path + '/pilotNb')
        if temp != ui.PILOT_NB and temp > 0:
            ui.PILOT_NB = temp
    if not tixi.checkElement(pilots_path + '/pilotMass'):
        tixi.createElement(pilots_path, 'pilotMass')
        tixi.updateDoubleElement(pilots_path + '/pilotMass',\
                                 ui.MASS_PILOT, '%g')
    else:
        temp = tixi.getDoubleElement(pilots_path + '/pilotMass')
        if temp != ui.MASS_PILOT and temp > 0:
            ui.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',\
                                 ui.MASS_CABIN_CREW, '%g')
    else:
        temp = tixi.getDoubleElement(CC_PATH + '/cabinCrewMemberMass')
        if temp != ui.MASS_CABIN_CREW and temp > 0:
            ui.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',\
                                 ui.MASS_PASS, '%g')
    else:
        temp = tixi.getDoubleElement(PASS_PATH + '/passMass')
        if temp != ui.MASS_PASS and temp > 0:
            ui.MASS_PASS = temp

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

    # 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

    # Fuel density ===========================================================

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

    # Propulsion =============================================================
    if not tixi.checkElement(PROP_PATH + '/turboprop'):
        tixi = cpf.create_branch(tixi, PROP_PATH, False)
        tixi.createElement(PROP_PATH, 'turboprop')
        if ui.TURBOPROP:
            tixi.updateTextElement(PROP_PATH + '/turboprop', 'True')
        else:
            tixi.updateTextElement(PROP_PATH + '/turboprop', 'False')
    else:
        temp = tixi.getTextElement(PROP_PATH + '/turboprop')
        if temp == 'False':
            ui.TURBOPROP = False
        else:
            ui.TURBOPROP = True

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

    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 (ind, ui)
Esempio n. 30
0
def get_ted_list(tixi):
    """ Get a list of all the TED found in the CPACS file.

    Function 'get_ted_list' looks in the CPACS file for all the Trailin Edge
    Devices (TED), saved them in a Pandas DataFrame with for each one corresponding:
        * Wing uID
        * Component Segment uiD
        * Symmetry direction (x,y,z or '')
        * Deflection list

    Source:
        * TIXI functions : http://tixi.sourceforge.net/Doc/

    Args:
        tixi (handles): TIXI Handle

    Returns:
        ted_df (Dataframe): Pandas Dataframe containing all the parameters
                            mentioned in the description of the function

    """

    tigl = cpsf.open_tigl(tixi)

    ted_df = pd.DataFrame({
        'ted_uid': [],
        'comp_seg_uid': [],
        'wing_uid': [],
        'sym_dir': [],
        'defl_list': []
    })

    if tixi.checkElement(WINGS_XPATH):
        wing_cnt = tixi.getNamedChildrenCount(WINGS_XPATH, 'wing')
        log.info(str(wing_cnt) + ' wings has been found.')
    else:
        wing_cnt = 0
        log.warning('No wings has been found in this CPACS file!')

    for i_wing in range(wing_cnt):
        wing_xpath = WINGS_XPATH + '/wing[' + str(i_wing + 1) + ']'
        wing_uid = cpsf.get_uid(tixi, wing_xpath)
        log.info(wing_uid)
        comp_segments_xpath = wing_xpath + '/componentSegments'

        if tixi.checkElement(comp_segments_xpath):
            comp_seg_cnt = tixi.getNamedChildrenCount(comp_segments_xpath,
                                                      'componentSegment')
            log.info(str(comp_seg_cnt) + ' component segments has been found.')
        else:
            comp_seg_cnt = 0
            log.warning('No Component segment has been found for this wing!')

        for c_seg in range(comp_seg_cnt):
            comp_seg_xpath = comp_segments_xpath + '/componentSegment[' + str(
                c_seg + 1) + ']'
            comp_seg_uid = cpsf.get_uid(tixi, comp_seg_xpath)
            log.info(comp_seg_uid)
            teds_xpath = comp_seg_xpath + '/controlSurfaces/trailingEdgeDevices'

            if tixi.checkElement(teds_xpath):
                ted_cnt = tixi.getNamedChildrenCount(teds_xpath,
                                                     'trailingEdgeDevice')
                log.info(
                    str(ted_cnt) + ' trailing edge devices has been found:')
            else:
                ted_cnt = 0
                log.warning(
                    'No trailing edge device has been found for this wing!')

            for ted in range(ted_cnt):
                ted_xpath = teds_xpath + '/trailingEdgeDevice[' + str(ted +
                                                                      1) + ']'

                ted_uid = cpsf.get_uid(tixi, ted_xpath)
                log.info(ted_uid)

                sym_dir = get_ted_symmetry(tixi, ted_uid)
                defl_list, _ = get_ted_deflections(tixi, ted_uid)

                ted_df.loc[len(ted_df)] = [
                    ted_uid, comp_seg_uid, wing_uid, sym_dir, defl_list
                ]

    return (ted_df)