def types():
    ### NumPy data types
    scalar_np = np.array(1)
    vector_np = np.array([1, 1])
    matrix_np = np.ones((2, 2))

    ### CasADi data types
    opti = Opti()
    scalar_cas = opti.variable(init_guess=1)
    vector_cas = opti.variable(n_vars=2, init_guess=1)

    ### Dynamically-typed data type creation (i.e. type depends on inputs)
    vector_dynamic = np.array([scalar_cas,
                               scalar_cas])  # vector as a dynamic-typed array
    matrix_dynamic = np.array([  # matrix as an dynamic-typed array
        [scalar_cas, scalar_cas], [scalar_cas, scalar_cas]
    ])

    ### Create lists of possible variable types for scalars, vectors, and matrices.
    scalar_options = [scalar_cas, scalar_np]
    vector_options = [vector_cas, vector_np, vector_dynamic]
    matrix_options = [matrix_np, matrix_dynamic]

    return {
        "scalar": scalar_options,
        "vector": vector_options,
        "matrix": matrix_options,
        "all": scalar_options + vector_options + matrix_options
    }
Ejemplo n.º 2
0
def test_where_numpy():
    a = np.ones(4)
    b = 2 * np.ones(4)

    c = np.where(np.array([True, False, True, False]), a, b)

    assert np.all(c == np.array([1, 2, 1, 2]))
Ejemplo n.º 3
0
def test_array_numpy_equivalency_2D():
    inputs = [[1, 2], [3, 4]]

    a = array(inputs)
    a_np = np.array(inputs)

    assert np.all(a == a_np)
Ejemplo n.º 4
0
    def draw_streamlines(self, res=200, show=True):
        fig, ax = plt.subplots(1, 1, figsize=(6.4, 4.8), dpi=200)

        plt.xlim(-0.5, 1.5)
        plt.ylim(-0.5, 0.5)
        xrng = np.diff(np.array(ax.get_xlim()))
        yrng = np.diff(np.array(ax.get_ylim()))

        x = np.linspace(*ax.get_xlim(), int(np.round(res * xrng / yrng)))
        y = np.linspace(*ax.get_ylim(), res)

        X, Y = np.meshgrid(x, y)
        shape = X.shape
        X = X.flatten()
        Y = Y.flatten()

        U, V = self.calculate_velocity(X, Y)
        X = X.reshape(shape)
        Y = Y.reshape(shape)
        U = U.reshape(shape)
        V = V.reshape(shape)

        # NaN out any points inside the airfoil
        for airfoil in self.airfoils:
            contains = airfoil.contains_points(X, Y)
            U[contains] = np.NaN
            V[contains] = np.NaN

        speed = (U**2 + V**2)**0.5
        Cp = 1 - speed**2

        ### Draw the airfoils
        for airfoil in self.airfoils:
            plt.fill(airfoil.x(), airfoil.y(), "k", linewidth=0, zorder=4)

        plt.streamplot(
            x,
            y,
            U,
            V,
            color=speed,
            density=2.5,
            arrowsize=0,
            cmap=plt.get_cmap('coolwarm_r'),
        )
        CB = plt.colorbar(
            orientation="horizontal",
            shrink=0.8,
            aspect=40,
        )
        CB.set_label(r"Relative Airspeed ($U/U_\infty$)")
        plt.clim(0.6, 1.4)

        plt.gca().set_aspect('equal', adjustable='box')
        plt.xlabel(r"$x/c$")
        plt.ylabel(r"$y/c$")
        plt.title(rf"Inviscid Airfoil: Flow Field")
        plt.tight_layout()
        if show:
            plt.show()
Ejemplo n.º 5
0
    def contains_points(
        self,
        x: Union[float, np.ndarray],
        y: Union[float, np.ndarray],
    ) -> np.ndarray:
        """
        Returns a boolean array of whether or not some (x, y) point(s) are contained within the Polygon.

        Args:
            x: x-coordinate(s) of the query points.
            y: y-coordinate(s) of the query points.

        Returns: A boolean array of the same size as x and y.

        """
        x = np.array(x)
        y = np.array(y)
        try:
            input_shape = (x + y).shape
        except ValueError as e:  # If arrays are not broadcastable
            raise ValueError(
                "Inputs x and y could not be broadcast together!") from e

        x = x.reshape(-1, 1)
        y = y.reshape(-1, 1)

        points = np.hstack((x, y))

        contained = path.Path(
            vertices=self.coordinates).contains_points(points)
        contained = np.array(contained).reshape(input_shape)

        return contained
Ejemplo n.º 6
0
def test_basic_logicals_numpy():
    a = np.array([True, True, False, False])
    b = np.array([True, False, True, False])

    assert np.all(
        a & b == np.array([True, False, False, False])
    )
Ejemplo n.º 7
0
    def __init__(
        self,
        xyz_le: np.ndarray = np.array([0, 0, 0]),
        chord: float = 1.,
        twist_angle: float = 0,
        twist_axis: np.ndarray = np.array([0, 1, 0]),
        airfoil: Airfoil = Airfoil("naca0012"),
        control_surface_is_symmetric: bool = True,
        control_surface_hinge_point: float = 0.75,
        control_surface_deflection: float = 0.,
    ):
        """
        Initialize a new wing cross section.
        Args:
            xyz_le: xyz-coordinates of the leading edge of the cross section, relative to the wing's datum.
            chord: Chord of the wing at this cross section
            twist_angle: Twist angle, in degrees, as defined about the leading edge.
            twist_axis: The twist axis vector, used if twist_angle != 0.
            airfoil: Airfoil associated with this cross section. [aerosandbox.Airfoil]
            control_surface_is_symmetric: Is the control surface symmetric? (e.g. True for flaps, False for ailerons.)
            control_surface_hinge_point: The location of the control surface hinge, as a fraction of chord.
            control_surface_deflection: Control deflection, in degrees. Downwards-positive.
        """

        self.xyz_le = xyz_le
        self.chord = chord
        self.twist = twist_angle
        self.twist_axis = twist_axis
        self.airfoil = airfoil
        self.control_surface_is_symmetric = control_surface_is_symmetric
        self.control_surface_hinge_point = control_surface_hinge_point
        self.control_surface_deflection = control_surface_deflection
Ejemplo n.º 8
0
def test_numpy_equivalency_1D():
    inputs = [1, 2]

    a = array(inputs)
    a_np = np.array(inputs)

    assert np.all(a == a_np)
Ejemplo n.º 9
0
def test_general_3D_shorthands():
    rotx = np.rotation_matrix_3D(1, np.array([1, 0, 0]))
    assert pytest.approx(rotx) == np.rotation_matrix_3D(1, "x")

    roty = np.rotation_matrix_3D(1, np.array([0, 1, 0]))
    assert pytest.approx(roty) == np.rotation_matrix_3D(1, "y")

    rotz = np.rotation_matrix_3D(1, np.array([0, 0, 1]))
    assert pytest.approx(rotz) == np.rotation_matrix_3D(1, "z")
def chain_conversion(axes: List[str] = ["geometry", "body", "geometry"]):
    x, y, z = copy.deepcopy(vector)
    for from_axes, to_axes in zip(axes, axes[1:]):
        x, y, z = op_point.convert_axes(x_from=x,
                                        y_from=y,
                                        z_from=z,
                                        from_axes=from_axes,
                                        to_axes=to_axes)
    return np.array(vector) == pytest.approx(np.array([x, y, z]))
Ejemplo n.º 11
0
def test_interpolated_model_at_vector():
    model = interpolated_model()
    x_data = {
        "x1": np.array([1.5, 2.5]),
        "x2": np.array([2.5, 3.5]),
    }
    assert np.all(
        model(x_data) == pytest.approx(underlying_function_2D(
            *x_data.values())))
def test_uniform_forward_difference_first_degree():
    assert np.finite_difference_coefficients(
        x=np.arange(2), x0=0,
        derivative_degree=1) == pytest.approx(np.array([-1, 1]))
    assert np.finite_difference_coefficients(
        x=np.arange(9), x0=0, derivative_degree=1) == pytest.approx(
            np.array([
                -761 / 280, 8, -14, 56 / 3, -35 / 2, 56 / 5, -14 / 3, 8 / 7,
                -1 / 8
            ]))
def test_uniform_central_difference():
    assert np.finite_difference_coefficients(
        x=[-1, 0, 1], x0=0,
        derivative_degree=1) == pytest.approx(np.array([-0.5, 0, 0.5]))
    assert np.finite_difference_coefficients(
        x=[-1, 0, 1], x0=0,
        derivative_degree=2) == pytest.approx(np.array([1, -2, 1]))
    assert np.finite_difference_coefficients(
        x=[-2, -1, 0, 1, 2], x0=0, derivative_degree=2) == pytest.approx(
            np.array([-1 / 12, 4 / 3, -5 / 2, 4 / 3, -1 / 12]))
Ejemplo n.º 14
0
def test_length():
    assert length(5) == 1
    assert length(5.) == 1
    assert length([1, 2, 3]) == 3

    assert length(np.array(5)) == 1
    assert length(np.array([5])) == 1
    assert length(np.array([1, 2, 3])) == 3
    assert length(np.ones((3, 2))) == 3

    assert length(cas.GenMX_ones(5)) == 5
Ejemplo n.º 15
0
def main():
    time = np.linspace(0, 10, 100)  # Time in seconds
    wing_velocity = 2  # Wing horizontal velocity in m/s
    chord = 2
    reduced_time = calculate_reduced_time(
        time, wing_velocity, chord)  # Number of semi chords travelled

    # Visualize the gust profiles as well as the pitch maneuvers
    fig, ax1 = plt.subplots(dpi=300)
    ln1 = ax1.plot(reduced_time,
                   np.array([top_hat_gust(s) for s in reduced_time]),
                   label="Top-Hat Gust",
                   lw=3)
    ln2 = ax1.plot(reduced_time,
                   np.array([sine_squared_gust(s) for s in reduced_time]),
                   label="Sine-Squared Gust",
                   lw=3)
    ax1.set_xlabel("Reduced time")
    ax1.set_ylabel("Velocity (m/s)")
    ax2 = ax1.twinx()
    ln3 = ax2.plot(reduced_time,
                   np.array([gaussian_pitch(s) for s in reduced_time]),
                   label="Guassian Pitch",
                   c="red",
                   ls="--",
                   lw=3)
    ax2.set_ylabel("Angle of Attack, degrees")
    lns = ln1 + ln2 + ln3
    labs = [l.get_label() for l in lns]
    ax2.legend(lns, labs, loc="lower right")
    plt.title("Gust and pitch example profiles")

    total_lift = pitching_through_transverse_gust(reduced_time, top_hat_gust,
                                                  wing_velocity,
                                                  gaussian_pitch)
    gust_lift = calculate_lift_due_to_transverse_gust(reduced_time,
                                                      top_hat_gust,
                                                      wing_velocity,
                                                      gaussian_pitch)
    pitch_lift = calculate_lift_due_to_pitching_profile(
        reduced_time, gaussian_pitch)
    added_mass_lift = added_mass_due_to_pitching(reduced_time, gaussian_pitch)

    # Visualize the different sources of lift
    plt.figure(dpi=300)
    plt.plot(reduced_time, total_lift, label="Total Lift", lw=2)
    plt.plot(reduced_time, gust_lift, label="Gust Lift", lw=2)
    plt.plot(reduced_time, pitch_lift, label="Pitching Lift", lw=2)
    plt.plot(reduced_time, added_mass_lift, label="Added Mass Lift", lw=2)
    plt.legend()
    plt.xlabel("Reduced time")
    plt.ylabel("$C_\ell$")
    plt.title("Guassian Pitch Maneuver Through Top-Hat Gust")
Ejemplo n.º 16
0
    def draw(self, draw_mcl=True, backend="matplotlib", show=True):
        """
        Draw the airfoil object.
        :param draw_mcl: Should we draw the mean camber line (MCL)? [boolean]
        :param backend: Which backend should we use? "plotly" or "matplotlib"
        :return: None
        """
        x = np.array(self.x()).reshape(-1)
        y = np.array(self.y()).reshape(-1)
        if draw_mcl:
            x_mcl = np.linspace(np.min(x), np.max(x), len(x))
            y_mcl = self.local_camber(x_mcl)

        if backend == "matplotlib":
            color = '#280887'
            plt.plot(x, y, ".-", zorder=11, color=color)
            plt.fill(x, y, zorder=10, color=color, alpha=0.2)
            if draw_mcl:
                plt.plot(x_mcl, y_mcl, "-", zorder=4, color=color, alpha=0.4)
            plt.axis("equal")
            plt.xlabel(r"$x/c$")
            plt.ylabel(r"$y/c$")
            plt.title(f"{self.name} Airfoil")
            plt.tight_layout()
            if show:
                plt.show()

        elif backend == "plotly":
            from aerosandbox.visualization.plotly import go
            fig = go.Figure()
            fig.add_trace(
                go.Scatter(x=x,
                           y=y,
                           mode="lines+markers",
                           name="Airfoil",
                           fill="toself",
                           line=dict(color="blue")), )
            if draw_mcl:
                fig.add_trace(
                    go.Scatter(x=x_mcl,
                               y=y_mcl,
                               mode="lines+markers",
                               name="Mean Camber Line (MCL)",
                               line=dict(color="navy")))
            fig.update_layout(xaxis_title="x/c",
                              yaxis_title="y/c",
                              yaxis=dict(scaleanchor="x", scaleratio=1),
                              title=f"{self.name} Airfoil")
            if show:
                fig.show()
            else:
                return fig
Ejemplo n.º 17
0
def test_euler_angles_equivalence_to_general_3D():
    phi = 1
    theta = 2
    psi = 3

    rot_euler = np.rotation_matrix_from_euler_angles(phi, theta, psi)
    rot_manual = (
            np.rotation_matrix_3D(psi, np.array([0, 0, 1])) @
            np.rotation_matrix_3D(theta, np.array([0, 1, 0])) @
            np.rotation_matrix_3D(phi, np.array([1, 0, 0]))
    )

    assert rot_euler == pytest.approx(rot_manual)
Ejemplo n.º 18
0
def test_cross_1D_input():
    a = np.array([1, 1, 1])
    b = np.array([1, 2, 3])

    cas_a = cas.DM(a)
    cas_b = cas.DM(b)

    correct_result = np.cross(a, b)
    cas_correct_result = cas.DM(correct_result)

    assert np.all(np.cross(a, cas_b) == cas_correct_result)
    assert np.all(np.cross(cas_a, b) == cas_correct_result)
    assert np.all(np.cross(cas_a, cas_b) == cas_correct_result)
Ejemplo n.º 19
0
def test_cross_2D_input_first_axis():
    a = np.tile(np.array([1, 1, 1]), (3, 1)).T
    b = np.tile(np.array([1, 2, 3]), (3, 1)).T

    cas_a = cas.DM(a)
    cas_b = cas.DM(b)

    correct_result = np.cross(a, b, axis=0)
    cas_correct_result = cas.DM(correct_result)

    assert np.all(np.cross(a, cas_b, axis=0) == cas_correct_result)
    assert np.all(np.cross(cas_a, b, axis=0) == cas_correct_result)
    assert np.all(np.cross(cas_a, cas_b, axis=0) == cas_correct_result)
Ejemplo n.º 20
0
 def draw(self, draw_mcl=True, backend="plotly", show=True):
     """
     Draw the airfoil object.
     :param draw_mcl: Should we draw the mean camber line (MCL)? [boolean]
     :param backend: Which backend should we use? "plotly" or "matplotlib"
     :return: None
     """
     x = np.array(self.x()).reshape(-1)
     y = np.array(self.y()).reshape(-1)
     if draw_mcl:
         x_mcl = np.linspace(np.min(x), np.max(x), len(x))
         y_mcl = self.local_camber(x_mcl)
     if backend == "plotly":
         fig = go.Figure()
         fig.add_trace(
             go.Scatter(x=x,
                        y=y,
                        mode="lines+markers",
                        name="Airfoil",
                        fill="toself",
                        line=dict(color="blue")), )
         if draw_mcl:
             fig.add_trace(
                 go.Scatter(x=x_mcl,
                            y=y_mcl,
                            mode="lines+markers",
                            name="Mean Camber Line (MCL)",
                            line=dict(color="navy")))
         fig.update_layout(xaxis_title="x/c",
                           yaxis_title="y/c",
                           yaxis=dict(scaleanchor="x", scaleratio=1),
                           title="%s Airfoil" % self.name)
         if show:
             fig.show()
         else:
             return fig
     elif backend == "matplotlib":
         fig, ax = plt.subplots(1, 1, figsize=(6.4, 4.8), dpi=200)
         plt.plot(x, y, ".-", zorder=11, color='#280887')
         if draw_mcl:
             plt.plot(x_mcl, y_mcl, "-", zorder=4, color='#28088744')
         plt.axis("equal")
         plt.xlabel(r"$x/c$")
         plt.ylabel(r"$y/c$")
         plt.title("%s Airfoil" % self.name)
         plt.tight_layout()
         if show:
             plt.show()
         else:
             return fig, ax
Ejemplo n.º 21
0
 def xyz_te(self) -> np.ndarray:
     """
     Returns the (wing-relative) coordinates of the trailing edge of the cross section.
     """
     rot = np.rotation_matrix_3D(self.twist * pi / 180, self.twist_axis)
     xyz_te = self.xyz_le + rot @ np.array([self.chord, 0, 0])
     return xyz_te
Ejemplo n.º 22
0
def test_interpn_bounds_error_multiple_samples():
    def value_func_3d(x, y, z):
        return 2 * x + 3 * y - z

    x = np.linspace(0, 5, 10)
    y = np.linspace(0, 5, 20)
    z = np.linspace(0, 5, 30)
    points = (x, y, z)
    values = value_func_3d(*np.meshgrid(*points, indexing="ij"))

    point = np.array([
        [2.21, 3.12, 1.15],
        [3.42, 5.81, 2.43]
    ])
    with pytest.raises(ValueError):
        value = np.interpn(
            points, values, point
        )

    ### CasADi test
    point = cas.DM(point)
    with pytest.raises(ValueError):
        value = np.interpn(
            points, values, point
        )
Ejemplo n.º 23
0
def get_coordinates_from_raw_dat(raw_text) -> np.ndarray:
    """
    Returns a Nx2 ndarray of airfoil coordinates from the raw text of a airfoil *.dat file.
    Args:
        raw_text: The raw text of the *.dat file, as read by file.readlines()

    Returns: A Nx2 ndarray of airfoil coordinates [x, y].

    """
    raw_coordinates = []

    def is_number(
            s):  # determines whether a string is representable as a float
        try:
            float(s)
        except ValueError:
            return False
        return True

    for line in raw_text:
        try:
            line_split = re.split(r'[; |, |\*|\n]', line)
            line_items = [s for s in line_split if s != "" and is_number(s)]
            if len(line_items) == 2:
                raw_coordinates.append(line_items)
        except:
            pass

    if len(raw_coordinates) == 0:
        raise ValueError("File was found, but could not read any coordinates!")

    coordinates = np.array(raw_coordinates, dtype=float)

    return coordinates
Ejemplo n.º 24
0
def test_reshape():
    a = np.array([
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9],
        [10, 11, 12],
    ])
    b = cas.DM(a)

    test_inputs = [
        -1,
        (4, 3),
        (3, 4),
        (12, 1),
        (1, 12),
        (-1),
        (12, -1),
        (-1, 12),
    ]

    for i in test_inputs:
        ra = np.reshape(a, i)
        rb = np.reshape(b, i)
        if len(ra.shape) == 1:
            ra = ra.reshape(-1, 1)

        assert np.all(ra == rb)
Ejemplo n.º 25
0
def test_assert_equal_shape():
    a = np.array([1, 2, 3])
    b = cas.DM(a)

    np.assert_equal_shape([a, a])
    np.assert_equal_shape({
        "thing1": a,
        "thing2": a,
    })
    with pytest.raises(ValueError):
        np.assert_equal_shape([np.array([1, 2, 3]), np.array([1, 2, 3, 4])])
        np.assert_equal_shape({
            "thing1": np.array([1, 2, 3]),
            "thing2": np.array([1, 2, 3, 4])
        })
    np.assert_equal_shape([2, 3, 4])
Ejemplo n.º 26
0
def test_sum2():
    # Check it returns the same results with casadi and numpy
    a = np.array([[1, 2, 3], [1, 2, 3]])
    b = cas.SX(a)

    assert np.all(np.sum(a) == cas.DM(np.sum(b)))
    assert np.all(np.sum(a, axis=1) == cas.DM(np.sum(b, axis=1)))
Ejemplo n.º 27
0
def convert_mesh_to_polydata_format(
        points,
        faces
):
    """
    Pyvista uses a slightly different convention for the standard (points, faces) format as described above. They
    give `faces` as a single 1D vector of roughly length (M*3), or (M*4) in the case of quadrilateral meshing.
    Basically, the mesh displayer goes down the `faces` array, and when it sees a number N, it interprets that as the
    number of vertices in the following face. Then, the next N entries are interpreted as integer references to the
    vertices of the face.

    This has the benefit of allowing for mixed tri/quad meshes.

    Args:
        points: `points` array of the original standard-format mesh
        faces: `faces` array of the original standard-format mesh

    Returns:

        (points, faces), except that `faces` is now in a pyvista.PolyData compatible format.

    """
    faces = [
        [len(face), *face]
        for face in faces
    ]
    faces = np.array(faces)
    faces = np.reshape(faces, -1)
    return points, faces
Ejemplo n.º 28
0
    def rotate(self,
               angle: float,
               x_center: float = 0.,
               y_center: float = 0.) -> 'Airfoil':
        """
        Rotates the airfoil clockwise by the specified amount, in radians.

        Rotates about the point (x_center, y_center), which is (0, 0) by default.

        Args:
            angle: Angle to rotate, counterclockwise, in radians.

            x_center: The x-coordinate of the center of rotation.

            y_center: The y-coordinate of the center of rotation.

        Returns: The rotated Airfoil.

        """

        coordinates = np.copy(self.coordinates)

        ### Translate
        translation = np.array([x_center, y_center])
        coordinates -= translation

        ### Rotate
        rotation_matrix = np.rotation_matrix_2D(angle=angle, )
        coordinates = (rotation_matrix @ coordinates.T).T

        ### Translate
        coordinates += translation

        return Airfoil(name=self.name, coordinates=coordinates)
Ejemplo n.º 29
0
def test_interpn_fill_value():
    def value_func_3d(x, y, z):
        return 2 * x + 3 * y - z

    x = np.linspace(0, 5, 10)
    y = np.linspace(0, 5, 20)
    z = np.linspace(0, 5, 30)
    points = (x, y, z)
    values = value_func_3d(*np.meshgrid(*points, indexing="ij"))

    point = np.array([5.21, 3.12, 1.15])

    value = np.interpn(
        points, values, point,
        method="bspline",
        bounds_error=False,
        fill_value=-17
    )
    assert value == pytest.approx(-17)

    value = np.interpn(
        points, values, point,
        method="bspline",
        bounds_error=False,
    )
    assert np.isnan(value)

    value = np.interpn(
        points, values, point,
        method="bspline",
        bounds_error=None,
        fill_value=None
    )
    assert value == pytest.approx(value_func_3d(5, 3.12, 1.15))
Ejemplo n.º 30
0
def test_cas_vector():
    output = reflect_over_XZ_plane(cas.DM(vec))
    assert isinstance(output, cas.DM)
    assert np.all(
        output ==
        np.array([0, -1, 2])
    )