Example #1
0
def cheb_D1_fchebt(v):
    '''
    Evaluate 1st derivative with Chebyshev polynomials via fast Fourier
    transform (FFT).

    Ref:
        Kopriva, DA **Implementing Spectral Methods for Partial Differential
        Equations**, 2009

    :param:v: 1D numpy array contains the data to be differentiated.

    '''

    N = np.size(v) - 1
    if N == 0:
        return 0

    # Perfrom forward Chebyshev transform to obtain the coefficients
    V = cheb_fast_transform(v)

    # Compute the 1st Derivative coefficients in spetral space
    W = cheb_D1_coefficients(V)

    # Transfrom back to spatial space for theta
    w = cheb_inverse_fast_transform(W)

    return w
Example #2
0
def cheb_mde_neumann_split(W, u0, Lx, Ns):
    '''
    Solution of modified diffusion equation (MDE) 
    via Strang operator splitting as time-stepping scheme 
    and pseudospectral methods on Chebyshev grids.

    The MDE is:
        dq/dt = Dq + Wq
    where D is Laplace operator. Neumann boundary condition is assumed.
    '''

    ds = 1. / (Ns - 1)
    N = np.size(W) - 1
    u = u0.copy()
    u[0] = 0.
    u[N] = 0.

    k2 = (np.pi * np.pi) / (Lx * Lx) * np.arange(N + 1) * np.arange(N + 1)
    expw = np.exp(-0.5 * ds * W)
    for i in xrange(Ns - 1):
        u = expw * u
        ak = cheb_fast_transform(u) * np.exp(-ds * k2)
        u = cheb_inverse_fast_transform(ak)
        u = expw * u

    ii = np.arange(N + 1)
    x = 1. * ii * Lx / N
    return (u, x)
Example #3
0
def test_cheb_fast_transform():
    N = 10
    ii = np.arange(N + 1)
    x = np.cos(np.pi * ii / N)
    f = np.exp(x) * np.sin(5. * x)

    F = cheb_fast_transform(f)
    ff = cheb_inverse_fast_transform(F)

    print f
    print ff
Example #4
0
    def solve(self, w, u0, q=None):
        '''
            dq/dt = Dq + Wq = Dq - wq
        '''
        N = self.N
        u = u0.reshape(u0.size)  # force 1D array
        f = np.zeros(u.size + 2)  # u.size is N+1
        ge = np.zeros(self.pep.size + 1)
        go = np.zeros(self.pop.size + 1)
        uc = u.astype(complex)
        fc = f.astype(complex)
        gec = ge.astype(complex)
        goc = go.astype(complex)

        expw = np.exp(-0.5 * self.h * w)
        for i in xrange(self.Ns - 1):
            u = expw * u

            u = cheb_fast_transform(u)

            f[:N + 1] = u
            g = self.pg * f[0:N-1] - self.qg * f[2:N+1] \
                    + self.rg * f[4:N+3]
            ge[1:] = g[0:N - 1:2]
            go[1:] = g[1:N - 1:2]
            ue = solve_tridiag_complex_thual(self.pen, self.qen, self.ren,
                                             self.bce, ge)
            uo = solve_tridiag_complex_thual(self.pon, self.qon, self.ron,
                                             self.bco, go)
            uc[0:N + 1:2] = ue
            uc[1:N + 1:2] = uo

            fc[:N + 1] = uc
            gc = self.pg * fc[0:N-1] - self.qg * fc[2:N+1] \
                    + self.rg * fc[4:N+3]
            gec[1:] = gc[0:N - 1:2]
            goc[1:] = gc[1:N - 1:2]
            ue = solve_tridiag_complex_thual(self.pep, self.qep, self.rep,
                                             self.bce, gec)
            uo = solve_tridiag_complex_thual(self.pop, self.qop, self.rop,
                                             self.bco, goc)
            uc[0:N + 1:2] = ue
            uc[1:N + 1:2] = uo
            u = uc.real

            u = cheb_inverse_fast_transform(u)

            u = 2. * (self.K / self.h)**2 * expw * u

            if q is not None:
                q[i + 1] = u

        return (u, self.x)
Example #5
0
def cheb_mde_oscheb(W, u0, Lx, Ns, bc_even, bc_odd):
    '''
    Solution of modified diffusion equation (MDE) 
    via Strang operator splitting as time-stepping scheme 
    and fast Chebyshev transform.

    Ref:
        Her, S. M.; Garcia-Cervera, C. J.; Fredrickson, G. H. macromolecules, 2012, 45, 2905.

    The MDE is:
        dq/dt = Dq - Wq
    in the interval [0, L], with homogeneous Dirichlet boundary conditions at both boundaries.
    where D is Laplace operator.
    Discretization:
        x_j = cos(j*L_x/N), j = 0, 1, 2, ..., N

    :param:W: W_j, j = 0, 1, ..., N
    :param:u0: u0_j, j = 0, 1, ..., N
    :param:Lx: the physical length of the interval [0, L_x]
    :param:Ns: contour index, s_j, j = 0, 1, ..., N_s
    '''
    ds = 1. / (Ns - 1)
    N = u0.size - 1
    u = u0.reshape(u0.size)  # force 1D array
    K = (Lx / 2.)**2
    lambp = K * (1. + 1j) / ds  # \lambda_+
    lambn = K * (1. - 1j) / ds  # \lambda_-

    c = np.ones(N + 1)
    c[0] = 2.
    c[-1] = 2.  # c_0=c_N=2, c_1=c_2=...=c_{N-1}=1
    b = np.ones(N + 3)
    b[N - 1:] = 0.  # b_{N-1}=...=b_{N+2}=0, b_0=b_1=...=b_{N-2}=1
    n = np.arange(N + 1)
    pe = 0.25 * c[0:N - 1:2] / n[2:N + 1:2] / (n[2:N + 1:2] - 1)
    po = 0.25 * c[1:N - 1:2] / n[3:N + 1:2] / (n[3:N + 1:2] - 1)
    pep = -pe * lambp
    pen = -pe * lambn
    pop = -po * lambp
    pon = -po * lambn
    qe = 0.5 * b[2:N + 1:2] / (n[2:N + 1:2]**2 - 1)
    qo = 0.5 * b[3:N + 1:2] / (n[3:N + 1:2]**2 - 1)
    qep = 1 + qe * lambp
    qen = 1 + qe * lambn
    qop = 1 + qo * lambp
    qon = 1 + qo * lambn
    re = 0.25 * b[4:N + 3:2] / n[2:N + 1:2] / (n[2:N + 1:2] + 1)
    ro = 0.25 * b[5:N + 3:2] / n[3:N + 1:2] / (n[3:N + 1:2] + 1)
    rep = -re * lambp
    ren = -re * lambn
    rop = -ro * lambp
    ron = -ro * lambn
    pg = np.zeros(pe.size + po.size)
    pg[0:N - 1:2] = pe
    pg[1:N - 1:2] = po
    qg = np.zeros(qe.size + qo.size)
    qg[0:N - 1:2] = qe
    qg[1:N - 1:2] = qo
    rg = np.zeros(re.size + ro.size)
    rg[0:N - 1:2] = re
    rg[1:N - 1:2] = ro

    #dbce = np.ones(pe.size + 1)
    #dbco = np.ones(po.size + 1)
    dbce = bc_even
    dbco = bc_odd
    f = np.zeros(u.size + 2)  # u.size is N+1
    ge = np.zeros(pe.size + 1)
    go = np.zeros(po.size + 1)

    uc = u.astype(complex)
    fc = f.astype(complex)
    gec = ge.astype(complex)
    goc = go.astype(complex)

    expw = np.exp(-0.5 * ds * W)
    for i in xrange(Ns - 1):
        u = expw * u

        u = cheb_fast_transform(u)

        f[:N + 1] = u
        g = pg * f[0:N - 1] - qg * f[2:N + 1] + rg * f[4:N + 3]
        ge[1:] = g[0:N - 1:2]
        go[1:] = g[1:N - 1:2]
        ue = solve_tridiag_complex_thual(pen, qen, ren, dbce, ge)
        uo = solve_tridiag_complex_thual(pon, qon, ron, dbco, go)
        uc[0:N + 1:2] = ue
        uc[1:N + 1:2] = uo

        fc[:N + 1] = uc
        gc = pg * fc[0:N - 1] - qg * fc[2:N + 1] + rg * fc[4:N + 3]
        gec[1:] = gc[0:N - 1:2]
        goc[1:] = gc[1:N - 1:2]
        ue = solve_tridiag_complex_thual(pep, qep, rep, dbce, gec)
        uo = solve_tridiag_complex_thual(pop, qop, rop, dbco, goc)
        uc[0:N + 1:2] = ue
        uc[1:N + 1:2] = uo
        u = uc.real

        u = cheb_inverse_fast_transform(u)

        u = 2. * (K / ds)**2 * expw * u

    return u