def interp(self, y, eigvals, eigvectors, eigval=1, verbose=False):
        """Interpolate solution eigenvector and it's derivative onto y

        Parameters
        ----------
            y : array
                Interpolation points
            eigvals : array
                All computed eigenvalues
            eigvectors : array
                All computed eigenvectors
            eigval : int, optional
                The chosen eigenvalue, ranked with descending imaginary
                part. The largest imaginary part is 1, the second
                largest is 2, etc.
            verbose : bool, optional
                Print information or not
        """
        N = self.N
        nx, eigval = self.get_eigval(eigval, eigvals, verbose)
        phi_hat = np.zeros(N, np.complex)
        phi_hat[:-4] = np.squeeze(eigvectors[:, nx])

        if not len(self.P4) == len(y):
            SB = Basis(N, 'C', bc='Biharmonic', quad=self.quad)
            self.P4 = SB.evaluate_basis_all(x=y)
            self.T4x = SB.evaluate_basis_derivative_all(x=y, k=1)
        phi = np.dot(self.P4, phi_hat)
        dphidy = np.dot(self.T4x, phi_hat)

        return eigval, phi, dphidy
def test_project_hermite(typecode, dim):
    # Using sympy to compute an analytical solution
    x, y, z = symbols("x,y,z")
    sizes = (20, 19)

    funcs = {
        (1, 0): (cos(4*y)*sin(2*x))*exp(-x**2/2),
        (1, 1): (cos(4*x)*sin(2*y))*exp(-y**2/2),
        (2, 0): (sin(3*z)*cos(4*y)*sin(2*x))*exp(-x**2/2),
        (2, 1): (sin(2*z)*cos(4*x)*sin(2*y))*exp(-y**2/2),
        (2, 2): (sin(2*x)*cos(4*y)*sin(2*z))*exp(-z**2/2)
        }
    xs = {0:x, 1:y, 2:z}

    for shape in product(*([sizes]*dim)):
        bases = []
        for n in shape[:-1]:
            bases.append(Basis(n, 'F', dtype=typecode.upper()))
        bases.append(Basis(shape[-1], 'F', dtype=typecode))

        for axis in range(dim+1):
            ST0 = hBasis[0](3*shape[-1])
            bases.insert(axis, ST0)
            fft = TensorProductSpace(comm, bases, dtype=typecode, axes=axes[dim][axis])
            X = fft.local_mesh(True)
            ue = funcs[(dim, axis)]
            due = ue.diff(xs[0], 1)
            u_h = project(ue, fft)
            du_h = project(due, fft)
            du2 = project(Dx(u_h, 0, 1), fft)

            assert np.linalg.norm(du_h-du2) < 1e-5
            bases.pop(axis)
            fft.destroy()
    def assemble(self):
        N = self.N
        SB = Basis(N, 'C', bc='Biharmonic', quad=self.quad)
        SB.plan((N, N), 0, np.float, {})

        # (u'', v)
        K = inner_product((SB, 0), (SB, 2))

        # ((1-x**2)u, v)
        x = sp.symbols('x', real=True)
        K1 = inner_product((SB, 0), (SB, 0), measure=(1-x**2))

        # ((1-x**2)u'', v)
        K2 = inner_product((SB, 0), (SB, 2), measure=(1-x**2))

        # (u'''', v)
        Q = inner_product((SB, 0), (SB, 4))

        # (u, v)
        M = inner_product((SB, 0), (SB, 0))

        Re = self.Re
        a = self.alfa
        B = -Re*a*1j*(K-a**2*M)
        A = Q-2*a**2*K+a**4*M - 2*a*Re*1j*M - 1j*a*Re*(K2-a**2*K1)
        return A.diags().toarray(), B.diags().toarray()
    def interp(self, y, eigvals, eigvectors, eigval=1, verbose=False):
        """Interpolate solution eigenvector and it's derivative onto y

        Parameters
        ----------
            y : array
                Interpolation points
            eigvals : array
                All computed eigenvalues
            eigvectors : array
                All computed eigenvectors
            eigval : int, optional
                The chosen eigenvalue, ranked with descending imaginary
                part. The largest imaginary part is 1, the second
                largest is 2, etc.
            verbose : bool, optional
                Print information or not
        """
        N = self.N
        nx, eigval = self.get_eigval(eigval, eigvals, verbose)
        phi_hat = np.zeros(N, np.complex)
        phi_hat[:-4] = np.squeeze(eigvectors[:, nx])

        if not len(self.P4) == len(y):
            SB = Basis(N, 'C', bc='Biharmonic', quad=self.quad)
            self.P4 = SB.evaluate_basis_all(x=y)
            self.T4x = SB.evaluate_basis_derivative_all(x=y, k=1)
        phi = np.dot(self.P4, phi_hat)
        dphidy = np.dot(self.T4x, phi_hat)

        return eigval, phi, dphidy
Beispiel #5
0
def test_biharmonic2D(family, axis):
    la = lla
    if family == 'chebyshev':
        la = cla
    N = (16, 16)
    SD = Basis(N[axis], family=family, bc='Biharmonic')
    K1 = Basis(N[(axis + 1) % 2], family='F', dtype='d')
    subcomms = mpi4py_fft.pencil.Subcomm(MPI.COMM_WORLD, allaxes2D[axis])
    bases = [K1]
    bases.insert(axis, SD)
    T = TensorProductSpace(subcomms, bases, axes=allaxes2D[axis])
    u = TrialFunction(T)
    v = TestFunction(T)
    if family == 'chebyshev':
        mat = inner(v, div(grad(div(grad(u)))))
    else:
        mat = inner(div(grad(v)), div(grad(u)))

    H = la.Biharmonic(*mat)
    u = Function(T)
    u[:] = np.random.random(u.shape) + 1j * np.random.random(u.shape)
    f = Function(T)
    f = H.matvec(u, f)

    g0 = Function(T)
    g1 = Function(T)
    g2 = Function(T)
    M = {d.get_key(): d for d in mat}
    g0 = M['SBBmat'].matvec(u, g0)
    g1 = M['ABBmat'].matvec(u, g1)
    g2 = M['BBBmat'].matvec(u, g2)

    assert np.linalg.norm(f - (g0 + g1 + g2)) < 1e-8
Beispiel #6
0
def test_shentransform(typecode, dim, ST, quad):

    for shape in product(*([sizes] * dim)):
        bases = []
        for n in shape[:-1]:
            bases.append(Basis(n, 'F', dtype=typecode.upper()))
        bases.append(Basis(shape[-1], 'F', dtype=typecode))

        if dim < 3:
            n = min(shape)
            if typecode in 'fdg':
                n //= 2
                n += 1
            if n < comm.size:
                continue
        for axis in range(dim + 1):
            ST0 = ST(shape[-1], quad=quad)
            bases.insert(axis, ST0)
            fft = TensorProductSpace(comm, bases, dtype=typecode)
            U = random_like(fft.forward.input_array)
            F = fft.forward(U)
            Fc = F.copy()
            V = fft.backward(F)
            F = fft.forward(U)
            assert allclose(F, Fc)
            bases.pop(axis)
            fft.destroy()
Beispiel #7
0
def test_project(typecode, dim, ST, quad):
    # Using sympy to compute an analytical solution
    x, y, z = symbols("x,y,z")
    sizes = (25, 24)

    funcs = {
        (1, 0): (cos(4 * y) * sin(2 * np.pi * x)) * (1 - x**2),
        (1, 1): (cos(4 * x) * sin(2 * np.pi * y)) * (1 - y**2),
        (2, 0): (sin(6 * z) * cos(4 * y) * sin(2 * np.pi * x)) * (1 - x**2),
        (2, 1): (sin(2 * z) * cos(4 * x) * sin(2 * np.pi * y)) * (1 - y**2),
        (2, 2): (sin(2 * x) * cos(4 * y) * sin(2 * np.pi * z)) * (1 - z**2)
    }
    syms = {1: (x, y), 2: (x, y, z)}
    xs = {0: x, 1: y, 2: z}

    for shape in product(*([sizes] * dim)):
        bases = []
        for n in shape[:-1]:
            bases.append(Basis(n, 'F', dtype=typecode.upper()))
        bases.append(Basis(shape[-1], 'F', dtype=typecode))

        if dim < 3:
            n = min(shape)
            if typecode in 'fdg':
                n //= 2
                n += 1
            if n < comm.size:
                continue
        for axis in range(dim + 1):
            ST0 = ST(shape[-1], quad=quad)
            bases.insert(axis, ST0)
            fft = TensorProductSpace(comm,
                                     bases,
                                     dtype=typecode,
                                     axes=axes[dim][axis])
            X = fft.local_mesh(True)
            ue = funcs[(dim, axis)]
            ul = lambdify(syms[dim], ue, 'numpy')
            uq = ul(*X).astype(typecode)
            uh = Function(fft)
            uh = fft.forward(uq, uh)
            due = ue.diff(xs[axis], 1)
            dul = lambdify(syms[dim], due, 'numpy')
            duq = dul(*X).astype(typecode)
            uf = project(Dx(uh, axis, 1), fft)
            uy = Array(fft)
            uy = fft.backward(uf, uy)
            assert np.allclose(uy, duq, 0, 1e-6)
            for ax in (x for x in range(dim + 1) if x is not axis):
                due = ue.diff(xs[axis], 1, xs[ax], 1)
                dul = lambdify(syms[dim], due, 'numpy')
                duq = dul(*X).astype(typecode)
                uf = project(Dx(Dx(uh, axis, 1), ax, 1), fft)
                uy = Array(fft)
                uy = fft.backward(uf, uy)
                assert np.allclose(uy, duq, 0, 1e-6)

            bases.pop(axis)
            fft.destroy()
Beispiel #8
0
def test_curl(typecode):
    K0 = Basis(N[0], 'F', dtype=typecode.upper())
    K1 = Basis(N[1], 'F', dtype=typecode.upper())
    K2 = Basis(N[2], 'F', dtype=typecode)
    T = TensorProductSpace(comm, (K0, K1, K2), dtype=typecode)
    X = T.local_mesh(True)
    K = T.local_wavenumbers()
    Tk = VectorTensorProductSpace(T)
    u = TrialFunction(Tk)
    v = TestFunction(Tk)

    U = Array(Tk)
    U_hat = Function(Tk)
    curl_hat = Function(Tk)
    curl_ = Array(Tk)

    # Initialize a Taylor Green vortex
    U[0] = np.sin(X[0]) * np.cos(X[1]) * np.cos(X[2])
    U[1] = -np.cos(X[0]) * np.sin(X[1]) * np.cos(X[2])
    U[2] = 0
    U_hat = Tk.forward(U, U_hat)
    Uc = U_hat.copy()
    U = Tk.backward(U_hat, U)
    U_hat = Tk.forward(U, U_hat)
    assert allclose(U_hat, Uc)

    divu_hat = project(div(U_hat), T)
    divu = Array(T)
    divu = T.backward(divu_hat, divu)
    assert allclose(divu, 0)

    curl_hat[0] = 1j * (K[1] * U_hat[2] - K[2] * U_hat[1])
    curl_hat[1] = 1j * (K[2] * U_hat[0] - K[0] * U_hat[2])
    curl_hat[2] = 1j * (K[0] * U_hat[1] - K[1] * U_hat[0])

    curl_ = Tk.backward(curl_hat, curl_)

    w_hat = Function(Tk)
    w_hat = inner(v, curl(U_hat), output_array=w_hat)
    A = inner(v, u)
    for i in range(3):
        w_hat[i] = A[i].solve(w_hat[i])

    w = Array(Tk)
    w = Tk.backward(w_hat, w)
    #from IPython import embed; embed()
    assert allclose(w, curl_)

    u_hat = Function(Tk)
    u_hat = inner(v, U, output_array=u_hat)
    for i in range(3):
        u_hat[i] = A[i].solve(u_hat[i])

    uu = Array(Tk)
    uu = Tk.backward(u_hat, uu)

    assert allclose(u_hat, U_hat)
Beispiel #9
0
def test_curl2():
    # Test projection of curl

    K0 = Basis(N[0], 'C', bc=(0, 0))
    K1 = Basis(N[1], 'F', dtype='D')
    K2 = Basis(N[2], 'F', dtype='d')
    K3 = Basis(N[0], 'C')

    T = TensorProductSpace(comm, (K0, K1, K2))
    TT = TensorProductSpace(comm, (K3, K1, K2))
    X = T.local_mesh(True)
    K = T.local_wavenumbers(False)
    Tk = VectorTensorProductSpace(T)
    TTk = MixedTensorProductSpace([T, T, TT])

    U = Array(Tk)
    U_hat = Function(Tk)
    curl_hat = Function(TTk)
    curl_ = Array(TTk)

    # Initialize a Taylor Green vortex
    U[0] = np.sin(X[0]) * np.cos(X[1]) * np.cos(X[2]) * (1 - X[0]**2)
    U[1] = -np.cos(X[0]) * np.sin(X[1]) * np.cos(X[2]) * (1 - X[0]**2)
    U[2] = 0
    U_hat = Tk.forward(U, U_hat)
    Uc = U_hat.copy()
    U = Tk.backward(U_hat, U)
    U_hat = Tk.forward(U, U_hat)
    assert allclose(U_hat, Uc)

    # Compute curl first by computing each term individually
    curl_hat[0] = 1j * (K[1] * U_hat[2] - K[2] * U_hat[1])
    curl_[0] = T.backward(
        curl_hat[0], curl_[0])  # No x-derivatives, still in Dirichlet space
    dwdx_hat = project(Dx(U_hat[2], 0, 1), TT)  # Need to use space without bc
    dvdx_hat = project(Dx(U_hat[1], 0, 1), TT)  # Need to use space without bc
    dwdx = Array(TT)
    dvdx = Array(TT)
    dwdx = TT.backward(dwdx_hat, dwdx)
    dvdx = TT.backward(dvdx_hat, dvdx)
    curl_hat[1] = 1j * K[2] * U_hat[0]
    curl_hat[2] = -1j * K[1] * U_hat[0]
    curl_[1] = T.backward(curl_hat[1], curl_[1])
    curl_[2] = T.backward(curl_hat[2], curl_[2])
    curl_[1] -= dwdx
    curl_[2] += dvdx

    # Now do it with project
    w_hat = project(curl(U_hat), TTk)
    w = Array(TTk)
    w = TTk.backward(w_hat, w)
    assert allclose(w, curl_)
    def interp(self, y, eigvals, eigvectors, eigval=1, verbose=False):
        """Interpolate solution eigenvector and it's derivative onto y

        Parameters
        ----------
            y : array
                Interpolation points
            eigvals : array
                All computed eigenvalues
            eigvectors : array
                All computed eigenvectors
            eigval : int, optional
                The chosen eigenvalue, ranked with descending imaginary
                part. The largest imaginary part is 1, the second
                largest is 2, etc.
            verbose : bool, optional
                Print information or not
        """
        nx, eigval = self.get_eigval(eigval, eigvals, verbose)
        SB = Basis(self.N, 'C', bc='Biharmonic', quad=self.quad, dtype='D')
        phi_hat = Function(SB)
        phi_hat[:-4] = np.squeeze(eigvectors[:, nx])
        phi = phi_hat.eval(y)
        dphidy = Dx(phi_hat, 0, 1).eval(y)
        return eigval, phi, dphidy
def test_project(typecode, dim, ST, quad):
    # Using sympy to compute an analytical solution
    x, y, z = symbols("x,y,z")
    sizes = (20, 19)

    funcs = {
        (1, 0): (cos(1*y)*sin(1*np.pi*x))*(1-x**2),
        (1, 1): (cos(1*x)*sin(1*np.pi*y))*(1-y**2),
        (2, 0): (sin(1*z)*cos(1*y)*sin(1*np.pi*x))*(1-x**2),
        (2, 1): (sin(1*z)*cos(1*x)*sin(1*np.pi*y))*(1-y**2),
        (2, 2): (sin(1*x)*cos(1*y)*sin(1*np.pi*z))*(1-z**2)
        }
    xs = {0:x, 1:y, 2:z}

    for shape in product(*([sizes]*dim)):
        bases = []
        for n in shape[:-1]:
            bases.append(Basis(n, 'F', dtype=typecode.upper()))
        bases.append(Basis(shape[-1], 'F', dtype=typecode))

        for axis in range(dim+1):
            ST0 = ST(shape[-1], quad=quad)
            bases.insert(axis, ST0)
            fft = TensorProductSpace(comm, bases, dtype=typecode, axes=axes[dim][axis])
            dfft = fft.get_orthogonal()
            X = fft.local_mesh(True)
            ue = funcs[(dim, axis)]
            uq = Array(fft, buffer=ue)
            uh = Function(fft)
            uh = fft.forward(uq, uh)
            due = ue.diff(xs[axis], 1)
            duq = Array(fft, buffer=due)
            uf = project(Dx(uh, axis, 1), dfft).backward()
            assert np.linalg.norm(uf-duq) < 1e-5
            for ax in (x for x in range(dim+1) if x is not axis):
                due = ue.diff(xs[axis], 1, xs[ax], 1)
                duq = Array(fft, buffer=due)
                uf = project(Dx(Dx(uh, axis, 1), ax, 1), dfft).backward()
                assert np.linalg.norm(uf-duq) < 1e-5

            bases.pop(axis)
            fft.destroy()
            dfft.destroy()
    def assemble(self):
        N = self.N
        SB = Basis(N, 'C', bc='Biharmonic', quad=self.quad)
        SB.plan((N, N), 0, np.float, {})

        x, _ = self.x, self.w = SB.points_and_weights(N)

        # Trial function
        P4 = SB.evaluate_basis_all(x=x)

        # Second derivatives
        T2x = SB.evaluate_basis_derivative_all(x=x, k=2)

        # (u'', v)
        K = np.zeros((N, N))
        K[:-4, :-4] = inner_product((SB, 0), (SB, 2)).diags().toarray()

        # ((1-x**2)u, v)
        xx = np.broadcast_to((1 - x**2)[:, np.newaxis], (N, N))
        #K1 = np.dot(w*P4.T, xx*P4)  # Alternative: K1 = np.dot(w*P4.T, ((1-x**2)*P4.T).T)
        K1 = np.zeros((N, N))
        K1 = SB.scalar_product(xx * P4, K1)
        K1 = extract_diagonal_matrix(
            K1).diags().toarray()  # For improved roundoff

        # ((1-x**2)u'', v)
        K2 = np.zeros((N, N))
        K2 = SB.scalar_product(xx * T2x, K2)
        K2 = extract_diagonal_matrix(
            K2).diags().toarray()  # For improved roundoff

        # (u'''', v)
        Q = np.zeros((self.N, self.N))
        Q[:-4, :-4] = inner_product((SB, 0), (SB, 4)).diags().toarray()

        # (u, v)
        M = np.zeros((self.N, self.N))
        M[:-4, :-4] = inner_product((SB, 0), (SB, 0)).diags().toarray()

        Re = self.Re
        a = self.alfa
        B = -Re * a * 1j * (K - a**2 * M)
        A = Q - 2 * a**2 * K + a**4 * M - 2 * a * Re * 1j * M - 1j * a * Re * (
            K2 - a**2 * K1)
        return A, B
Beispiel #13
0
def test_helmholtz3D(family, axis):
    la = lla
    if family == 'chebyshev':
        la = cla
    N = (8, 9, 10)
    SD = Basis(N[allaxes3D[axis][0]], family=family, bc=(0, 0))
    K1 = Basis(N[allaxes3D[axis][1]], family='F', dtype='D')
    K2 = Basis(N[allaxes3D[axis][2]], family='F', dtype='d')
    subcomms = mpi4py_fft.pencil.Subcomm(MPI.COMM_WORLD, [0, 1, 1])
    bases = [0] * 3
    bases[allaxes3D[axis][0]] = SD
    bases[allaxes3D[axis][1]] = K1
    bases[allaxes3D[axis][2]] = K2
    T = TensorProductSpace(subcomms, bases, axes=allaxes3D[axis])
    u = TrialFunction(T)
    v = TestFunction(T)
    if family == 'chebyshev':
        mat = inner(v, div(grad(u)))
    else:
        mat = inner(grad(v), grad(u))

    H = la.Helmholtz(*mat)
    u = Function(T)
    s = SD.sl[SD.slice()]
    u[s] = np.random.random(u[s].shape) + 1j * np.random.random(u[s].shape)
    f = Function(T)
    f = H.matvec(u, f)

    g0 = Function(T)
    g1 = Function(T)
    M = {d.get_key(): d for d in mat}
    g0 = M['ADDmat'].matvec(u, g0)
    g1 = M['BDDmat'].matvec(u, g1)

    assert np.linalg.norm(f - (g0 + g1)) < 1e-12, np.linalg.norm(f - (g0 + g1))

    uc = Function(T)
    uc = H(uc, f)
    assert np.linalg.norm(uc - u) < 1e-12
Beispiel #14
0
def test_mul2():
    mat = SparseMatrix({0: 1}, (3, 3))
    v = np.ones(3)
    c = mat * v
    assert np.allclose(c, 1)
    mat = SparseMatrix({-2: 1, -1: 1, 0: 1, 1: 1, 2: 1}, (3, 3))
    c = mat * v
    assert np.allclose(c, 3)
    SD = Basis(8, "L", bc=(0, 0), scaled=True)
    u = TrialFunction(SD)
    v = TestFunction(SD)
    mat = inner(grad(u), grad(v))
    z = Function(SD, val=1)
    c = mat * z
    assert np.allclose(c[:6], 1)
    def assemble(self):
        N = self.N
        SB = Basis(N, 'C', bc='Biharmonic', quad=self.quad)
        SB.plan((N, N), 0, np.float, {})

        x, _ = self.x, self.w = SB.points_and_weights(N)

        # Trial function
        P4 = SB.evaluate_basis_all(x=x)

        # Second derivatives
        T2x = SB.evaluate_basis_derivative_all(x=x, k=2)

        # (u'', v)
        K = np.zeros((N, N))
        K[:-4, :-4] = inner_product((SB, 0), (SB, 2)).diags().toarray()

        # ((1-x**2)u, v)
        xx = np.broadcast_to((1-x**2)[:, np.newaxis], (N, N))
        #K1 = np.dot(w*P4.T, xx*P4)  # Alternative: K1 = np.dot(w*P4.T, ((1-x**2)*P4.T).T)
        K1 = np.zeros((N, N))
        K1 = SB.scalar_product(xx*P4, K1)
        K1 = extract_diagonal_matrix(K1).diags().toarray() # For improved roundoff

        # ((1-x**2)u'', v)
        K2 = np.zeros((N, N))
        K2 = SB.scalar_product(xx*T2x, K2)
        K2 = extract_diagonal_matrix(K2).diags().toarray() # For improved roundoff

        # (u'''', v)
        Q = np.zeros((self.N, self.N))
        Q[:-4, :-4] = inner_product((SB, 0), (SB, 4)).diags().toarray()

        # (u, v)
        M = np.zeros((self.N, self.N))
        M[:-4, :-4] = inner_product((SB, 0), (SB, 0)).diags().toarray()

        Re = self.Re
        a = self.alfa
        B = -Re*a*1j*(K-a**2*M)
        A = Q-2*a**2*K+a**4*M - 2*a*Re*1j*M - 1j*a*Re*(K2-a**2*K1)
        return A, B