Example #1
0
def add_wings(axes_2d, axes_3d, aircraft):
    """
    Add wings (segment vertices) to axes objects

    Args:
        :axes_2d: 2D axes object (matplotlib)
        :axes_3d: 3D axes object (matplotlib)
        :aircraft: (object) data structure for aircraft model
    """

    axes_yz, axes_xz, axes_xy = axes_2d
    for (_, _, segment), (_, _, wing) in ot.all_segments(aircraft):
        points = np.array([
            segment.vertices['a'],
            segment.vertices['b'],
            segment.vertices['c'],
            segment.vertices['d'],
            segment.vertices['a'],
        ])
        _plot_XYZ_points(axes_2d,
                         axes_3d,
                         points,
                         wing.symmetry,
                         linewidth=PS.LINEWIDTH_b,
                         color=C.MESH_MIRROR)
Example #2
0
def set_autopanels(aircraft, settings):
    """
    Automatically set chord- and spanwise discretisation settings

    Args:
        :aircraft: (object) data structure for aircraft geometry
        :autopanels_c: (int) number of chordwise panels on the main wing
        :autopanels_s: (int) number of spanwise panels on the main wing
    """

    autopanels_c = settings.settings.get('vlm_autopanels_c', MIN_AUTOPANELS)
    autopanels_s = settings.settings.get('vlm_autopanels_s', MIN_AUTOPANELS)

    for this_segment, _ in ot.all_segments(aircraft):
        segment = this_segment[2]

        if segment.panels['num_c'] is None:
            segment.panels['num_c'] = autopanels_c

        if segment.panels['num_s'] is None:
            wing_span = segment.parent_wing.span
            segment_span = segment.geometry['span']
            segment.panels['num_s'] = ceil((segment_span/wing_span)*autopanels_s)

    for this_control, this_wing in ot.all_controls(aircraft):
        control = this_control[2]

        if control.panels['num_c'] is None:
            control.panels['num_c'] = autopanels_c
Example #3
0
def _scale_plots(axes_2d, axes_3d, aircraft):
    """
    Correct the axes scaling

    Args:
        :axes_2d: 2D axes object (matplotlib)
        :axes_3d: 3D axes object (matplotlib)
        :aircraft: Aircraft model
    """

    axes_yz, axes_xz, axes_xy = axes_2d

    # Iterate through segment vertices to determine required plot dimension
    lims = np.zeros((2, 3))
    for (_, _, segment), (_, _, wing) in ot.all_segments(aircraft):
        points = np.array([
            segment.vertices['a'], segment.vertices['b'],
            segment.vertices['c'], segment.vertices['d'], segment.vertices['a']
        ])
        _get_limits(points, lims, symmetry=wing.symmetry)

    # Adjust scaling for all axes objects
    _scale_fig(axes_3d, lims)
    _scale_fig(axes_yz, lims, directions='yz')
    _scale_fig(axes_xz, lims, directions='xz')
    _scale_fig(axes_xy, lims, directions='xy')
Example #4
0
def pre_panelling(aircraft):
    """
    Create subdivisions and subareas for all aircraft wings

    Note:
        * This routine divides the wing into subdivisions and subareas
          in order to generate a suitable mesh for wing with control surfaces.
        * In a first step "mandatory" subdivisions are made: The wing is divided
          into a minimum amount of subareas according to the leading and trailing
          edge control surfaces.
        * In a second step further spanwise subdivisions are added.

    Args:
        :aircraft: (obj) aircraft object
    """

    # TODO:
    # - Potential problem:
    #   * The algorithm is based on "correct ordering" of segments:
    #     Segments must be ordered from root to tip (check if this always given!?)

    # ===== PART ONE (MANDATORY SUBDIVISIONS) =====

    # For each control we must add suitable subdivisions
    for this_control, this_wing in ot.all_controls(aircraft):
        control = this_control[2]
        wing = this_wing[2]

        # Segment names on which control surface edges are located
        segment_inner_name = control.segment_uid['inner']
        segment_outer_name = control.segment_uid['outer']

        # Control surface geometry
        eta_inner = control.rel_vertices['eta_inner']
        eta_outer = control.rel_vertices['eta_outer']
        xsi_inner = control.rel_vertices['xsi_inner']
        xsi_outer = control.rel_vertices['xsi_outer']

        # Hinge axis
        xsi_h1 = control.rel_hinge_vertices['xsi_inner']
        xsi_h2 = control.rel_hinge_vertices['xsi_outer']

        # ----- CASE (A) -----
        # The left and right edge of the control are located on SAME segment
        if segment_inner_name == segment_outer_name:
            wing.segments[segment_inner_name].add_subdivision_for_control(
                    eta_inner, eta_outer, control,
                    xsi_inner, xsi_outer, xsi_h1, xsi_h2)

        # ----- CASE (B) -----
        # - The control surface spans over one or more segment borders
        # - Now we will make a list of segments over which the control spans
        # - We will interpolate the position of the control and the hinge
        #   axis at segment borders
        else:
            # Create a list of segments which contain the control
            # list_of_segments[0]: segment_uid
            # list_of_segments[1]: eta_inner
            # list_of_segments[2]: eta_outer
            # list_of_segments[3]: xsi_inner
            # list_of_segments[4]: xsi_outer
            # list_of_segments[5]: xsi_h1
            # list_of_segments[6]: xsi_h2
            list_of_segments = []

            # Flags to indicate that the inner or outer control positions have been set
            inner_set = False
            outer_set = False

            # To start with we use averaged values for xsi (geometry and hinge axis)
            xsi_avg = (xsi_inner + xsi_outer)/2
            xsi_h_avg = (xsi_h1 + xsi_h2)/2

            for segment_uid in wing.segments.keys():
                if segment_uid == segment_inner_name:
                    inner_set = True
                    # Note: eta_outer = 1
                    list_of_segments.append([segment_uid, eta_inner, 1, xsi_inner, xsi_avg, xsi_h1, xsi_h_avg])
                    continue

                elif inner_set and not outer_set:
                    # Note: eta_inner = 0
                    # Note: eta_outer = 1
                    list_of_segments.append([segment_uid, 0, 1, xsi_avg, xsi_avg, xsi_h_avg, xsi_h_avg])

                    # If we are on the last segment we must update some incorrectly set values
                    if segment_uid == segment_outer_name:
                        outer_set = True
                        list_of_segments[-1][2] = eta_outer
                        list_of_segments[-1][4] = xsi_outer
                        list_of_segments[-1][6] = xsi_h2
                        break

            # Potentially, we must readjust the control surface geometry/hinge axis at borders
            if (xsi_inner != xsi_outer) or (xsi_h1 != xsi_h2):
                # Let's first compute the "length" of the control surface
                control_len = [0, ]

                for row in list_of_segments:
                    segment_uid, eta_i, eta_o, xsi_i, xsi_o, xsi_hi, xsi_ho = row

                    segment = wing.segments[segment_uid]
                    segment_vertices = segment.vertices

                    a = get_abs_segment_point_coords(segment_vertices, eta_i, xsi_i)
                    b = get_abs_segment_point_coords(segment_vertices, eta_o, xsi_o)
                    ab = b - a

                    # l: total length of control
                    l = control_len[-1]
                    control_len.append(l + np.sqrt(np.dot(ab, ab)))

                l = control_len[-1]

                # Now, we update the xsi values using linear interpolation
                for i, row in enumerate(list_of_segments):
                    segment_uid, eta_i, eta_o, xsi_i, xsi_o, xsi_hi, xsi_ho = row

                    # Update the xsi values
                    l_i = control_len[i]
                    l_o = control_len[i+1]

                    xsi_i = lin_interpol((xsi_inner, xsi_outer), (0, l), l_i)
                    xsi_o = lin_interpol((xsi_inner, xsi_outer), (0, l), l_o)
                    xsi_hi = lin_interpol((xsi_h1, xsi_h2), (0, l), l_i)
                    xsi_ho = lin_interpol((xsi_h1, xsi_h2), (0, l), l_o)

                    list_of_segments[i] = [segment_uid, eta_i, eta_o, xsi_i, xsi_o, xsi_hi, xsi_ho]

            # Finally, we create the subdivisions using our list
            for row in list_of_segments:
                segment_uid, eta_i, eta_o, xsi_i, xsi_o, xsi_h1, xsi_h2 = row

                wing.segments[segment_uid].add_subdivision_for_control(
                        eta_i, eta_o, control, xsi_i, xsi_o, xsi_h1, xsi_h2)

    # ===== PART TWO (ADDITIONAL SPANWISE SUBDIVISIONS) =====

    # - Adding additional spanwise subdivisions is done here in Python rather
    #   than in the C code as it is more convenient to keep track of which
    #   parts (subareas) of the discretised surface have which functions
    for this_segment, _ in ot.all_segments(aircraft):
        segment = this_segment[2]

        for eta in np.linspace(0, 1, segment.panels['num_s']+1):
            if (eta == 0) or (eta == 1):
                continue
            segment.add_subdivision(eta, eta, ignore_inval_eta=True)