Esempio n. 1
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

    """

    log.info("----- Start of CPACSUpdater -----")
    log.info(f"{cpacs_path} will be updated.")

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

    # Object seems to be unused, but are use in "eval" function
    aircraft = get_tigl_configuration(tigl)
    wings = aircraft.get_wings()
    fuselage = aircraft.get_fuselages().get_fuselage(1)

    # Perform update of all the variable contained in 'optim_var_dict'
    for name, vars in optim_var_dict.items():

        # Unpack the variables
        val_type, listval, _, _, getcommand, setcommand = vars

        if val_type == "des" and listval[0] not in ["-", "True", "False"]:

            if setcommand not in ["-", ""]:

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

                # Update value by using tigl configuration
                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:

                # Update value directly in the CPACS file
                xpath = getcommand
                tixi.updateTextElement(xpath, str(listval[-1]))

    aircraft.write_cpacs(aircraft.get_uid())
    tigl.close()
    tixi.save(cpacs_out_path)

    log.info(f"{cpacs_out_path} has been saved.")
    log.info("----- Start of CPACSUpdater -----")
Esempio n. 2
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 = open_tigl(tixi)
    aircraft = get_tigl_configuration(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
Esempio n. 3
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. 4
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)
def geom_eval(w_nb, awg, cpacs_in):
    """Main function to evaluate the wings geometry.

    Args:
        w_nb (integer): Number of wings [-].
        awg (class): AircraftWingGeometry class look at aircraft_geometry_class.py
                     in the classes folder for explanation.
        cpacs_in (str): Path to the CPACS file

    Returns:
        awg: AircraftWingGeometry class updated.
    """

    log.info("-----------------------------------------------------------")
    log.info("---------- Analysing wing geometry ------------------------")
    log.info("-----------------------------------------------------------")

    # Opening tixi and tigl
    tixi = open_tixi(cpacs_in)
    tigl = 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 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

    tixi.save(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. 6
0
def generate_mesh_def_config(tixi, wkdir, ted_uid, wing_uid, sym_dir, defl_list):
    """Function to create config file for a TED.

    Function 'generate_mesh_def_config' will create SU2 configuration files to
    create SU2 deformed mesh for a specific Trailing Edge Device (TED) at several
    deflection angle (from defl_list)

    Args:
        tixi (handle): TIXI handle
        wkdir (str): Path to the working directory
        ted_uid (str): uID of the TED
        wing_uid (str): uID of the coresponding wing
        sym_dir (str): Direction of the axis of symmetry ('x','y','z' or '')
        defl_list (str): List of deflection angles to generate

    """

    tigl = open_tigl(tixi)
    ac_name = aircraft_name(tixi)
    DEFAULT_CONFIG_PATH = MODULE_DIR + "/files/DefaultConfig_v7.cfg"
    cfg = ConfigFile(DEFAULT_CONFIG_PATH)
    config_dir_name = ac_name + "_TED_" + ted_uid
    # TODO: add check or remove if already exist?
    os.mkdir(os.path.join(wkdir, "MESH", config_dir_name))

    # Get TED and hinge line definition
    ted_corner = get_ted_corner(tixi, tigl, ted_uid)
    ted_corner_list, ted_corner_sym_list = get_ffd_box(ted_corner, sym_dir)
    ted_hinge = get_ted_hinge(tixi, tigl, ted_uid)
    hinge_list, hinge_sym_list = get_hinge_lists(ted_hinge, sym_dir)

    # General parmeters
    ref_len = get_value(tixi, REF_XPATH + "/length")
    ref_area = get_value(tixi, REF_XPATH + "/area")
    ref_ori_moment_x = get_value_or_default(tixi, REF_XPATH + "/point/x", 0.0)
    ref_ori_moment_y = get_value_or_default(tixi, REF_XPATH + "/point/y", 0.0)
    ref_ori_moment_z = get_value_or_default(tixi, REF_XPATH + "/point/z", 0.0)

    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
    cfg["GRID_MOVEMENT"] = "NONE"
    cfg["ROTATION_RATE"] = "0.0 0.0 0.0"

    # TODO: is it the best way or should be pass as arg?
    mesh_dir = os.path.join(wkdir, "MESH")
    su2_mesh_path = os.path.join(mesh_dir, ac_name + "_baseline.su2")
    cfg["MESH_FILENAME"] = "../" + ac_name + "_baseline.su2"

    # Mesh Marker
    bc_wall_list, engine_bc_list = get_mesh_marker(su2_mesh_path)

    bc_wall_str = "(" + ",".join(bc_wall_list) + ")"
    cfg["MARKER_EULER"] = bc_wall_str
    cfg["MARKER_FAR"] = " (Farfield)"
    cfg["MARKER_SYM"] = " (0)"
    cfg["MARKER_PLOTTING"] = bc_wall_str
    cfg["MARKER_MONITORING"] = bc_wall_str
    cfg["MARKER_MOVING"] = "( NONE )"
    cfg["DV_MARKER"] = bc_wall_str

    # FFD BOX definition
    cfg["DV_KIND"] = "FFD_SETTING"
    cfg["DV_MARKER"] = "( " + wing_uid + ")"
    cfg["FFD_CONTINUITY"] = "2ND_DERIVATIVE"
    cfg["FFD_DEFINITION"] = "( " + ted_uid + ", " + ",".join(ted_corner_list) + ")"
    cfg["FFD_DEGREE"] = "( 6, 10, 3 )"  # TODO: how to chose/calculate these value?
    if sym_dir:
        cfg["FFD_DEFINITION"] += "; (" + ted_uid + "_sym, " + ",".join(ted_corner_sym_list) + ")"
        cfg["FFD_DEGREE"] += ";( 6, 10, 3 )"  # TODO: how to chose/calculate these value?
    cfg["MESH_OUT_FILENAME"] = "_mesh_ffd_box.su2"

    # Write Config definition for FFD box
    config_file_name = "ConfigDEF.cfg"
    config_path = os.path.join(wkdir, "MESH", config_dir_name, config_file_name)
    cfg.write_file(config_path, overwrite=True)
    log.info(config_path + " have has been written.")

    # FFD BOX rotation
    for defl in defl_list:

        cfg["DV_KIND"] = "FFD_ROTATION"
        cfg["DV_MARKER"] = "( " + wing_uid + ")"
        cfg["DV_PARAM"] = "( " + ted_uid + ", " + ",".join(hinge_list) + ")"
        cfg["DV_VALUE"] = str(defl / 1000)  # SU2 use 1/1000 degree...

        cfg["MESH_FILENAME"] = "_mesh_ffd_box.su2"
        defl_mesh_name = ac_name + "_TED_" + ted_uid + "_defl" + str(defl) + ".su2"
        if sym_dir:
            defl_mesh_name = "_" + defl_mesh_name
        cfg["MESH_OUT_FILENAME"] = defl_mesh_name

        # Write Config rotation for FFD box
        config_file_name = "ConfigROT_defl" + str(defl) + ".cfg"
        config_path = os.path.join(wkdir, "MESH", config_dir_name, config_file_name)
        cfg.write_file(config_path, overwrite=True)
        log.info(config_path + " have has been written.")

        if sym_dir:
            # TODO: add a condition for anti symmetric deflection (e.g. ailerons)
            cfg["DV_MARKER"] = "( " + wing_uid + ")"
            cfg["DV_PARAM"] = "( " + ted_uid + "_sym, " + ",".join(hinge_sym_list) + ")"
            cfg["DV_VALUE"] = str(defl / 1000)  # SU2 use 1/1000 degree...

            cfg["MESH_FILENAME"] = defl_mesh_name
            defl_mesh_sym_name = ac_name + "_TED_" + ted_uid + "_defl" + str(defl) + "_sym.su2"
            cfg["MESH_OUT_FILENAME"] = defl_mesh_sym_name

            config_file_name = "ConfigROT_sym_defl" + str(defl) + ".cfg"
            config_path = os.path.join(wkdir, "MESH", config_dir_name, config_file_name)
            cfg.write_file(config_path, overwrite=True)
            log.info(config_path + " have has been written.")
Esempio n. 7
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 = open_tixi(cpacs_in)
    tigl = open_tigl(tixi)

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

    fus_nb = tixi.getNamedChildrenCount(
        "/cpacs/vehicles/aircraft/model/fuselages", "fuselage")
    #  ----------------------------------------------------------------------------
    #  INITIALIZATION 1 -----------------------------------------------------------
    #  ----------------------------------------------------------------------------

    ag.fus_nb = fus_nb
    ag.fuse_nb = fus_nb
    i = ag.fus_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(fus_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, fus_nb))
    ag.fuse_sec_width = np.zeros((max_sec_nb, fus_nb))
    ag.fuse_sec_rel_dist = np.zeros((max_sec_nb, fus_nb))
    ag.fuse_seg_index = np.zeros((max_sec_nb, fus_nb))
    ag.fuse_seg_length = np.zeros((max_seg_nb, fus_nb))
    fuse_center_section_point = np.zeros((max_sec_nb, fus_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, fus_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, fus_nb))
    c = False
    cabin_nb = np.zeros((1, fus_nb))
    cabin_seg = np.zeros((max_seg_nb, fus_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, fus_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]

    tixi.save(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("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("Mean fuselage width [m]: " + str(ag.fuse_mean_width))
    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. 8
0
def fuse_geom_eval(fus_nb, h_min, fuse_thick, F_FUEL, afg, cpacs_in):
    """Main function to evaluate the fuselage geometry

    Args:
        fus_nb (int): Number of fuselages.
        h_min (float): Minimum height for the fuselage [m].
        fuse_thick(float) : Thickness of the fuselage [mm].
        F_FUEL (float-array): Percentage of the total volume of the fuel tank
                              fuselage, used for fuel straging (set False if
                              fuselage is ment for payload/passengers).
        afg (class): AircraftGeometry class look at aircraft_geometry_class.py
                     in the classes folder for explanation.
        cpacs_in (str): Path to the CPACS file

    Returns:
        afg (class): Updated aircraft_geometry class
    """

    log.info("-----------------------------------------------------------")
    log.info("---------- Analysing fuselage geometry --------------------")
    log.info("-----------------------------------------------------------")

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

    # INITIALIZATION 1 ----------------------------------------------------------
    afg.fus_nb = fus_nb

    # Counting sections and segments----------------------------------------------

    for i in range(1, afg.fus_nb + 1):
        afg.fuse_sec_nb.append(tigl.fuselageGetSectionCount(i))
        afg.fuse_seg_nb.append(tigl.fuselageGetSegmentCount(i))
        afg.fuse_vol.append(tigl.fuselageGetVolume(i))
        afg.fuse_surface.append(tigl.fuselageGetSurfaceArea(i))

    # Checking segment and section connection and reordering them
    (afg.fuse_sec_nb, start_index, seg_sec,
     fuse_sec_index) = check_segment_connection(afg.fus_nb, afg.fuse_seg_nb,
                                                afg.fuse_sec_nb, tigl)
    afg.f_seg_sec = seg_sec

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

    max_sec_nb = np.amax(afg.fuse_sec_nb)
    max_seg_nb = np.amax(afg.fuse_seg_nb)
    afg.fuse_sec_per = np.zeros((max_sec_nb, afg.fus_nb))
    afg.fuse_sec_width = np.zeros((max_sec_nb, afg.fus_nb))
    afg.fuse_sec_height = np.zeros((max_sec_nb, afg.fus_nb))
    afg.fuse_sec_rel_dist = np.zeros((max_sec_nb, afg.fus_nb))
    afg.fuse_seg_index = np.zeros((max_sec_nb, afg.fus_nb))
    afg.fuse_seg_length = np.zeros((max_seg_nb, afg.fus_nb))
    afg.fuse_center_section_point = np.zeros((max_sec_nb, afg.fus_nb, 3))
    afg.fuse_center_seg_point = np.zeros((max_sec_nb, afg.fus_nb, 3))
    afg.fuse_seg_vol = np.zeros((max_seg_nb, afg.fus_nb))
    x1 = np.zeros((max_sec_nb, afg.fus_nb))
    y1 = np.zeros((max_sec_nb, afg.fus_nb))
    z1 = np.zeros((max_sec_nb, afg.fus_nb))
    x2 = np.zeros((max_sec_nb, afg.fus_nb))
    y2 = np.zeros((max_sec_nb, afg.fus_nb))
    z2 = np.zeros((max_sec_nb, afg.fus_nb))

    # FUSELAGE ANALYSIS ----------------------------------------------------------

    # Aircraft total length ------------------------------------------------------
    afg.tot_length = tigl.configurationGetLength()

    # Evaluating fuselage: sections perimeter, segments volume and length ---
    for i in range(1, afg.fus_nb + 1):
        (afg.fuse_sec_rel_dist[:, i - 1],
         afg.fuse_seg_index[:, i - 1]) = rel_dist(
             i,
             afg.fuse_sec_nb[i - 1],
             afg.fuse_seg_nb[i - 1],
             tigl,
             seg_sec[:, i - 1, :],
             start_index[i - 1],
         )
        afg.fuse_length.append(round(afg.fuse_sec_rel_dist[-1, i - 1], 3))
        for j in range(1, afg.fuse_seg_nb[i - 1] + 1):
            k = int(afg.fuse_seg_index[j][i - 1])
            afg.fuse_sec_per[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)
            afg.fuse_seg_vol[j - 1][i - 1] = tigl.fuselageGetSegmentVolume(
                i, k)
            afg.fuse_center_section_point[j][i - 1][0] = (fpx + fpx2) / 2
            afg.fuse_center_section_point[j][i - 1][1] = (fpy + fpy2) / 2
            afg.fuse_center_section_point[j][i - 1][2] = (fpz + fpz2) / 2
            hw1 = 0.0
            hw2 = 0.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 -
                       afg.fuse_center_section_point[j][i - 1][2]) < 0.01:
                    if fpy > afg.fuse_center_section_point[j][
                            i - 1][1] and hw1 == 0.0:
                        hw1 = abs(fpy -
                                  afg.fuse_center_section_point[j][i - 1][1])
                        x1[j, i - 1] = fpx
                        y1[j, i - 1] = fpy
                        z1[j, i - 1] = fpz
                    elif fpy < afg.fuse_center_section_point[j][
                            i - 1][1] and hw2 == 0.0:
                        hw2 = abs(fpy -
                                  afg.fuse_center_section_point[j][i - 1][1])
                        x2[j, i - 1] = fpx
                        y2[j, i - 1] = fpy
                        z2[j, i - 1] = fpz
                        break
            afg.fuse_sec_width[j][i - 1] = hw1 + hw2
            hh1 = 0.0
            hh2 = 0.0
            for zeta in np.arange(0.0, 1.0, 0.001):
                (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 1.0, zeta)
                if abs(fpy -
                       afg.fuse_center_section_point[j][i - 1][1]) < 0.01:
                    if fpz > afg.fuse_center_section_point[j][
                            i - 1][2] and hh1 == 0.0:
                        hh1 = abs(fpz -
                                  afg.fuse_center_section_point[j][i - 1][2])
                    elif fpz < afg.fuse_center_section_point[j][
                            i - 1][2] and hh2 == 0.0:
                        hh2 = abs(fpz -
                                  afg.fuse_center_section_point[j][i - 1][2])
                        break
            afg.fuse_sec_height[j][i - 1] = hh1 + hh2
            (fslpx, fslpy, fslpz) = tigl.fuselageGetPoint(1, k, 0.0, 0.0)
            (fslpx2, fslpy2, fslpz2) = tigl.fuselageGetPoint(1, k, 1.0, 0.0)
            afg.fuse_seg_length[j - 1][i - 1] = abs(fslpx2 - fslpx)
        k = int(afg.fuse_seg_index[1][i - 1])
        afg.fuse_sec_per[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)
        afg.fuse_center_section_point[0][i - 1][0] = (fpx + fpx2) / 2
        afg.fuse_center_section_point[0][i - 1][1] = (fpy + fpy2) / 2
        afg.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 - afg.fuse_center_section_point[0][i - 1][2]) < 0.01:
                if fpy > afg.fuse_center_section_point[0][i -
                                                          1][1] and hw1 == 0:
                    hw1 = abs(fpy - afg.fuse_center_section_point[0][i - 1][1])
                    x1[0, i - 1] = fpx
                    y1[0, i - 1] = fpy
                    z1[0, i - 1] = fpz
                elif fpy < afg.fuse_center_section_point[0][i -
                                                            1][1] and hw2 == 0:
                    hw2 = abs(fpy - afg.fuse_center_section_point[0][i - 1][1])
                    x2[0, i - 1] = fpx
                    y2[0, i - 1] = fpy
                    z2[0, i - 1] = fpz
                    break
        afg.fuse_sec_width[0][i - 1] = hw1 + hw2
        hh1 = 0.0
        hh2 = 0.0
        for zeta in np.arange(0.0, 1.0, 0.001):
            (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 1.0, zeta)
            if abs(fpy - afg.fuse_center_section_point[0][i - 1][1]) < 0.01:
                if fpz > afg.fuse_center_section_point[0][i -
                                                          1][2] and hh1 == 0.0:
                    hh1 = abs(fpz - afg.fuse_center_section_point[0][i - 1][2])
                elif fpz < afg.fuse_center_section_point[0][
                        i - 1][2] and hh2 == 0.0:
                    hh2 = abs(fpz - afg.fuse_center_section_point[0][i - 1][2])
                    break
        afg.fuse_sec_height[0][i - 1] = hh1 + hh2
        afg.fuse_mean_width.append(
            round(np.mean(afg.fuse_sec_width[:, i - 1]), 3))

    # Evaluating the point at the center of each segment.
    for i in range(int(afg.fuse_nb)):
        for j in range(1, afg.fuse_seg_nb[i - 1] + 1):
            afg.fuse_center_seg_point[j - 1][
                i - 1][0] = (afg.fuse_center_section_point[j - 1][i - 1][0] +
                             afg.fuse_center_section_point[j][i - 1][0]) / 2
            afg.fuse_center_seg_point[j - 1][
                i - 1][1] = (afg.fuse_center_section_point[j - 1][i - 1][1] +
                             afg.fuse_center_section_point[j][i - 1][1]) / 2
            afg.fuse_center_seg_point[j - 1][
                i - 1][2] = (afg.fuse_center_section_point[j - 1][i - 1][2] +
                             afg.fuse_center_section_point[j][i - 1][2]) / 2

    # Evaluating cabin length and volume, nose length and tail_length ------------
    log.info("-----------------------------------------------------------")
    log.info("----------- Analysing cabin dimensions --------------------")
    log.info("-----------------------------------------------------------")
    corr = (1.3) + np.zeros((afg.fus_nb))
    c = False
    afg.cabin_nb = np.zeros((afg.fus_nb))
    afg.cabin_area = np.zeros((afg.fus_nb))
    afg.fuse_cabin_length = np.zeros((afg.fus_nb))
    afg.cabin_seg = np.zeros((max_seg_nb, afg.fus_nb))
    afg.cabin_length = np.zeros((afg.fus_nb))
    afg.fuse_cabin_vol = np.zeros((afg.fus_nb))
    afg.fuse_nose_length = np.zeros((afg.fus_nb))
    afg.fuse_tail_length = np.zeros((afg.fus_nb))
    afg.fuse_fuel_vol = np.zeros((afg.fus_nb))

    for i in range(1, afg.fus_nb + 1):
        ex = False
        cabin_seg = np.zeros((max_seg_nb, 1))
        cabin_nb = 0
        cabin_length = 0
        cabin_volume = 0
        nose_length = 0
        tail_length = 0
        if not F_FUEL[i - 1]:
            for j in range(1, afg.fuse_seg_nb[i - 1] + 1):
                if round(afg.fuse_sec_width[j][i - 1], 3) == round(
                        np.amax(afg.fuse_sec_width[:, i - 1]),
                        3) and (h_min <= afg.fuse_sec_height[j, i - 1]):
                    cabin_length += afg.fuse_seg_length[j - 1, i - 1]
                    cabin_volume += afg.fuse_seg_vol[j - 1, i - 1]
                    cabin_seg[j - 1] = 1
                    c = True
                elif not c:
                    nose_length += afg.fuse_seg_length[j - 1, i - 1]
            if cabin_length >= 0.65 * afg.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 = afg.fuse_length[i -
                                              1] - cabin_length - nose_length
                cabin_nb = 1
                ex = True
            while ex is False:
                c = False
                cabin_seg[:] = 0
                nose_length = 0
                tail_length = 0
                cabin_length = 0
                cabin_volume = 0
                for j in range(1, afg.fuse_seg_nb[i - 1] + 1):
                    if afg.fuse_sec_width[j][i - 1] >= (
                            corr[i - 1] * afg.fuse_mean_width[i - 1]) and (
                                h_min <= afg.fuse_sec_height[j, i - 1]):
                        cabin_length += afg.fuse_seg_length[j - 1, i - 1]
                        cabin_volume += afg.fuse_seg_vol[j - 1, i - 1]
                        cabin_seg[j - 1] = 1
                        c += 1
                    elif c > 1:
                        tail_length += afg.fuse_seg_length[j - 1, i - 1]
                    else:
                        nose_length += afg.fuse_seg_length[j - 1, i - 1]
                if corr[i - 1] > 0.0 and cabin_length < (
                        0.20 * afg.fuse_length[i - 1]):
                    corr[i - 1] -= 0.05
                else:
                    ex = True
            afg.fuse_nose_length[i - 1] = round(nose_length, 3)
            afg.fuse_fuel_vol[i - 1] = 0
            afg.fuse_tail_length[i - 1] = round(tail_length, 3)
            afg.fuse_cabin_length[i - 1] = round(cabin_length, 3)
            afg.fuse_cabin_vol[i - 1] = round(cabin_volume, 3)
            afg.cabin_nb[i - 1] = cabin_nb
            afg.cabin_seg[:, i - 1] = cabin_seg[:, 0]
            afg.fuse_cabin_length[i - 1] = round(cabin_length, 3)
            cabin_area = 0
            for j in range(0, afg.fuse_seg_nb[i - 1]):
                if afg.cabin_seg[j, i - 1] == 1:
                    (x11, y11, _) = (x1[j, i - 1], y1[j, i - 1], z1[j, i - 1])
                    (x12, y12, _) = (x1[j + 1, i - 1], y1[j + 1,
                                                          i - 1], z1[j + 1,
                                                                     i - 1])
                    (x21, y21, _) = (x2[j, i - 1], y2[j, i - 1], z2[j, i - 1])
                    (x22, y22, _) = (x2[j + 1, i - 1], y2[j + 1,
                                                          i - 1], z2[j + 1,
                                                                     i - 1])
                    cabin_area += 0.5 * abs(
                        x11 * y12 + x12 * y22 + x22 * y21 + x21 * y11 -
                        (y11 * x12 + y12 * x22 + y22 * x21 + y21 * x11))
                elif cabin_area > 0 and afg.cabin_seg[j, i - 1] == 0:
                    break
            thick_area = afg.fuse_cabin_length[i - 1] * (fuse_thick * 2.0)
            afg.cabin_area[i - 1] = round((cabin_area - thick_area), 3)
        else:
            afg.fuse_fuel_vol[i - 1] *= F_FUEL[i - 1] / 100.0
            afg.fuse_nose_length[i - 1] = 0
            afg.fuse_tail_length[i - 1] = 0
            afg.fuse_cabin_length[i - 1] = 0
            afg.fuse_cabin_vol[i - 1] = 0
            afg.cabin_area[i - 1] = 0

    tixi.save(cpacs_in)

    # log info display ------------------------------------------------------------
    log.info("-----------------------------------------------------------")
    log.info("---------- Fuselage Geometry Evaluations ------------------")
    log.info("---------- USEFUL INFO ----------------------------------\n" +
             "If fuselage number is greater than 1 the\n" +
             "informations of each obj are listed in an\n " +
             "array ordered progressively")
    log.info("-----------------------------------------------------------")
    log.info("---------- Fuselage Results -------------------------------")
    log.info("Number of fuselage [-]: " + str(afg.fus_nb))
    log.info("Number of fuselage sections [-]: " + str(afg.fuse_sec_nb))
    log.info("Number of fuselage segments [-]: " + str(afg.fuse_seg_nb))
    log.info("Cabin segments array [-]:\n" + str(cabin_seg))
    log.info("Fuse Length [m]:\n" + str(afg.fuse_length))
    log.info("Fuse nose Length [m]:\n" + str(afg.fuse_nose_length))
    log.info("Fuse cabin Length [m]:\n" + str(afg.fuse_cabin_length))
    log.info("Fuse tail Length [m]:\n" + str(afg.fuse_tail_length))
    log.info("Aircraft Length [m]: " + str(afg.tot_length))
    log.info("Perimeter of each section of each fuselage [m]: \n" +
             str(afg.fuse_sec_per))
    log.info("Relative distance of each section of each fuselage [m]: \n" +
             str(afg.fuse_sec_rel_dist))
    log.info("Length of each segment of each fuselage [m]: \n" +
             str(afg.fuse_seg_length))
    log.info("Mean fuselage width [m]: " + str(afg.fuse_mean_width))
    log.info("Width of each section of each fuselage [m]: \n" +
             str(afg.fuse_sec_width))
    log.info("Cabin area [m^2]:\n" + str(afg.cabin_area))
    log.info("Fuselage wetted surface [m^2]:\n" + str(afg.fuse_surface))
    log.info("Volume of all the segmetns of each fuselage [m^3]: \n" +
             str(afg.fuse_seg_vol))
    log.info("Volume of each cabin [m^3]:\n" + str(afg.fuse_cabin_vol))
    log.info("Volume of each fuselage [m^3]:\n" + str(afg.fuse_vol))
    log.info("Volume of fuel in each fuselage [m^3]:\n" +
             str(afg.fuse_fuel_vol))
    log.info("-----------------------------------------------------------")

    return afg
Esempio n. 9
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):
                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
            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
    tixi.save(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
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.

    Args:
        h_min (float): Minimum height for the fuselage [m].
        awg (class): AircraftWingGeometry class look at
                     aircraft_geometry_class.py in the classes folder for explanation.
        cpacs_in (str): Path to the CPACS file.
        TP (boolean): True if the aircraft is a turboprop.
        FUEL_ON_CABIN (float): Percentage of the cabin volume used for fuel
                           storaging instead for passengers. (default 0%)

    Returns:
        wing_nodes (float-array): 3D array containing the nodes coordinates (x,y,z) [m,m,m].
        awg (class): 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 = open_tixi(cpacs_in)
    tigl = 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:
                    (_, y13, z13) = (xl, yl, zl)
                    z_min = zl
                if zu > z_max:
                    (_, 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:
                (_, y23, z23) = (x23_t, y23_t, z23_t)
                (_, 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
            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
            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
            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)