Beispiel #1
0
def mtow_plot(model):
    model.cost = model["MTOW"]
    fig, ax = plt.subplots()
    x = np.linspace(1, 15, 500)
    tol = 0.05
    time = 0.0
    nsolves = 0
    ws = []
    xs = []
    for p in [85, 90, 95]:
        wind = get_windspeed(38, p, 15000, 355)
        cwind = get_windspeed(38, p, np.linspace(0, 15000, 11)[1:], 355)
        for vk in model.varkeys["V_{wind}"]:
            if "Climb" in vk.models:
                model.substitutions.update({vk: cwind[vk.idx[0]]})
            else:
                model.substitutions.update({vk: wind})

        model.substitutions.update({"MTOW": 1000})
        model.cost = 1/model["t_Mission/Loiter"]
        sol = model.solve("mosek")
        time += sol["soltime"]
        nsolves += 1
        upper = sol("t_Mission/Loiter").magnitude
        xmin_ = x[x < upper + 0.03]
        xs.append(xmin_)

        del model.substitutions["MTOW"]
        model.cost = model["MTOW"]
        bst = autosweep_1d(model, tol, model["t_Mission/Loiter"],
                           [1, xmin_[-1]], solver="mosek")
        bsts = find_sols([bst])
        sols = np.hstack([b.sols for b in bsts])
        time += sum(np.unique([s["soltime"] for s in sols]))
        nsolves += bst.nsols
        ws.append(bst.sample_at(xmin_)["cost"])

    print "%d solves in %.4f seconds" % (nsolves, time)
    ax.fill_between(xs[0], ws[0],
                    np.append(ws[2], [1000]*(len(xs[0])-len(xs[2]))),
                    facecolor="r", edgecolor="None", alpha=0.3)
    ax.plot(xs[0], ws[0], "r")
    ax.plot(xs[1], ws[1], "r", lw=2)
    ax.plot(xs[2], ws[2], "r")
    for i, p in enumerate(["80%", "90%", "95%"]):
        weight = ws[i].magnitude
        we = 500 + min(abs(weight-500))
        if we not in weight:
            we = 500 - min(abs(weight-500))
        end = xs[i][weight == we][0]
        ax.annotate(p, xy=(end, we), xytext=(end+0.3, we+0.01),
                    arrowprops=dict(arrowstyle="-"), fontsize=12)
    ax.grid()
    ax.set_ylim([0, 1000])
    ax.set_xlabel("Endurance [days]")
    ax.set_ylabel("Max Take Off Weight [lbf]")
    return fig, ax
Beispiel #2
0
def gas_lat(model, cost, subs=None):
    plt.rcParams.update({'font.size': 15})
    fig, ax = plt.subplots()
    lat = np.arange(0, 60, 1)
    model.substitutions.update(subs)
    model.cost = model[cost]
    for a in [80, 90, 95]:
        mtow = []
        wind = []
        for l in lat:
            wind.append(get_windspeed(l, a, 15000, 355))
            maxwind = max(wind)
            for v in model.varkeys["V_{wind}"]:
                model.substitutions.update({v: maxwind})
            try:
                sol = model.solve("mosek")
                mtow.append(sol(cost).magnitude)
            except RuntimeWarning:
                mtow.append(np.nan)
        ax.plot(lat, mtow, lw=2)

    ax.set_xlabel("Latitude [deg]")
    labels = ["$\\pm$" + item.get_text() for item in ax.get_xticklabels()]
    labels = ["$\\pm$%d" % l for l in np.linspace(20, 45, len(labels))]
    ax.set_xticklabels(labels)
    ax.legend(["%d Percentile Winds" % a for a in [80, 90, 95]],
              loc=2,
              fontsize=15)

    return fig, ax
Beispiel #3
0
def fit_setup(altitude=(40000, 80000), latitude=45, day=355):
    """
    Function that sets up the fit for altitude versus density. Density in
    10^-1 kg/m^3

    Inputs
    ------
    altitude: tuple - two values for the upper and lower bound of altitude
              range (ex. (40000, 80000)). Altitude in ft
    latitude: int - latitude of earth in degrees
    percentage: int - percentile wind speeds

    Outputs
    ------
    x: 1D array of x values for fit
    y: 1D array of y values for fit

    """

    N = 20
    percentiles = range(75, 100, 5) + [99]
    altitude = np.linspace(altitude[0], altitude[1], N)
    df = pd.read_csv("usstd_atm.csv")
    wind = []
    ps = []
    for p in percentiles:
        wind.append(
            np.array(get_windspeed(latitude, p, altitude, day)) / WIND_NORM)
        ps.append([p / PERCT_NORM] * len(altitude))

    hm = altitude * 0.3048
    g = 9.80665  # m/s^2
    R = 287.04  # m^2/K/s^2
    T11 = 216.65  # K
    p = 22632 * np.exp(-g / R / T11 * (hm - 11000))
    density = p / R / T11 * RHO_NORM

    u1 = np.hstack([density] * len(percentiles))
    u2 = np.hstack(ps)
    w = np.hstack(wind)
    x = np.log([u1, u2])
    y = np.log(w)

    return x, y
Beispiel #4
0
def windalt_plot(latitude, sol1=None, sol2=None, p=0.90):
    plt.rcParams.update({'font.size': 15})
    alt = np.linspace(40000, 80000, 20)
    fig, ax = plt.subplots()
    if sol1:
        p = sol1("p_{wind}").items()[0][1]
        if sol2:
            sols = [sol1, sol2]
        else:
            sols = [sol1]
        for sol in sols:
            altsol = altitude(min([sol(sv).magnitude for sv in sol("\\rho")]))
            vsol = max([sol(sv).to("knots").magnitude for sv in sol("V")])
            ax.plot(altsol / 1000, vsol, "o", markersize=10, mfc="c")

    y = get_windspeed(latitude, np.round(p * 100), alt, 355)
    f = interpolate.interp1d(alt, y, "cubic")
    vwind = f(alt)
    l = ax.plot(alt / 1000.0, vwind * 1.95384, linewidth=2)
    ax.set_xlabel("Altitude [kft]")
    ax.set_ylabel("90th Percentile Wind Speed [knots]")
    ax.grid()
    ax.set_ylim([0, 200])
    return fig, ax
M = Mission()
M.cost = M["MTOW"]
M.substitutions.update({"W_{pay}": 10})
for e in M.varkeys["\\eta_{prop}"]:
    M.substitutions.update({e: 0.75})
for cd in M.varkeys["CDA_0"]:
    M.substitutions.update({cd: 0.01})
fig, ax = plt.subplots()
lower = 1
upper = 10
xmin_ = np.linspace(lower, upper, 100)
tol = 0.05
for p in [85, 90, 95]:
    notpassing = True
    while notpassing:
        wind = get_windspeed(38, p, 15000, 355)
        cwind = get_windspeed(38, p, np.linspace(0, 15000, 11)[1:], 355)
        for vk in M.varkeys["V_{wind}"]:
            if "Climb" in vk.models:
                M.substitutions.update({vk: cwind[vk.idx[0]]})
            else:
                M.substitutions.update({vk: wind})
        try:
            bst = sweep_1d(M,
                           tol,
                           M["t_Mission/Loiter"], [lower, upper],
                           solver="mosek")
            notpassing = False
        except RuntimeWarning:
            notpassing = True
            upper -= 0.1
Beispiel #6
0
def ld_plot(model, num):
    model.cost = 1/model["t_Mission/Loiter"]
    for e in model.varkeys["\\eta_{prop}"]:
        model.substitutions.update({e: 0.75})

    fig, ax = plt.subplots()
    wind = get_windspeed(38, 90, 15000, 355)
    cwind = get_windspeed(38, 90, np.linspace(0, 15000, 11)[1:], 355)
    for vk in model.varkeys["V_{wind}"]:
        if "Climb" in vk.models:
            model.substitutions.update({vk: cwind[vk.idx[0]]})
        else:
            model.substitutions.update({vk: wind})
    model.substitutions.update({"MTOW": 200})
    model.substitutions.update({"N_{max}_Mission/AircraftLoading/WingLoading/GustL":  0.1})
    sol = model.solve("mosek")
    re = sol("Re_Mission/Loiter/FlightSegment/AircraftPerf/WingAero")[-1]

    if num == 1 or num == 2:
        clm = sol("C_L_Mission/Loiter/FlightSegment/AircraftPerf/WingAero")
        cdm = sol("c_{dp}_Mission/Loiter/FlightSegment/AircraftPerf/WingAero")
        l = ax.plot(clm, cdm, "o", mfc="None", ms=7, mew=1.5,
                    label="With Wind Constraint")
        ax.annotate("mission start", xy=(clm[0], cdm[0]), xytext=(0.87, 0.0062),
                    arrowprops=dict(arrowstyle="->"), fontsize=13)
        ax.annotate("mission end", xy=(clm[-1], cdm[-1]), xytext=(0.42, 0.0072),
                    arrowprops=dict(arrowstyle="->"), fontsize=13)

    cl = np.linspace(0.2, 1.5, 100)
    cd = return_cd(cl, re)
    cl15 = cl**1.5/cd
    clmax = cl[cl15 == max(cl15)]
    cdmax = cd[cl15 == max(cl15)]

    for vk in model.varkeys["m_{fac}"]:
        if "Loiter" in vk.descr["models"] and "FlightState" in vk.descr["models"]:
            model.substitutions.update({vk:0.01})
    sol = model.solve("mosek")
    clw = sol("C_L_Mission/Loiter/FlightSegment/AircraftPerf/WingAero")
    cdw = sol("c_{dp}_Mission/Loiter/FlightSegment/AircraftPerf/WingAero")
    if num == 2:
        l = ax.plot(clw, cdw, "s", mfc="None", ms=7, mew=1.5,
                    label="Without Wind Constraint")
        ax.annotate("mission start", xy=(clw[0], cdw[0]), xytext=(1.2, 0.0087),
                    arrowprops=dict(arrowstyle="->"), fontsize=13)
        ax.annotate("mission end", xy=(clw[-1], cdw[-1]), xytext=(0.9, 0.013),
                    arrowprops=dict(arrowstyle="->"), fontsize=13)

    l = ax.plot(clmax, cdmax, "+", mec="#084081", mfc="None", ms=7, mew=1.5)
    l = ax.plot(cl, cd, linewidth=2, label="Re=%3.fk" % (re/1000.),
                c="#084081", zorder=1)
    lines = [l[0]]
    re = sol("Re_Mission/Loiter/FlightSegment/AircraftPerf/WingAero")
    for i, r, col in zip(range(5), re, ["#0868ac","#0868ac","#0868ac", "#2b8cbe", "#2b8cbe"]):
        cd = return_cd(cl, r)
        cl15 = cl**1.5/cd
        clmax = cl[cl15 == max(cl15)]
        cdmax = cd[cl15 == max(cl15)]
        if i == 2 or i == 4:
            l = ax.plot(cl, cd, linewidth=2, label="Re=%3.fk" % (r/1000.),
                        c=col, zorder=1)
            lines.append(l[0])
            ax.plot(clmax, cdmax, "+", mec=col, mfc="None", ms=7, mew=1.5)

    labelLines(lines, fontsize=12, zorder=[2.5]*3, align=False,
               xvals=[1.05, 0.85, 0.7])
    ax.set_xlabel("$C_L$")
    ax.set_ylabel("$c_{d_p}$")
    if num == 2:
        ax.legend(["With Wind Constraint", "Without Wind Constraint"],
                  fontsize=15, loc=2)
    if num == 1:
        ax.legend(["With Wind Constraint"], fontsize=15, loc=2)
    ax.grid()

    for vk in model.varkeys["m_{fac}"]:
        if "Loiter" in vk.descr["models"] and "FlightState" in vk.descr["models"]:
            model.substitutions.update({vk:1})

    return fig, ax
Beispiel #7
0
fig, ax = plt.subplots()
lat = np.arange(0, 60, 1)
M = Mission()
M.substitutions.update({"W_{pay}": 10})
for e in M.varkeys["\\eta_{prop}"]:
    M.substitutions.update({e: 0.75})
for cd in M.varkeys["CDA_0"]:
    M.substitutions.update({cd: 0.01})
M.substitutions.update({"t_Mission/Loiter": 7})
M.cost = M["MTOW"]
for a in [80, 90, 95]:
    mtow = []
    wind = []
    for l in lat:
        wind.append(get_windspeed(l, a, 15000, 355))
        maxwind = max(wind)
        for v in M.varkeys["V_{wind}"]:
            M.substitutions.update({v: maxwind})
        try:
            sol = M.solve("mosek")
            mtow.append(sol("MTOW").magnitude)
        except RuntimeWarning:
            mtow.append(np.nan)
    ax.plot(lat, mtow)

ax.set_ylim([0, 1000])
ax.set_xlim([20, 50])
ax.grid()
labels = ["$\\pm$" + item.get_text() for item in ax.get_xticklabels()]
labels = ["$\\pm$%d" % l for l in np.linspace(20, 50, len(labels))]
def plot_lats():
    fig, ax = plt.subplots()
    lat = np.arange(20, 41, 1)
    Mg = Mgas()
    Mg.substitutions.update({"W_{pay}": 10})
    Mg.substitutions.update({"t_Mission/Loiter": 7})
    Mg.cost = Mg["MTOW"]
    psolar = []
    pgas = []
    faillat = []
    gtime = 0.0
    gnsols = 0
    stime = 0.0
    snsols = 0.0
    for a in [80, 90, 95]:
        wg = []
        ws = []
        runagains = True
        highestwind = 0
        for l in lat:
            if runagains:
                Ms = Msolar(latitude=l)
                Ms.substitutions.update({"W_{pay}": 10})
                for vk in Ms.varkeys["p_{wind}"]:
                    Ms.substitutions.update({vk: a / 100.0})
                Ms.cost = Ms["W_{total}"]
                try:
                    sol = Ms.solve("mosek")
                    stime += sol["soltime"]
                    snsols += 1
                    ws.append(sol("W_{total}").magnitude)
                except RuntimeWarning:
                    ws.append(np.nan)
                    faillat.append(l)
                    runagains = False
            else:
                ws.append(np.nan)

            wind = get_windspeed(l, a, 15000, 355)
            cwind = get_windspeed(l, a, np.linspace(0, 15000, 11)[1:], 355)
            if wind > highestwind:
                highestwind = wind
                for vk in Mg.varkeys["V_{wind}"]:
                    if "Climb" in vk.models:
                        Mg.substitutions.update({vk: cwind[vk.idx[0]]})
                    else:
                        Mg.substitutions.update({vk: wind})
            try:
                sol = Mg.solve("mosek")
                gtime += sol["soltime"]
                gnsols += 1
                wg.append(sol("MTOW").magnitude)
            except RuntimeWarning:
                wg.append(np.nan)
                print "Fail, Lat: %d" % l

        pgas.append(wg)
        psolar.append(ws)

    print "Solar: %d solves in %.4f seconds" % (snsols, stime)
    print "Gas: %d solves in %.4f seconds" % (gnsols, gtime)

    indl = psolar[0].index(max(psolar[0]))
    indh = psolar[2].index(max(psolar[2]))
    a = (psolar[2][indh] - psolar[0][indl]) / (lat[indh] - lat[indl])
    b = psolar[0][indl] - a * lat[indl]
    c = a * lat[indh + 1:indl + 1] + b
    ax.fill_between(lat[0:indl + 1],
                    psolar[0][0:indl + 1],
                    np.append(np.array(psolar[-1][0:indh + 1]), c),
                    alpha=0.3,
                    facecolor="b",
                    edgecolor="None")
    psolar[1][np.where(lat == 31)[0][0]] = np.nan
    ax.plot(lat, psolar[1], "b", lw=2)
    ax.plot(lat, pgas[1], "r", lw=2)
    ax.plot(lat, psolar[0], "b")
    ax.plot(lat, psolar[2], "b")
    ax.fill_between(lat,
                    pgas[0],
                    pgas[2],
                    alpha=0.3,
                    facecolor="r",
                    edgecolor="None")
    ax.plot(lat, pgas[0], "r")
    ax.plot(lat, pgas[2], "r")

    for i, p in enumerate(["80%", "90%", "95%"]):
        ax.annotate(p,
                    xy=(36, pgas[i][np.where(lat == 36)[0][0]]),
                    xytext=(0.1, -20),
                    textcoords="offset points",
                    arrowprops=dict(arrowstyle="-"),
                    fontsize=12)

    ax.annotate("80%",
                xy=(30, psolar[0][np.where(lat == 30)[0][0]]),
                xytext=(15, 15),
                textcoords="offset points",
                arrowprops=dict(arrowstyle="-"),
                fontsize=12)
    ax.annotate("90%",
                xy=(28, psolar[1][np.where(lat == 28)[0][0]]),
                xytext=(15, 15),
                textcoords="offset points",
                arrowprops=dict(arrowstyle="-"),
                fontsize=12)
    ax.annotate("95%",
                xy=(27, psolar[2][np.where(lat == 27)[0][0]]),
                xytext=(-30, 15),
                textcoords="offset points",
                arrowprops=dict(arrowstyle="-"),
                fontsize=12)

    ax.set_ylim([0, 350])
    ax.set_xlim([20, 40])
    ax.grid()
    ax.set_xlabel("Latitude Requirement [deg]")
    ax.set_ylabel("Max Take Off Weight [lbf]")
    labels = ["$\\pm$" + item.get_text() for item in ax.get_xticklabels()]
    labels = ["$\\pm$%d" % l for l in np.linspace(20, 40, len(labels))]
    ax.set_xticklabels(labels)
    ax.legend(["Solar-electric Powered", "Gas Powered"], fontsize=15, loc=2)
    return fig, ax