def test_fuselage_aerodynamics_optimization():
    opti = asb.Opti()

    alpha = opti.variable(init_guess=0, lower_bound=0, upper_bound=30)
    beta = opti.variable(init_guess=0)

    fuselage = asb.Fuselage(xsecs=[
        asb.FuselageXSec(xyz_c=[xi, 0, 0],
                         radius=asb.Airfoil("naca0010").local_thickness(
                             0.8 * xi)) for xi in np.cosspace(0, 1, 20)
    ], )

    aero = asb.AeroBuildup(airplane=asb.Airplane(fuselages=[fuselage]),
                           op_point=asb.OperatingPoint(velocity=10,
                                                       alpha=alpha,
                                                       beta=beta)).run()

    opti.minimize(-aero["L"] / aero["D"])
    sol = opti.solve(verbose=False)
    print(sol.value(alpha))
    assert sol.value(alpha) > 10 and sol.value(alpha) < 20
    assert sol.value(beta) == pytest.approx(0, abs=1e-3)

    opti.minimize(aero["D"])
    sol = opti.solve(verbose=False)
    assert sol.value(alpha) == pytest.approx(0, abs=1e-2)
    assert sol.value(beta) == pytest.approx(0, abs=1e-2)
def test_airfoil_symmetric_NACA():
    a = asb.AirfoilInviscid(airfoil=[asb.Airfoil("naca0012").repanel(50)],
                            op_point=asb.OperatingPoint(
                                velocity=1,
                                alpha=0,
                            ))
    assert a.Cl == pytest.approx(0, abs=1e-8)
def test_airfoil_multielement():
    a = asb.AirfoilInviscid(airfoil=[
        asb.Airfoil("e423").repanel(n_points_per_side=50),
        asb.Airfoil("naca6408").repanel(n_points_per_side=25).scale(
            0.4, 0.4).rotate(np.radians(-20)).translate(0.9, -0.05),
    ],
                            op_point=asb.OperatingPoint(velocity=1, alpha=5))
示例#4
0
def test_conventional():
    from aerosandbox.aerodynamics.aero_3D.test_aero_3D.geometries.conventional import airplane
    analysis = asb.VortexLatticeMethod(
        airplane=airplane,
        op_point=asb.OperatingPoint(alpha=10),
    )
    return analysis.run()
示例#5
0
    def get_aero(alpha, taper_ratio):
        airplane = asb.Airplane(wings=[
            asb.Wing(symmetric=True,
                     xsecs=[
                         asb.WingXSec(
                             xyz_le=[-0.25, 0, 0],
                             chord=1,
                         ),
                         asb.WingXSec(
                             xyz_le=[-0.25 * taper_ratio, 1, 0],
                             chord=taper_ratio,
                         )
                     ])
        ])
        op_point = asb.OperatingPoint(
            velocity=1,
            alpha=alpha,
        )

        vlm = asb.VortexLatticeMethod(
            airplane,
            op_point,
            chordwise_resolution=6,
            spanwise_resolution=6,
        )
        return vlm.run()
示例#6
0
def test_flat_plate_mirrored():
    if not avl_present:
        return
    from aerosandbox.aerodynamics.aero_3D.test_aero_3D.geometries.flat_plate_mirrored import airplane
    analysis = asb.AVL(
        airplane=airplane,
        op_point=asb.OperatingPoint(alpha=10),
    )
    return analysis.run()
def test_order_wind_body():
    op_point = asb.OperatingPoint(
        alpha=90,
        beta=90,
    )
    x, y, z = op_point.convert_axes(0, 1, 0, "body", "wind")
    assert x == pytest.approx(1)
    assert y == pytest.approx(0)
    assert z == pytest.approx(0)
示例#8
0
def test_flat_plate_mirrored():
    from aerosandbox.aerodynamics.aero_3D.test_aero_3D.geometries.flat_plate_mirrored import airplane
    analysis = asb.VortexLatticeMethod(
        airplane=airplane,
        op_point=asb.OperatingPoint(alpha=10),
        spanwise_resolution=1,
        chordwise_resolution=3,
    )
    return analysis.run()
def LD_from_alpha(alpha):
    op_point = asb.OperatingPoint(
        velocity=1,
        alpha=alpha,
    )

    vlm = asb.VortexLatticeMethod(airplane,
                                  op_point,
                                  align_trailing_vortices_with_wind=True)
    aero = vlm.run()

    CD0 = 0.01

    LD = aero["CL"] / (aero["CD"] + CD0)
    return LD
示例#10
0
文件: solver.py 项目: KikeM/winglets
    def _solve(self, value, mode=None):
        """Create and solve a VLM3 problem for a given angle of attack
        or lift coefficient.

        Parameters
        ----------
        value : float
        mode : str
            [SolverMode.ALPHA, SolverMode.CL]

        Returns
        -------
        aero_problem : VLM3-like object
        """

        # Create vlm3-object
        if mode == SolverMode.ALPHA:

            atmosphere = self._atmosphere
            rho = atmosphere.density(T=atmosphere.T, P=atmosphere.P)

            aero_problem = sbx.vlm3(
                airplane=self.model.airplane,
                op_point=sbx.OperatingPoint(velocity=self.velocity,
                                            alpha=value,
                                            density=rho),
            )

        elif mode == SolverMode.CL:

            aero_problem = self._find_alpha_for_cl(cl=value)

        else:
            raise NotImplementedError("'mode' must be either 'alpha' or 'cl'.")

        # Solve
        aero_problem.run(verbose=False)

        self.CL = aero_problem.CL
        self.CDi = aero_problem.CDi
        self.CY = aero_problem.CY
        self.alpha = aero_problem.op_point.alpha

        return aero_problem
示例#11
0
import aerosandbox as asb
import aerosandbox.numpy as np

import matplotlib.pyplot as plt
import aerosandbox.tools.pretty_plots as p

fuselage = asb.Fuselage(xsecs=[
    asb.FuselageXSec(xyz_c=[xi, 0, 0],
                     radius=asb.Airfoil("naca0020").local_thickness(xi) / 2)
    for xi in np.cosspace(0, 1, 20)
], )

fig, ax = plt.subplots(figsize=(7, 6))
V = np.linspace(10, 1000, 1001)
op_point = asb.OperatingPoint(velocity=V, )

aero = asb.AeroBuildup(
    airplane=asb.Airplane(fuselages=[fuselage]),
    op_point=op_point,
).run()

plt.plot(op_point.mach(), aero["CD"], label="Full Model")

aero = asb.AeroBuildup(airplane=asb.Airplane(fuselages=[fuselage]),
                       op_point=op_point,
                       include_wave_drag=False).run()

plt.plot(op_point.mach(),
         aero["CD"],
         zorder=1.9,
         label="Model without Wave Drag")
示例#12
0
#
#
#
#
# aero_problem.run()

aleph = np.linspace(0, 15, 16)
sol = pd.DataFrame(columns=['alpha', 'cl', 'cdi', 'cl/cdi'])

for a in aleph:
    aero_problem = ae.vlm3(  # Analysis type: Vortex Lattice Method, version 3
        airplane=testPlane,
        op_point=ae.OperatingPoint(
            velocity=4.5,
            alpha=a,
            beta=0,
            p=0,
            q=0,
            r=0,
        ),
    )
    aero_problem.run()
    sol = sol.append(
        {
            'alpha': a,
            'cl': aero_problem.Cl,
            'cdi': aero_problem.CDi,
            'cl/cdi': (aero_problem.Cl / aero_problem.CDi)
        },
        ignore_index=True)

print(sol)
def test_airfoil_with_TE_gap():
    a = asb.AirfoilInviscid(airfoil=asb.Airfoil("naca4408").repanel(100),
                            op_point=asb.OperatingPoint(velocity=1, alpha=5))
    assert a.Cl == pytest.approx(1.0754, abs=0.01)  # From XFoil
def test_airfoil_ground_effect():
    a = asb.AirfoilInviscid(
        airfoil=asb.Airfoil("naca4408").repanel(100).translate(0, 0.2),
        op_point=asb.OperatingPoint(velocity=1, alpha=0),
        ground_effect=True)
    assert a.calculate_velocity(0, 0)[1] == pytest.approx(0)
示例#15
0
def test_aero_buildup():
    analysis = asb.AeroBuildup(
        airplane=airplane,
        op_point=asb.OperatingPoint(),
    )
    return analysis.run()
示例#16
0
def display_graph(n_clicks, alpha, height, streamline_density,
                  operating_checklist, *kulfan_inputs):
    ### Figure out if a button was pressed
    global n_clicks_last
    if n_clicks is None:
        n_clicks = 0

    analyze_button_pressed = n_clicks > n_clicks_last
    n_clicks_last = n_clicks

    ### Parse the checklist
    ground_effect = "ground_effect" in operating_checklist

    ### Start constructing the figure
    airfoil = asb.Airfoil(coordinates=asb.get_kulfan_coordinates(
        lower_weights=np.array(kulfan_inputs[n_kulfan_inputs_per_side:]),
        upper_weights=np.array(kulfan_inputs[:n_kulfan_inputs_per_side]),
        TE_thickness=0,
        enforce_continuous_LE_radius=False,
        n_points_per_side=200,
    ))

    ### Do coordinates output
    coordinates_output = "\n".join(
        ["```"] + ["AeroSandbox Airfoil"] +
        ["\t%f\t%f" % tuple(coordinate)
         for coordinate in airfoil.coordinates] + ["```"])

    ### Continue doing the airfoil things
    airfoil = airfoil.rotate(angle=-np.radians(alpha))
    airfoil = airfoil.translate(0, height + 0.5 * np.sind(alpha))
    fig = go.Figure()
    fig.add_trace(
        go.Scatter(
            x=airfoil.x(),
            y=airfoil.y(),
            mode="lines",
            name="Airfoil",
            fill="toself",
            line=dict(color="blue"),
        ))

    ### Default text output
    text_output = 'Click "Analyze" to compute aerodynamics!'

    xrng = (-0.5, 1.5)
    yrng = (-0.6, 0.6) if not ground_effect else (0, 1.2)

    if analyze_button_pressed:

        analysis = asb.AirfoilInviscid(
            airfoil=airfoil.repanel(50),
            op_point=asb.OperatingPoint(
                velocity=1,
                alpha=0,
            ),
            ground_effect=ground_effect,
        )

        x = np.linspace(*xrng, 100)
        y = np.linspace(*yrng, 100)
        X, Y = np.meshgrid(x, y)
        u, v = analysis.calculate_velocity(x_field=X.flatten(),
                                           y_field=Y.flatten())
        U = u.reshape(X.shape)
        V = v.reshape(Y.shape)

        streamline_fig = ff.create_streamline(
            x,
            y,
            U,
            V,
            arrow_scale=1e-16,
            density=streamline_density,
            line=dict(color="#ff82a3"),
            name="Streamlines",
        )

        fig = go.Figure(data=streamline_fig.data + fig.data)

        text_output = make_table(
            pd.DataFrame({
                "Engineering Quantity": ["C_L"],
                "Value": [f"{analysis.Cl:.3f}"]
            }))

    fig.update_layout(
        xaxis_title="x/c",
        yaxis_title="y/c",
        showlegend=False,
        yaxis=dict(scaleanchor="x", scaleratio=1),
        margin={"t": 0},
        title=None,
    )

    fig.update_xaxes(range=xrng)
    fig.update_yaxes(range=yrng)

    return fig, text_output, [coordinates_output]
    analysis = asb.VortexLatticeMethod(
        airplane=airplane,
        op_point=asb.OperatingPoint(alpha=10),
    )
    return analysis.run()


def test_flat_plate_mirrored():
    from aerosandbox.aerodynamics.aero_3D.test_aero_3D.geometries.flat_plate_mirrored import airplane
    analysis = asb.VortexLatticeMethod(
        airplane=airplane,
        op_point=asb.OperatingPoint(alpha=10),
        spanwise_resolution=1,
        chordwise_resolution=3,
    )
    return analysis.run()


if __name__ == '__main__':
    # test_conventional()
    # test_vanilla()
    # test_flat_plate()['CL']
    # test_flat_plate_mirrored()
    # pytest.main()
    from aerosandbox.aerodynamics.aero_3D.test_aero_3D.geometries.conventional import airplane
    analysis = asb.VortexLatticeMethod(
        airplane=airplane,
        op_point=asb.OperatingPoint(alpha=10),
    )
    aero = analysis.run()
    analysis.draw()
def test_beta_stability_body():
    op_point = asb.OperatingPoint(alpha=0, beta=90)
    x, y, z = op_point.convert_axes(0, 1, 0, "body", "stability")
    assert x == pytest.approx(0)
    assert y == pytest.approx(1)
    assert z == pytest.approx(0)
def display_geometry(
    display_geometry,
    run_ll_analysis,
    run_vlm_analysis,
    n_booms,
    wing_span,
    alpha,
):
    ### Figure out which button was clicked
    try:
        button_pressed = np.argmax(
            np.array([
                float(display_geometry),
                float(run_ll_analysis),
                float(run_vlm_analysis),
            ]))
        assert button_pressed is not None
    except:
        button_pressed = 0

    ### Make the airplane
    airplane = make_airplane(
        n_booms=n_booms,
        wing_span=wing_span,
    )
    op_point = asb.OperatingPoint(
        density=0.10,
        velocity=20,
        alpha=alpha,
    )
    if button_pressed == 0:
        # Display the geometry
        figure = airplane.draw(show=False, colorbar_title=None)
        output = "Please run an analysis to display the data."
    elif button_pressed == 1:
        # Run an analysis
        opti = cas.Opti()  # Initialize an analysis/optimization environment
        ap = asb.Casll1(airplane=airplane,
                        op_point=op_point,
                        opti=opti,
                        run_setup=False)
        ap.setup(verbose=False)
        # Solver options
        p_opts = {}
        s_opts = {}
        # s_opts["mu_strategy"] = "adaptive"
        opti.solver('ipopt', p_opts, s_opts)
        # Solve
        try:
            sol = opti.solve()
            output = make_table(
                pd.DataFrame({
                    "Figure": ["CL", "CD", "CDi", "CDp", "L/D"],
                    "Value": [
                        sol.value(ap.CL),
                        sol.value(ap.CD),
                        sol.value(ap.CDi),
                        sol.value(ap.CDp),
                        sol.value(ap.CL / ap.CD),
                    ]
                }))
        except:
            sol = opti.debug
            output = html.P(
                "Aerodynamic analysis failed! Most likely the airplane is stalled at this flight condition."
            )

        figure = ap.draw(show=False)  # Generates figure

    elif button_pressed == 2:
        # Run an analysis
        opti = cas.Opti()  # Initialize an analysis/optimization environment
        ap = asb.Casvlm1(airplane=airplane,
                         op_point=op_point,
                         opti=opti,
                         run_setup=False)
        ap.setup(verbose=False)
        # Solver options
        p_opts = {}
        s_opts = {}
        s_opts["max_iter"] = 50
        # s_opts["mu_strategy"] = "adaptive"
        opti.solver('ipopt', p_opts, s_opts)
        # Solve
        try:
            sol = opti.solve()
            output = make_table(
                pd.DataFrame({
                    "Figure": ["CL", "CDi", "L/Di"],
                    "Value": [
                        sol.value(ap.CL),
                        sol.value(ap.CDi),
                        sol.value(ap.CL / ap.CDi),
                    ]
                }))
        except:
            sol = opti.debug
            output = html.P(
                "Aerodynamic analysis failed! Most likely the airplane is stalled at this flight condition."
            )

        figure = ap.draw(show=False)  # Generates figure

    figure.update_layout(
        autosize=True,
        # width=1000,
        # height=700,
        margin=dict(
            l=0,
            r=0,
            b=0,
            t=0,
        ))

    return (figure, output)
import matplotlib.pyplot as plt
import aerosandbox.tools.pretty_plots as p

fuselage = asb.Fuselage(xsecs=[
    asb.FuselageXSec(xyz_c=[xi, 0, 0],
                     radius=asb.Airfoil("naca0010").local_thickness(xi))
    for xi in np.cosspace(0, 1, 20)
], )

fig, ax = plt.subplots(figsize=(7, 6))
Beta, Alpha = np.meshgrid(np.linspace(-90, 90, 500), np.linspace(-90, 90, 500))
aero = asb.AeroBuildup(airplane=asb.Airplane(fuselages=[fuselage]),
                       op_point=asb.OperatingPoint(
                           velocity=10,
                           alpha=Alpha,
                           beta=Beta,
                       )).run()

from aerosandbox.tools.string_formatting import eng_string

p.contour(
    Beta,
    Alpha,
    aero["L"],
    colorbar_label="Lift $L$ [N]",
    # levels=100,
    linelabels_format=lambda s: eng_string(s, unit="N"),
    cmap=plt.get_cmap("coolwarm"))
p.equal()
p.show_plot("3D Fuselage Lift", r"$\beta$ [deg]", r"$\alpha$ [deg]")
示例#21
0
from aerosandbox.aerodynamics.aero_3D.test_aero_3D.geometries.conventional import airplane
import aerosandbox as asb
import aerosandbox.numpy as np

for i, wing in enumerate(airplane.wings):
    for j, xsec in enumerate(wing.xsecs):
        af = xsec.airfoil
        af.generate_polars(
            cache_filename=f"cache/{af.name}.json",
            xfoil_kwargs=dict(xfoil_repanel="naca" in af.name.lower()))
        airplane.wings[i].xsecs[j].airfoil = af

op_point = asb.OperatingPoint(velocity=25, alpha=3)

vlm = asb.VortexLatticeMethod(
    airplane,
    op_point,
    align_trailing_vortices_with_wind=True,
    chordwise_resolution=12,
    spanwise_resolution=12,
)
vlm_aero = vlm.run()

ab = asb.AeroBuildup(airplane, op_point)
ab_aero = ab.run()

avl = asb.AVL(
    airplane,
    op_point,
)
avl_aero = avl.run()
示例#22
0
import aerosandbox as asb
import aerosandbox.numpy as np
from aerosandbox.aerodynamics.aero_3D.test_aero_3D.conventional import airplane

analysis = asb.AeroBuildup(
    airplane=airplane,
    op_point=asb.OperatingPoint(
        atmosphere=asb.Atmosphere(altitude=0, method="ISA"),
        velocity=10,  # m/s
        alpha=5,  # In degrees
        beta=0,  # In degrees
        p=0,  # About the body x-axis, in rad/sec
        q=0,  # About the body y-axis, in rad/sec
        r=0,  # About the body z-axis, in rad/sec
    ),
)
示例#23
0
    geometry_folder = Path(
        asb.__file__
    ).parent.parent / "tutorial" / "04 - Geometry" / "example_geometry"

    import sys

    sys.path.insert(0, str(geometry_folder))

    from vanilla import airplane as vanilla

    ### Do the AVL run
    analysis = VortexLatticeMethod(
        airplane=vanilla,
        op_point=asb.OperatingPoint(
            atmosphere=asb.Atmosphere(altitude=0),
            velocity=10,
            alpha=0,
            beta=0,
            p=0,
            q=0,
            r=0,
        ),
        spanwise_resolution=12,
        chordwise_resolution=12,
    )

    res = analysis.run()

    for k, v in res.items():
        print(f"{str(k).rjust(10)} : {v:.4f}")
示例#24
0
def op_point():

    return sbx.OperatingPoint(velocity=1.0, alpha=1.0, density=1.0)
示例#25
0
        pressure_total_2: The total pressure at the compressor inlet face, at the conditions to be evaluated. [Pa]

    Returns:

        The ratio `m_dot_corrected / m_dot`.

    """
    temperature_standard = 273.15 + 15
    pressure_standard = 101325
    return (temperature_total_2 /
            temperature_standard)**0.5 / (pressure_total_2 / pressure_standard)


if __name__ == '__main__':
    import aerosandbox as asb

    atmo = asb.Atmosphere(altitude=10668)
    op_point = asb.OperatingPoint(atmo, velocity=0.80 * atmo.speed_of_sound())
    m_dot_corrected_over_m_dot_ratio = m_dot_corrected_over_m_dot(
        temperature_total_2=op_point.total_temperature(),
        pressure_total_2=op_point.total_pressure())

    ### CFM56-2 engine test
    mass_cfm56_2 = mass_turbofan(  # Data here from Wikipedia, cross-referenced to other sources for sanity check.
        m_dot_core_corrected=364 / (5.95 + 1),
        overall_pressure_ratio=31.2,
        bypass_ratio=5.95,
        diameter_fan=1.73
    )  # real mass: (2139 to 2200 kg bare, ~3400 kg installed)
示例#26
0
def get_aero(xyz_ref):
    return asb.AeroBuildup(airplane=asb.Airplane(fuselages=[fuselage],
                                                 xyz_ref=xyz_ref),
                           op_point=asb.OperatingPoint(velocity=10,
                                                       alpha=5,
                                                       beta=5)).run()
示例#27
0
import aerosandbox as asb
import casadi as cas
from airplane import make_airplane

n_booms = 1
wing_span = 40
alpha = 5

airplane = make_airplane(n_booms=n_booms, wing_span=wing_span,)
op_point = asb.OperatingPoint(density=0.10, velocity=20, alpha=alpha,)

### LL
# Run an analysis
opti = cas.Opti()  # Initialize an analysis/optimization environment
# airplane.fuselages=[]
ap = asb.Casvlm1(airplane=airplane, op_point=op_point, opti=opti)
# Solver options
p_opts = {}
s_opts = {}
# s_opts["mu_strategy"] = "adaptive"
opti.solver("ipopt", p_opts, s_opts)
# Solve
try:
    sol = opti.solve()
except RuntimeError:
    sol = opti.debug
    raise Exception("An error occurred!")
# Postprocess
# ap.substitute_solution(sol)
ap.draw(show=False).show()
示例#28
0

def CD_function(alpha, Re, mach, deflection):
    return 0 * Re**0


def CM_function(alpha, Re, mach, deflection):
    return 0 * alpha


ideal_airfoil = asb.Airfoil(name="Ideal Airfoil",
                            coordinates=get_NACA_coordinates('naca0012'),
                            CL_function=CL_function,
                            CD_function=CD_function,
                            CM_function=CM_function)

wing = asb.Wing(xsecs=[
    asb.WingXSec(xyz_le=[0, y_i, 0], chord=1, airfoil=ideal_airfoil)
    for y_i in [0, 10]
],
                symmetric=True)

airplane = asb.Airplane(wings=[wing])

op_point = asb.OperatingPoint(velocity=340, alpha=0)

aero = asb.AeroBuildup(airplane=airplane, op_point=op_point).run()

from pprint import pprint

pprint(aero)
import aerosandbox as asb
import aerosandbox.numpy as np
from typing import List
import copy
import pytest

vector = [1, 2, 3]
op_point = asb.OperatingPoint(alpha=10, beta=5)


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]))


def test_basic():
    assert chain_conversion()


def test_geometry():
    assert chain_conversion(["body", "geometry", "body"])


def test_stability():
    assert chain_conversion(["body", "stability", "body"])
def test_alpha_wind():
    op_point = asb.OperatingPoint(alpha=90, beta=0)
    x, y, z = op_point.convert_axes(0, 0, 1, "geometry", "wind")
    assert x == pytest.approx(-1)
    assert y == pytest.approx(0)
    assert z == pytest.approx(0)