rcj(ax)
tl(fig)

fig.savefig('Figures/figure6d_bifurcation_sugar_glider.pdf', transparent=True)

# %% Plot the equilibrium glide velocity on a polar plot

fig, ax = plt.subplots()

for ii, fp_kind in enumerate(possible_class):

    idx = np.where(nt_class_1 == fp_kind)[0]
    if len(idx) > 0:
        geq = nt_equil_1[idx, 1]
        veq = eqns.v_equil(geq, cl_fun_1, cd_fun_1)
        vxeq = veq * np.cos(geq)
        vzeq = -veq * np.sin(geq)

        ax.plot(vxeq,
                vzeq,
                'o',
                c=bfbmap[ii],
                ms=2,
                label=fp_kind,
                mec=bfbmap[ii])

ax.set_xlim(0, 1.5)
ax.set_ylim(-1.5, 0)
ax.set_xlabel(r"$\hat{v}_x$", fontsize=18)
ax.set_ylabel(r"$\hat{v}_z$", fontsize=18)
rcj(ax)
tl(fig)

fig.savefig('Figures/figure6c_bifurcation_chukar.pdf', transparent=True)

# %% Plot the equilibrium glide velocity on a polar plot

fig, ax = plt.subplots()

for ii, fp_kind in enumerate(possible_class):

    idx = np.where(ch_class_spl == fp_kind)[0]
    if len(idx) > 0:
        geq = ch_equil_spl[idx, 1]
        veq = eqns.v_equil(geq, cl_fun, cd_fun)
        vxeq = veq * np.cos(geq)
        vzeq = -veq * np.sin(geq)

        ax.plot(vxeq,
                vzeq,
                'o',
                c=bfbmap[ii],
                ms=2,
                label=fp_kind,
                mec=bfbmap[ii])

ax.axis('equal', adjustable='box')
ax.set_xlim(0, 1.5)
ax.set_ylim(-1.5, 0)
ax.set_xlabel(r"$\hat{v}_x$", fontsize=18)
            transparent=True)


# %% Velocity bifurcation plot (could be for the paper...)


fig, ax = plt.subplots()

for ii, fp_kind in enumerate(possible_class):

    idx = np.where(sq_class_spl == fp_kind)[0]
    if len(idx) > 0:
        peq = sq_equil_spl[idx, 0]
        geq = sq_equil_spl[idx, 1]
        aleq = peq + geq
        veq = eqns.v_equil(aleq, cl_fun, cd_fun)
        vxeq = veq * np.cos(geq)
        vzeq = -veq * np.sin(geq)
        ax.plot(rd(peq), veq, 'o', c=bfbmap[ii], ms=2, mec=bfbmap[ii])

#        nos = np.ones(len(veq))
#        sk = 5
#        ax.plot(rd(peq), veq, rd(geq), 'o',
#                c=bfbmap[ii], ms=2, label=fp_kind, mec=bfbmap[ii])
#        ax.plot(rd(peq)[::sk], .755 * nos[::sk], rd(geq)[::sk], 'o',
#                c=bfbmap[ii], ms=2, mec=bfbmap[ii], alpha=.35)
#        ax.plot(rd(peq)[::sk], veq[::sk], 18 * nos[::sk], 'o',
#                c=bfbmap[ii], ms=2, mec=bfbmap[ii], alpha=.35)

#ax.set_ylim(ymax=.755)
ax.set_xlabel(r'$\theta$', fontsize=18)
lab = 'airfoil squirrel, ' + r'$\theta=$2' + u'\u00B0'
ax.text(.05, -1, lab, fontsize=16)

fig.savefig('Figures/figure5aii_vpd2_airfoil_squirrel.pdf', transparent=True)

# %% Additional plots

fig, ax = plt.subplots()

for ii, fp_kind in enumerate(possible_class):

    idx = np.where(so_class_25 == fp_kind)[0]
    if len(idx) > 0:
        geq = so_equil_25[idx, 1]
        veq = eqns.v_equil(geq, cl_fun_25, cd_fun_25)
        vxeq = veq * np.cos(geq)
        vzeq = -veq * np.sin(geq)

        ax.plot(vxeq,
                vzeq,
                'o',
                c=bfbmap[ii],
                ms=2,
                label=fp_kind,
                mec=bfbmap[ii])

ax.set_xlim(0, 1.5)
ax.set_ylim(-1.5, 0)
ax.set_xlabel(r"$\hat{v}_x$", fontsize=18)
ax.set_ylabel(r"$\hat{v}_z$", fontsize=18)
示例#5
0
def phase_plotter(afdict,
                  pitch,
                  lims,
                  arng,
                  tvec,
                  ngrid=201,
                  nseed=41,
                  nseed_skip=1,
                  quiver=False,
                  skip=10,
                  seed=False,
                  timer=False,
                  gamtest=None,
                  extrap=None,
                  traj=None,
                  seedloc=None,
                  fig=None,
                  ax=None,
                  acc_contour=True,
                  nullcline_x=False,
                  nullcline_z=False):

    # unpack the data
    cli, cdi, = afdict['cli'], afdict['cdi']
    clip, cdip = afdict['clip'], afdict['cdip']

    # upack axis limits
    vxlim, vzlim = lims

    from eqns import cart_eqns, cart_model

    if traj is None:
        traj = ps_traj_dp5

    VXorig, VZorig, VX, VZ, ALPHA = setup_grid(ngrid, vxlim, vzlim, pitch,
                                               arng)
    CL = cli(ALPHA.flatten()).reshape(ALPHA.shape)
    CD = cdi(ALPHA.flatten()).reshape(ALPHA.shape)
    dVX, dVZ = cart_eqns(VX, VZ, CL, CD)
    AMAG = np.hypot(dVX, dVZ)
    AX, AZ = dVX / AMAG, dVZ / AMAG

    # calculation the integral curves
    now = time.time()
    # vxs, vzs, VXs, VZs, als = setup_grid(nseed, vxlim, vzlim, pitch, arng)
    vxseed, vzseed = seed_locations(nseed, vxlim, vzlim, pitch, arng)
    vxseed, vzseed = vxseed[::nseed_skip], vzseed[::nseed_skip]

    if seedloc is not None:
        vxseed = np.r_[vxseed, seedloc[:, 0]]
        vzseed = np.r_[vzseed, seedloc[:, 1]]
    odeargs = (pitch, cli, cdi)
    solns = []
    for i in range(len(vxseed)):
        x0 = (0, 0, vxseed[i], vzseed[i])
        soln = traj(x0, tvec, odeargs, cart_model, arng, vxlim, vzlim)
        solns.append(soln)
    if timer:
        print('Elapsed time: {:.3f}'.format(time.time() - now))

    # equilibrium points
    if gamtest is not None:
        from eqns import pitch_bifurcation as pb
        from eqns import v_equil, vxvz_equil, tau_delta, classify_fp
        equil = pb([pitch], gamtest, cli, cdi, angle_rng=arng)
        thbar, gambar = equil.T
        vbar = v_equil(pitch + gambar, cli, cdi)
        vxbar, vzbar = vxvz_equil(vbar, gambar)

        td, ev = tau_delta(equil, cli, cdi, clip, cdip, arng)
        _, _, fp_class = classify_fp(td)

        possible_class = [
            'saddle point', 'unstable focus', 'unstable node', 'stable focus',
            'stable node'
        ]
        bfbmap = [bmap[0], bmap[4], bmap[2], bmap[3], bmap[1]]

    if fig is None or ax is None:
        fig, ax = plt.subplots(figsize=(5.5, 5.125))

    if quiver:
        ax.quiver(VX[::skip, ::skip],
                  VZ[::skip, ::skip],
                  AX[::skip, ::skip],
                  AZ[::skip, ::skip],
                  color='gray',
                  pivot='middle',
                  alpha=.8,
                  edgecolor='gray',
                  linewidths=0 * np.ones(VX[::skip, ::skip].size))

    for i in range(len(solns)):
        ax.plot(solns[i][:, 2],
                solns[i][:, 3],
                '-',
                ms=2.25,
                c='gray',
                alpha=.95,
                lw=.5)  # color=bmap[1])

    if seed:
        ax.plot(vxseed, vzseed, 'o', ms=2.5)

    if gamtest is not None:
        for ii, fp_kind in enumerate(possible_class):
            idx = np.where(fp_class == fp_kind)[0]
            if len(idx) == 0:
                continue

            # now globalize the phase space
            if fp_kind == 'saddle point':
                #  or fp_kind == 'stable node' or fp_kind == 'unstable node':
                tvec = np.linspace(tvec[0], 3 * tvec[-1], 6 * len(tvec))
                vxpt, vzpt = vxbar[idx], vzbar[idx]
                solns = []
                for i in range(len(vxpt)):
                    vxs, vzs = saddle_filler(vxpt[i], vzpt[i])
                    for vx0, vz0 in zip(vxs, vzs):
                        ic = (0, 0, vx0, vz0)
                        sn1 = traj(ic, tvec, odeargs, cart_model, arng, vxlim,
                                   vzlim)
                        sn2 = traj(ic, -tvec, odeargs, cart_model, arng, vxlim,
                                   vzlim)
                        solns.append(sn1)
                        solns.append(sn2)

                # plot the globalized saddles
                for i in range(len(solns)):
                    ax.plot(solns[i][:, 2], solns[i][:, 3], '-', c=bfbmap[ii])

            # plot the equilibrium point
            ax.plot(vxbar[idx],
                    vzbar[idx],
                    'o',
                    ms=7,
                    c=bfbmap[ii],
                    zorder=200)

    if acc_contour:
        ax.contourf(VX, VZ, AMAG, [0, .1], colors=[bmap[3]], alpha=.2)
        # ax.contourf(VX, VZ, dVZ, [0, .1], colors=[bmap[4]], alpha=.2)

    if extrap is not None and extrap[0] is not None:
        ax.contourf(VX,
                    VZ,
                    np.array(ALPHA < extrap[0]).astype(np.int), [.5, 1.5],
                    colors='gray',
                    alpha=.1)
    if extrap is not None and extrap[1] is not None:
        ax.contourf(VX,
                    VZ,
                    np.array(ALPHA > extrap[1]).astype(np.int), [.5, 1.5],
                    colors='gray',
                    alpha=.1)

    # plot the nullclines
    if nullcline_x:
        ax.contour(VX, VZ, dVX, [0], colors=[bmap[3]], alpha=1, zorder=100)
    if nullcline_z:
        ax.contour(VX, VZ, dVZ, [0], colors=[bmap[3]], alpha=1, zorder=100)

    ax.set_xlim(vxlim[0], vxlim[1])
    ax.set_ylim(vzlim[1], vzlim[0])

    ax.xaxis.set_label_position('top')
    ax.xaxis.tick_top()
    ax.set_xlabel(r"$\hat{v}_x$", fontsize=20)
    ax.set_ylabel(r"$\hat{v}_z    $", fontsize=20, rotation=0)
    ax.set_aspect('equal', adjustable='box')  # these need to be square
    ax.set_xticks([0, .25, .5, .75, 1, 1.25])
    ax.set_yticks([0, -.25, -.5, -.75, -1, -1.25])
    ax.set_xticklabels(['0', '', '', '', '', '1.25'])
    ax.set_yticklabels(['0', '', '', '', '', '-1.25'])
    [ttl.set_size(18) for ttl in ax.get_xticklabels()]
    [ttl.set_size(18) for ttl in ax.get_yticklabels()]
    rcj(ax, ['bottom', 'right'])
    tl(fig)

    return fig, ax