예제 #1
0
    def test_KatzPlotkin(self):
        """Test final unsteady lift/drag to TAT for high AR problem using
        generalised Katz and Plotkin method."""

        M = 1
        N = 1
        Mstar = 200
        VMOPTS = VMopts(M, N, True, Mstar, False, False)

        # Define wing geometry parameters."
        c = 1
        b = 10000  #semi-span

        # Define free-stream conditions."
        U_mag = 0.0
        alpha = 0.0 * np.pi / 180.0
        theta = 1.0 * np.pi / 180.0
        VMINPUT = VMinput(c, b, U_mag, alpha, theta)

        # Define unsteady simulation parameters.
        WakeLength = 200.0
        DeltaS = 1.0
        NumChordLengths = 200.0
        VelA_A = np.array([0, 1.0, 0])
        OmegaA_A = np.array([0, 0, 0])
        VMUNST = VMUnsteadyInput(VMOPTS,VMINPUT,\
                                 WakeLength,\
                                 DeltaS,\
                                 NumChordLengths,\
                                 VelA_A, OmegaA_A)

        # Define 'aeroelastic' parameters
        AELOPTS = AeroelasticOps(ElasticAxis=-0.5,
                                 InertialAxis=0.0,
                                 AirDensity=1.0)

        # Run C++ solver."
        CoeffHistory = Run_Cpp_Solver_UVLM(VMOPTS, VMINPUT, VMUNST, AELOPTS)

        # Check forces from Katz and Plotkin method."
        self.assertAlmostEqual(CoeffHistory[-1, 3],
                               2 * np.pi * VMINPUT.theta,
                               delta=1e-3)
        self.assertAlmostEqual(-CoeffHistory[-1, 2], 0, delta=1e-5)
예제 #2
0
파일: UVLM.py 프로젝트: cndaqiang/SHARPy
    N = 10
    Mstar = 10 * M
    U_mag = 25.0
    alpha = 1.0 * np.pi / 180.0
    theta = 0.0 * np.pi / 180.0
    imageMeth = True

    # Define wing geometry parameters.
    c = 1
    b = 2000  #16 #semi-span

    # Physical time-step
    DeltaS = c / (M * U_mag)

    # Solver options
    VMOPTS = VMopts(M, N, imageMeth, Mstar, False, True, True, DeltaS, False,
                    4)

    # Solver inputs
    WakeLength = Mstar / M  # specified in chord lengths
    ctrlSurf = None  #ControlSurf(3, 4, 6, 9, 'sin', 1*np.pi/180.0, 2*np.pi)
    VMINPUT = VMinput(c, b, U_mag, alpha, theta, WakeLength, ctrlSurf)

    # Define unsteady solver parameters.
    NumChordLengths = 100.0
    VelA_A = np.array([0, 0, 0])
    OmegaA_A = np.array([0, 0, 0])
    VMUNST = VMUnsteadyInput(VMOPTS,VMINPUT,\
                             WakeLength,\
                             DeltaS*U_mag/c,\
                             NumChordLengths,\
                             VelA_A, OmegaA_A)
예제 #3
0
    def test_ctrlSurf(self):
        """Test K&P then Joukowski methods unsteady lift and drag."""

        # Declare UVLM solver options.
        VMOPTS = VMopts(M=25,
                        N=2,
                        ImageMethod=True,
                        Mstar=250,
                        Steady=False,
                        KJMeth=False,
                        NewAIC=True,
                        DelTime=0.0,
                        Rollup=False,
                        NumCores=4)

        # Define wing geometry parameters.
        c = 1.0
        b = 1000.0
        theta = 0.0 * np.pi / 180.0

        # Define free-stream conditions.
        U_mag = 1.0
        alpha = 0.0 * np.pi / 180.0

        # Define Control Surface
        k = 1.0
        omega = 2 * U_mag * k / c
        betaBar = 0.1 * np.pi / 180.0
        ctrlSurf = ControlSurf(20, 25, 0, 2, 'sin', betaBar, omega)

        # Length of simulation.
        nT = 2.0
        NumChordLengths = nT * np.pi / k

        VMINPUT = VMinput(c,
                          b,
                          U_mag,
                          alpha,
                          theta,
                          WakeLength=NumChordLengths,
                          ctrlSurf=ctrlSurf)

        # Define unsteady solver parameters.
        VMUNST = VMUnsteadyInput(VMOPTS,
                                 VMINPUT,
                                 WakeLength=10.0,
                                 DelS=1.0 / 25.0,
                                 NumChordLengths=NumChordLengths,
                                 VelA_G=np.array([0, 0, 0]),
                                 OmegaA_G=np.array([0, 0, 0]))

        # Define 'aeroelastic' options.
        ElasticAxis = -0.5
        AELOPTS = AeroelasticOps(ElasticAxis=ElasticAxis)  # Quarter chord.

        # Run C++ solver.
        CoeffHistoryKatz = Run_Cpp_Solver_UVLM(VMOPTS, VMINPUT, VMUNST,
                                               AELOPTS)

        # Run from Joukowski method.
        VMOPTS.KJMeth.value = True
        CoeffHistoryJouk = Run_Cpp_Solver_UVLM(VMOPTS, VMINPUT, VMUNST,
                                               AELOPTS)

        # Set parameters for analytical result.
        alphaBar = 0.0
        hBar = 0.0
        phi0 = 0.0
        phi1 = 0.0
        phi2 = 0.0
        a = ElasticAxis
        e = 0.6
        k = 1.0

        Cl, Cd, alpha, beta, hDot, s = TheoGarrAerofoil(
            alphaBar, betaBar, hBar, phi0, phi1, phi2, a, e, k, nT + 0.1)

        # Delete unused variables
        del hDot

        # Interpolate analytical result onto simulated time steps.
        ClTheo = np.interp(CoeffHistoryKatz[:, 0] * U_mag / (c / 2.0), s, Cl)
        CdGarr = np.interp(CoeffHistoryKatz[:, 0] * U_mag / (c / 2.0), s, Cd)

        # Calculate error as function of time in last period.
        kTimeMid = len(CoeffHistoryKatz[:, 0]) / 2
        ClErr = CoeffHistoryKatz[kTimeMid:, 3] - ClTheo[kTimeMid:]
        CdErr = -CoeffHistoryKatz[kTimeMid:, 2] - CdGarr[kTimeMid:]
        ClErrJouk = CoeffHistoryJouk[kTimeMid:, 3] - ClTheo[kTimeMid:]
        CdErrJouk = -CoeffHistoryJouk[kTimeMid:, 2] - CdGarr[kTimeMid:]

        # RMS error
        rmsCl = np.sqrt(np.mean(pow(ClErr, 2.0))) / max(CoeffHistoryKatz[:, 3])
        rmsCd = np.sqrt(np.mean(pow(CdErr,
                                    2.0))) / max(-CoeffHistoryKatz[:, 2])
        rmsClJouk = (np.sqrt(np.mean(pow(ClErrJouk, 2.0))) /
                     max(CoeffHistoryJouk[:, 3]))
        rmsCdJouk = (np.sqrt(np.mean(pow(CdErrJouk, 2.0))) /
                     max(-CoeffHistoryJouk[:, 2]))

        # Check RMS is same as on 23/05/13
        self.assertAlmostEqual(rmsCl, 0.0241589106969, 6, 'RMS error in lift.')
        self.assertAlmostEqual(rmsCd, 0.136290106597, 5, 'RMS error in drag.')

        Plotting = False
        if Plotting == True:
            # Define beta here for plotting purposes.
            betaSim = betaBar * np.sin(omega * CoeffHistoryKatz[:, 0])

            plt.subplot(2, 1, 1)
            plt.grid()
            plt.plot(betaSim, -CoeffHistoryKatz[:, 2], 'ko-', beta, Cd, 'k-.')
            plt.xlabel(r'$\beta$')
            plt.ylabel(r'$C_d$')
            plt.subplot(2, 1, 2)
            plt.grid()
            plt.plot(betaSim, CoeffHistoryKatz[:, 3], 'ko-', beta, Cl, 'k-.')
            plt.xlabel(r'$\beta$')
            plt.ylabel(r'$C_l$')

            plt.show()
예제 #4
0
    def test_KatzPlotkin(self):
        """Test final unsteady lift/drag for AR8 problem."""

        M = 4
        N = 13
        Mstar = 160
        VMOPTS = VMopts(M, N, True, Mstar, False, False, True, 0.0, False, 4)

        # Define wing geometry parameters.
        c = 1
        b = 4  #semi-span

        # Define free-stream conditions.
        U_mag = 0.0
        alpha = 0.0 * np.pi / 180.0
        theta = 5.0 * np.pi / 180.0
        NumChordLengths = 10.0
        VMINPUT = VMinput(c, b, U_mag, alpha, theta, NumChordLengths)

        # Define unsteady solver parameters.
        WakeLength = 10.0
        DeltaS = 1.0 / 16.0
        VelA_A = np.array([0, 1.0, 0])
        OmegaA_A = np.array([0, 0, 0])
        VMUNST = VMUnsteadyInput(VMOPTS, VMINPUT, WakeLength, DeltaS,
                                 NumChordLengths, VelA_A, OmegaA_A)

        # Define 'aeroelastic' options.
        AELOPTS = AeroelasticOps(ElasticAxis=-0.5,
                                 InertialAxis=0.0,
                                 AirDensity=1.0)

        # Run C++ solver.
        CoeffHistory = Run_Cpp_Solver_UVLM(VMOPTS, VMINPUT, VMUNST, AELOPTS)

        # Check force for Katz and Plotkin method against textbook at final
        # time.
        CD = np.loadtxt('testData/Katz1p492_AR8_CD.dat', ndmin=2)
        CL = np.loadtxt('testData/Katz1p492_AR8_CL.dat', ndmin=2)

        self.assertAlmostEqual(CoeffHistory[-1, 3], CL[-1, 1], delta=1e-3)
        self.assertAlmostEqual(-CoeffHistory[-1, 2], CD[-1, 1], delta=1e-3)

        Plotting = False
        if Plotting == True:
            plt.figure(1)
            a = plt.plot(CD[:, 0], CD[:, 1], 'ks')
            b = plt.plot(CoeffHistory[:, 0], -CoeffHistory[:, 2], 'k-')
            plt.xlim((0, 10.0))
            plt.ylim((0, 0.03))
            plt.xlabel('U*t/c [-]')
            plt.ylabel('C_D')
            plt.legend(('Katz and Plotkin (2001)', 'SHARPy'),
                       'upper right',
                       shadow=True,
                       prop={'size': 12})

            plt.figure(2)
            c = plt.plot(CL[:, 0], CL[:, 1], 'ks')
            d = plt.plot(CoeffHistory[:, 0], CoeffHistory[:, 3], 'k-')
            plt.xlim((0, 10.0))
            plt.ylim((0, 0.6))
            plt.xlabel('U*t/c [-]')
            plt.ylabel('C_L')
            plt.legend(('Katz and Plotkin (2001)', 'SHARPy'),
                       'lower right',
                       shadow=True,
                       prop={'size': 12})

            lines = a, b, c, d
            plt.setp(lines, linewidth=2, markersize=6)

            plt.show()
예제 #5
0
        ZetaStar[:, :] += VMINPUT.U_infty * VMOPTS.DelTime.value

    # END for iTimeStep

    # Close tecplot file object.
    PostProcess.CloseAeroTecFile(FileObject)

    return CoeffHistory


if __name__ == '__main__':
    # Define options for aero solver.
    M = 4
    N = 10
    Mstar = 80
    VMOPTS = VMopts(M, N, True, Mstar, False, False, True, 0.0, True, 4)

    # Define wing geometry parameters.
    c = 1
    b = 4  #semi-span

    # Define Control Surface
    ctrlSurf = ControlSurf(3, 4, 6, 9, 'sin', 1 * np.pi / 180.0, 2 * np.pi)

    # Define free stream conditions.
    U_mag = 1.0
    alpha = 0.0 * np.pi / 180.0
    theta = 10.0 * np.pi / 180.0

    VMINPUT = VMinput(c, b, U_mag, alpha, theta, 0.0, 15.0, ctrlSurf)
예제 #6
0
파일: VLM.py 프로젝트: cndaqiang/SHARPy
    n = 1
    Umag = 1.0
    alpha = 1.0 * np.pi / 180.0
    chord = 1.0
    span = 2.e3
    WakeLength = 10.0
    imageMeth = True
    VMINPUT = DerivedTypesAero.VMinput(chord,
                                       b=span,
                                       U_mag=Umag,
                                       alpha=alpha,
                                       theta=0.0,
                                       WakeLength=WakeLength,
                                       ctrlSurf=None)

    VMOPTS = VMopts(m, n, imageMeth, Mstar=1, Steady=True, KJMeth=True)
    # run solver
    Coeffs, Zeta, ZetaStar, Gamma, GammaStar, foo, Uext = Run_Cpp_Solver_VLM(
        VMOPTS, VMINPUT)[0:7]
    del foo

    # unsteady params
    mW = 10 * m
    delS = 2 / m

    # transform states/inputs
    gam, gamW, gamPri, zeta, zetaW, zetaPri, nu, beam2aero = nln2linStates(
        Zeta, ZetaStar, Gamma, GammaStar, Uext, m, n, mW, chord)

    # generate linear model
    E, F, G, C, D = genSSuvlm(gam, gamW, gamPri, zeta, zetaW, zetaPri, nu, m,