Beispiel #1
0
    def interp(self, y, eigval=1, same_mesh=False, verbose=False):
        """Interpolate solution eigenvector and it's derivative onto y
        """
        N = self.N
        nx, eigval = self.get_eigval(eigval, verbose)
        phi_hat = np.zeros(N, np.complex)
        phi_hat[:-4] = np.squeeze(self.eigvectors[:, nx])
        if same_mesh:
            phi = np.zeros_like(phi_hat)
            dphidy = np.zeros_like(phi_hat)
            if self.SB is None:
                self.SB = ShenBiharmonicBasis(N, quad=self.quad, plan=True)
                self.SD = ShenDirichletBasis(N, quad=self.quad, plan=True)
                self.CDB = inner_product((self.SD, 0), (self.SB, 1))

            phi = self.SB.ifst(phi_hat, phi)
            dphidy_hat = self.CDB.matvec(phi_hat)
            dphidy_hat = self.SD.apply_inverse_mass(dphidy_hat)
            dphidy = self.SD.backward(dphidy_hat, dphidy)

        else:
            # Recompute interpolation matrices if necessary
            if not len(self.P4) == len(y):
                SB = ShenBiharmonicBasis(N, quad=self.quad)
                V = self.V = SB.vandermonde(y)
                P4 = self.P4 = SB.get_vandermonde_basis(V)
                T4x = self.T4x = SB.get_vandermonde_basis_derivative(V, 1)
            phi = np.dot(self.P4, phi_hat)
            dphidy = np.dot(self.T4x, phi_hat)

        return phi, dphidy
Beispiel #2
0
def test_Helmholtz_matvec(quad):
    M = 2*N
    SD = ShenDirichletBasis(M, quad=quad)
    kx = 11
    uj = np.random.randn(M)
    u_hat = np.zeros(M)
    u_hat = SD.forward(uj, u_hat)
    uj = SD.backward(u_hat, uj)

    B = inner_product((SD, 0), (SD, 0))
    A = inner_product((SD, 0), (SD, 2))

    AB = HelmholtzCoeff(M, 1, kx**2, SD.quad)

    u1 = np.zeros(M)
    u1 = SD.forward(uj, u1)
    c0 = np.zeros_like(u1)
    c1 = np.zeros_like(u1)
    c = A.matvec(u1, c0)+kx**2*B.matvec(u1, c1)

    b = np.zeros(M)
    #LUsolve.Mult_Helmholtz_1D(M, SD.quad=="GL", 1, kx**2, u1, b)
    b = AB.matvec(u1, b)
    #from IPython import embed; embed()
    assert np.allclose(c, b)

    b = np.zeros((M, 4, 4), dtype=np.complex)
    u1 = u1.repeat(16).reshape((M, 4, 4)) +1j*u1.repeat(16).reshape((M, 4, 4))
    kx = np.zeros((1, 4, 4))+kx
    #LUsolve.Mult_Helmholtz_3D_complex(M, SD.quad=="GL", 1.0, kx**2, u1, b)
    AB = HelmholtzCoeff(M, 1, kx**2, SD.quad)
    b = AB.matvec(u1, b)

    assert np.linalg.norm(b[:, 2, 2].real - c)/(M*16) < 1e-12
    assert np.linalg.norm(b[:, 2, 2].imag - c)/(M*16) < 1e-12
Beispiel #3
0
def test_Mult_CTD(quad):
    SD = ShenDirichletBasis(N, quad=quad)
    SD.plan(N, 0, np.complex, {})
    C = inner_product((SD.CT, 0), (SD, 1))
    B = inner_product((SD.CT, 0), (SD.CT, 0))

    vk = np.random.randn((N))+np.random.randn((N))*1j
    wk = np.random.randn((N))+np.random.randn((N))*1j

    bv = np.zeros(N, dtype=np.complex)
    bw = np.zeros(N, dtype=np.complex)
    vk0 = np.zeros(N, dtype=np.complex)
    wk0 = np.zeros(N, dtype=np.complex)
    cv = np.zeros(N, dtype=np.complex)
    cw = np.zeros(N, dtype=np.complex)

    vk0 = SD.forward(vk, vk0)
    vk = SD.backward(vk0, vk)
    vk0 = SD.forward(vk, vk0)
    wk0 = SD.forward(wk, wk0)
    wk = SD.backward(wk0, wk)
    wk0 = SD.forward(wk, wk0)

    LUsolve.Mult_CTD_1D(N, vk0, wk0, bv, bw)

    cv = np.zeros_like(vk0)
    cw = np.zeros_like(wk0)
    cv = C.matvec(vk0, cv)
    cw = C.matvec(wk0, cw)
    cv /= B[0]
    cw /= B[0]

    assert np.allclose(cv, bv)
    assert np.allclose(cw, bw)
Beispiel #4
0
def test_Mult_CTD_3D(quad):
    SD = ShenDirichletBasis(N, quad=quad)
    SD.plan((N, 4, 4), 0, np.complex, {})

    C = inner_product((SD.CT, 0), (SD, 1))
    B = inner_product((SD.CT, 0), (SD.CT, 0))

    vk = np.random.random((N, 4, 4))+np.random.random((N, 4, 4))*1j
    wk = np.random.random((N, 4, 4))+np.random.random((N, 4, 4))*1j

    bv = np.zeros((N, 4, 4), dtype=np.complex)
    bw = np.zeros((N, 4, 4), dtype=np.complex)
    vk0 = np.zeros((N, 4, 4), dtype=np.complex)
    wk0 = np.zeros((N, 4, 4), dtype=np.complex)
    cv = np.zeros((N, 4, 4), dtype=np.complex)
    cw = np.zeros((N, 4, 4), dtype=np.complex)

    vk0 = SD.forward(vk, vk0)
    vk = SD.backward(vk0, vk)
    vk0 = SD.forward(vk, vk0)
    wk0 = SD.forward(wk, wk0)
    wk = SD.backward(wk0, wk)
    wk0 = SD.forward(wk, wk0)

    LUsolve.Mult_CTD_3D_ptr(N, vk0, wk0, bv, bw, 0)

    cv = np.zeros_like(vk0)
    cw = np.zeros_like(wk0)
    cv = C.matvec(vk0, cv)
    cw = C.matvec(wk0, cw)
    cv /= B[0].repeat(np.array(bv.shape[1:]).prod()).reshape(bv.shape)
    cw /= B[0].repeat(np.array(bv.shape[1:]).prod()).reshape(bv.shape)

    assert np.allclose(cv, bv)
    assert np.allclose(cw, bw)
    def interp(self,
               y,
               eigvals,
               eigvectors,
               eigval=1,
               same_mesh=False,
               verbose=False):
        """Interpolate solution eigenvector and it's derivative onto y

        args:
            y            Interpolation points
            eigvals      All computed eigenvalues
            eigvectors   All computed eigenvectors
        kwargs:
            eigval       The chosen eigenvalue, ranked with descending imaginary
                         part. The largest imaginary part is 1, the second
                         largest is 2, etc.
            same_mesh    Boolean. Whether or not to interpolate to the same
                         quadrature points as used for computing the eigenvectors
            verbose      Boolean. 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 same_mesh:
            phi = np.zeros_like(phi_hat)
            dphidy = np.zeros_like(phi_hat)
            if self.SB is None:
                self.SB = ShenBiharmonicBasis(N, quad=self.quad, plan=True)
                self.SD = ShenDirichletBasis(N, quad=self.quad, plan=True)
                self.CDB = inner_product((self.SD, 0), (self.SB, 1))

            phi = self.SB.ifst(phi_hat, phi)
            dphidy_hat = self.CDB.matvec(phi_hat)
            dphidy_hat = self.SD.apply_inverse_mass(dphidy_hat)
            dphidy = self.SD.backward(dphidy_hat, dphidy)

        else:
            # Recompute interpolation matrices if necessary
            if not len(self.P4) == len(y):
                SB = ShenBiharmonicBasis(N, quad=self.quad)
                V = SB.vandermonde(y)
                self.P4 = SB.get_vandermonde_basis(V)
                self.T4x = SB.get_vandermonde_basis_derivative(V, 1)
            phi = np.dot(self.P4, phi_hat)
            dphidy = np.dot(self.T4x, phi_hat)

        return eigval, phi, dphidy
def test_Helmholtz2(quad):
    M = 2 * N
    SD = ShenDirichletBasis(M, quad=quad, plan=True)
    kx = 12
    points, weights = SD.points_and_weights(M)
    uj = np.random.randn(M)
    u_hat = np.zeros(M)
    u_hat = SD.forward(uj, u_hat)
    uj = SD.backward(u_hat, uj)

    #from IPython import embed; embed()
    A = inner_product((SD, 0), (SD, 2))
    B = inner_product((SD, 0), (SD, 0))
    s = SD.slice()

    u1 = np.zeros(M)
    u1 = SD.forward(uj, u1)
    c0 = np.zeros_like(u1)
    c1 = np.zeros_like(u1)
    c = A.matvec(u1, c0) + kx**2 * B.matvec(u1, c1)

    b = np.zeros(M)
    H = Helmholtz(M, kx, SD)
    b = H.matvec(u1, b)
    #LUsolve.Mult_Helmholtz_1D(M, SD.quad=="GL", 1, kx**2, u1, b)
    assert np.allclose(c, b)

    b = np.zeros((M, 4, 4), dtype=np.complex)
    u1 = u1.repeat(16).reshape((M, 4, 4)) + 1j * u1.repeat(16).reshape(
        (M, 4, 4))
    kx = np.zeros((4, 4)) + kx
    H = Helmholtz(M, kx, SD)
    b = H.matvec(u1, b)
    #LUsolve.Mult_Helmholtz_3D_complex(M, SD.quad=="GL", 1.0, kx**2, u1, b)
    assert np.linalg.norm(b[:, 2, 2].real - c) / (M * 16) < 1e-12
    assert np.linalg.norm(b[:, 2, 2].imag - c) / (M * 16) < 1e-12
class OrrSommerfeld(object):
    def __init__(self, **kwargs):
        self.par = {'alfa': 1., 'Re': 8000., 'N': 80, 'quad': 'GC'}
        self.par.update(**kwargs)
        for name, val in six.iteritems(self.par):
            setattr(self, name, val)
        self.P4 = np.zeros(0)
        self.T4x = np.zeros(0)
        self.SB, self.SD, self.CDB = (None, ) * 3
        self.x, self.w = None, None

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

        args:
            y            Interpolation points
            eigvals      All computed eigenvalues
            eigvectors   All computed eigenvectors
        kwargs:
            eigval       The chosen eigenvalue, ranked with descending imaginary
                         part. The largest imaginary part is 1, the second
                         largest is 2, etc.
            same_mesh    Boolean. Whether or not to interpolate to the same
                         quadrature points as used for computing the eigenvectors
            verbose      Boolean. 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 same_mesh:
            phi = np.zeros_like(phi_hat)
            dphidy = np.zeros_like(phi_hat)
            if self.SB is None:
                self.SB = ShenBiharmonicBasis(N, quad=self.quad, plan=True)
                self.SD = ShenDirichletBasis(N, quad=self.quad, plan=True)
                self.CDB = inner_product((self.SD, 0), (self.SB, 1))

            phi = self.SB.ifst(phi_hat, phi)
            dphidy_hat = self.CDB.matvec(phi_hat)
            dphidy_hat = self.SD.apply_inverse_mass(dphidy_hat)
            dphidy = self.SD.backward(dphidy_hat, dphidy)

        else:
            # Recompute interpolation matrices if necessary
            if not len(self.P4) == len(y):
                SB = ShenBiharmonicBasis(N, quad=self.quad)
                V = SB.vandermonde(y)
                self.P4 = SB.get_vandermonde_basis(V)
                self.T4x = SB.get_vandermonde_basis_derivative(V, 1)
            phi = np.dot(self.P4, phi_hat)
            dphidy = np.dot(self.T4x, phi_hat)

        return eigval, phi, dphidy

    def assemble(self):
        N = self.N
        SB = ShenBiharmonicBasis(N, quad=self.quad)
        SB.plan((N, N), 0, np.float, {})

        x, w = self.x, self.w = SB.points_and_weights(N)
        V = SB.vandermonde(x)

        # Trial function
        P4 = SB.get_vandermonde_basis(V)

        # Second derivatives
        T2x = SB.get_vandermonde_basis_derivative(V, 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

    def solve(self, verbose=False):
        """Solve the Orr-Sommerfeld eigenvalue problem
        """
        if verbose:
            print('Solving the Orr-Sommerfeld eigenvalue problem...')
            print('Re = ' + str(self.par['Re']) + ' and alfa = ' +
                  str(self.par['alfa']))
        A, B = self.assemble()
        return eig(A[:-4, :-4], B[:-4, :-4])
        # return eig(np.dot(inv(B[:-4, :-4]), A[:-4, :-4]))

    @staticmethod
    def get_eigval(nx, eigvals, verbose=False):
        """Get the chosen eigenvalue

        Args:
            nx       The chosen eigenvalue. nx=1 corresponds to the one with the
                     largest imaginary part, nx=2 the second largest etc.
            eigvals  Computed eigenvalues

            verbose  Print the value of the chosen eigenvalue

        """
        indices = np.argsort(np.imag(eigvals))
        indi = indices[-1 * np.array(nx)]
        eigval = eigvals[indi]
        if verbose:
            ev = list(eigval) if np.ndim(eigval) else [eigval]
            indi = list(indi) if np.ndim(indi) else [indi]
            for i, (e, v) in enumerate(zip(ev, indi)):
                print('Eigenvalue {} ({}) = {:2.16e}'.format(i + 1, v, e))
        return indi, eigval
Beispiel #8
0
def get_context():
    """Set up context for solver"""

    # Get points and weights for Chebyshev weighted integrals
    ST = ShenDirichletBasis(params.N[0], quad=params.Dquad)
    SB = ShenBiharmonicBasis(params.N[0], quad=params.Bquad)
    CT = Basis(params.N[0], quad=params.Dquad)
    ST0 = ShenDirichletBasis(params.N[0], quad=params.Dquad,
                             plan=True)  # For 1D problem
    K0 = C2CBasis(params.N[1], domain=(0, params.L[1]))
    K1 = R2CBasis(params.N[2], domain=(0, params.L[2]))

    #CT = ST.CT  # Chebyshev transform
    FST = TensorProductSpace(comm, (ST, K0, K1), **{
        'threads': params.threads,
        'planner_effort': params.planner_effort["dct"]
    })  # Dirichlet
    FSB = TensorProductSpace(comm, (SB, K0, K1), **{
        'threads': params.threads,
        'planner_effort': params.planner_effort["dct"]
    })  # Biharmonic
    FCT = TensorProductSpace(comm, (CT, K0, K1), **{
        'threads': params.threads,
        'planner_effort': params.planner_effort["dct"]
    })  # Regular Chebyshev
    VFS = VectorTensorProductSpace([FSB, FST, FST])

    # Padded
    STp = ShenDirichletBasis(params.N[0], quad=params.Dquad)
    SBp = ShenBiharmonicBasis(params.N[0], quad=params.Bquad)
    CTp = Basis(params.N[0], quad=params.Dquad)
    K0p = C2CBasis(params.N[1], padding_factor=1.5, domain=(0, params.L[1]))
    K1p = R2CBasis(params.N[2], padding_factor=1.5, domain=(0, params.L[2]))
    FSTp = TensorProductSpace(
        comm, (STp, K0p, K1p), **{
            'threads': params.threads,
            'planner_effort': params.planner_effort["dct"]
        })
    FSBp = TensorProductSpace(
        comm, (SBp, K0p, K1p), **{
            'threads': params.threads,
            'planner_effort': params.planner_effort["dct"]
        })
    FCTp = TensorProductSpace(
        comm, (CTp, K0p, K1p), **{
            'threads': params.threads,
            'planner_effort': params.planner_effort["dct"]
        })
    VFSp = VectorTensorProductSpace([FSBp, FSTp, FSTp])

    VFSp = VFS
    FCTp = FCT
    FSTp = FST
    FSBp = FSB

    Nu = params.N[0] - 2  # Number of velocity modes in Shen basis
    Nb = params.N[0] - 4  # Number of velocity modes in Shen biharmonic basis
    u_slice = slice(0, Nu)
    v_slice = slice(0, Nb)

    float, complex, mpitype = datatypes("double")

    # Mesh variables
    X = FST.local_mesh(True)
    x0, x1, x2 = FST.mesh()
    K = FST.local_wavenumbers(scaled=True)

    # Solution variables
    U = Array(VFS, False)
    U0 = Array(VFS, False)
    U_hat = Array(VFS)
    U_hat0 = Array(VFS)
    g = Array(FST)

    # primary variable
    u = (U_hat, g)

    H_hat = Array(VFS)
    H_hat0 = Array(VFS)
    H_hat1 = Array(VFS)

    dU = Array(VFS)
    hv = Array(FST)
    hg = Array(FST)
    Source = Array(VFS, False)
    Sk = Array(VFS)

    K2 = K[1] * K[1] + K[2] * K[2]
    K_over_K2 = np.zeros((2, ) + g.shape)
    for i in range(2):
        K_over_K2[i] = K[i + 1] / np.where(K2 == 0, 1, K2)

    work = work_arrays()

    nu, dt, N = params.nu, params.dt, params.N
    K4 = K2**2
    kx = K[0][:, 0, 0]

    alfa = K2[0] - 2.0 / nu / dt
    # Collect all matrices
    mat = config.AttributeDict(
        dict(
            CDD=inner_product((ST, 0), (ST, 1)),
            AB=HelmholtzCoeff(kx, -1.0, -alfa, ST.quad),
            AC=BiharmonicCoeff(kx,
                               nu * dt / 2., (1. - nu * dt * K2[0]),
                               -(K2[0] - nu * dt / 2. * K4[0]),
                               quad=SB.quad),
            # Matrices for biharmonic equation
            CBD=inner_product((SB, 0), (ST, 1)),
            ABB=inner_product((SB, 0), (SB, 2)),
            BBB=inner_product((SB, 0), (SB, 0)),
            SBB=inner_product((SB, 0), (SB, 4)),
            # Matrices for Helmholtz equation
            ADD=inner_product((ST, 0), (ST, 2)),
            BDD=inner_product((ST, 0), (ST, 0)),
            BBD=inner_product((SB, 0), (ST, 0)),
            CDB=inner_product((ST, 0), (SB, 1)),
            ADD0=inner_product((ST0, 0), (ST0, 2)),
            BDD0=inner_product((ST0, 0), (ST0, 0)),
        ))

    # Collect all linear algebra solvers
    #la = config.AttributeDict(dict(
    #HelmholtzSolverG = Helmholtz(N[0], np.sqrt(K2[0]+2.0/nu/dt), ST),
    #BiharmonicSolverU = Biharmonic(N[0], -nu*dt/2., 1.+nu*dt*K2[0],
    #-(K2[0] + nu*dt/2.*K4[0]), quad=SB.quad,
    #solver="cython"),
    #HelmholtzSolverU0 = Helmholtz(N[0], np.sqrt(2./nu/dt), ST),
    #TDMASolverD = TDMA(inner_product((ST, 0), (ST, 0)))
    #)
    #)
    mat.ADD.axis = 0
    mat.BDD.axis = 0
    mat.SBB.axis = 0

    la = config.AttributeDict(
        dict(HelmholtzSolverG=Helmholtz(mat.ADD, mat.BDD, -np.ones(
            (1, 1, 1)), (K2[0] + 2.0 / nu / dt)[np.newaxis, :, :]),
             BiharmonicSolverU=Biharmonic(
                 mat.SBB, mat.ABB, mat.BBB, -nu * dt / 2. * np.ones(
                     (1, 1, 1)), (1. + nu * dt * K2[0])[np.newaxis, :, :],
                 (-(K2[0] + nu * dt / 2. * K4[0]))[np.newaxis, :, :]),
             HelmholtzSolverU0=old_Helmholtz(N[0], np.sqrt(2. / nu / dt), ST),
             TDMASolverD=TDMA(inner_product((ST, 0), (ST, 0)))))

    hdf5file = KMMWriter({
        "U": U[0],
        "V": U[1],
        "W": U[2]
    },
                         chkpoint={
                             'current': {
                                 'U': U
                             },
                             'previous': {
                                 'U': U0
                             }
                         },
                         filename=params.solver + ".h5",
                         mesh={
                             "x": x0,
                             "y": x1,
                             "z": x2
                         })

    return config.AttributeDict(locals())
Beispiel #9
0
def get_context():
    """Set up context for solver"""

    # Get points and weights for Chebyshev weighted integrals
    ST = ShenDirichletBasis(params.N[0],
                            quad=params.Dquad,
                            threads=params.threads,
                            planner_effort=params.planner_effort["dct"])
    SN = ShenNeumannBasis(params.N[0],
                          quad=params.Nquad,
                          threads=params.threads,
                          planner_effort=params.planner_effort["dct"])
    CT = ST.CT

    Nf = params.N[
        2] / 2 + 1  # Number of independent complex wavenumbers in z-direction
    Nu = params.N[0] - 2  # Number of velocity modes in Shen basis
    Nq = params.N[0] - 3  # Number of pressure modes in Shen basis
    u_slice = slice(0, Nu)
    p_slice = slice(1, Nu)

    FST = SlabShen_R2C(params.N,
                       params.L,
                       comm,
                       threads=params.threads,
                       communication=params.communication,
                       planner_effort=params.planner_effort,
                       dealias_cheb=params.dealias_cheb)

    float, complex, mpitype = datatypes("double")

    # Get grid for velocity points
    X = FST.get_local_mesh(ST)
    x0, x1, x2 = FST.get_mesh_dims(ST)

    U = zeros((3, ) + FST.real_shape(), dtype=float)
    U_hat = zeros((3, ) + FST.complex_shape(), dtype=complex)
    P = zeros(FST.real_shape(), dtype=float)
    P_hat = zeros(FST.complex_shape(), dtype=complex)
    Pcorr = zeros(FST.complex_shape(), dtype=complex)
    U0 = zeros((3, ) + FST.real_shape(), dtype=float)
    U_hat0 = zeros((3, ) + FST.complex_shape(), dtype=complex)
    U_hat1 = zeros((3, ) + FST.complex_shape(), dtype=complex)
    dU = zeros((3, ) + FST.complex_shape(), dtype=complex)
    H_hat = zeros((3, ) + FST.complex_shape(), dtype=complex)
    H_hat0 = zeros((3, ) + FST.complex_shape(), dtype=complex)
    H_hat1 = zeros((3, ) + FST.complex_shape(), dtype=complex)

    diff0 = zeros((3, ) + FST.complex_shape(), dtype=complex)
    Source = zeros((3, ) + FST.real_shape(), dtype=float)
    Sk = zeros((3, ) + FST.complex_shape(), dtype=complex)

    K = FST.get_local_wavenumbermesh(scaled=True)
    K2 = K[1] * K[1] + K[2] * K[2]
    K_over_K2 = zeros((3, ) + FST.complex_shape())
    for i in range(3):
        K_over_K2[i] = K[i] / np.where(K2 == 0, 1, K2)
    work = work_arrays()

    # Primary variable
    u = (U_hat, P_hat)

    nu, dt, N = params.nu, params.dt, params.N

    # Collect all linear algebra solvers
    la = config.AttributeDict(
        dict(HelmholtzSolverU=Helmholtz(N[0], np.sqrt(K2[0] + 2.0 / nu / dt),
                                        ST),
             HelmholtzSolverP=Helmholtz(N[0], np.sqrt(K2[0]), SN),
             TDMASolverD=TDMA(inner_product((ST, 0), (ST, 0))),
             TDMASolverN=TDMA(inner_product((SN, 0), (SN, 0)))))

    alfa = K2[0] - 2.0 / nu / dt

    # Collect all matrices
    kx = K[0][:, 0, 0]
    mat = config.AttributeDict(
        dict(CDN=inner_product((ST, 0), (SN, 1)),
             CND=inner_product((SN, 0), (ST, 1)),
             BDN=inner_product((ST, 0), (SN, 0)),
             CDD=inner_product((ST, 0), (ST, 1)),
             BDD=inner_product((ST, 0), (ST, 0)),
             BDT=inner_product((ST, 0), (CT, 0)),
             AB=HelmholtzCoeff(kx, -1.0, -alfa, ST.quad)))

    hdf5file = IPCSWriter({
        "U": U[0],
        "V": U[1],
        "W": U[2],
        "P": P
    },
                          chkpoint={
                              'current': {
                                  'U': U,
                                  'P': P
                              },
                              'previous': {
                                  'U': U0
                              }
                          },
                          filename=params.solver + ".h5",
                          mesh={
                              "x": x0,
                              "xp": FST.get_mesh_dim(SN, 0),
                              "y": x1,
                              "z": x2
                          })

    return config.AttributeDict(locals())
Beispiel #10
0
def test_Mult_Div():

    SD = ShenDirichletBasis(N, "GC")
    SN = ShenNeumannBasis(N, "GC")
    SD.plan(N, 0, np.complex, {})
    SN.plan(N, 0, np.complex, {})

    Cm = inner_product((SN, 0), (SD, 1))
    Bm = inner_product((SN, 0), (SD, 0))

    uk = np.random.randn((N))+np.random.randn((N))*1j
    vk = np.random.randn((N))+np.random.randn((N))*1j
    wk = np.random.randn((N))+np.random.randn((N))*1j

    b = np.zeros(N, dtype=np.complex)
    uk0 = np.zeros(N, dtype=np.complex)
    vk0 = np.zeros(N, dtype=np.complex)
    wk0 = np.zeros(N, dtype=np.complex)

    uk0 = SD.forward(uk, uk0)
    uk = SD.backward(uk0, uk)
    uk0 = SD.forward(uk, uk0)
    vk0 = SD.forward(vk, vk0)
    vk = SD.backward(vk0, vk)
    vk0 = SD.forward(vk, vk0)
    wk0 = SD.forward(wk, wk0)
    wk = SD.backward(wk0, wk)
    wk0 = SD.forward(wk, wk0)

    LUsolve.Mult_Div_1D(N, 7, 7, uk0[:N-2], vk0[:N-2], wk0[:N-2], b[1:N-2])

    uu = np.zeros_like(uk0)
    v0 = np.zeros_like(vk0)
    w0 = np.zeros_like(wk0)
    uu = Cm.matvec(uk0, uu)
    uu += 1j*7*Bm.matvec(vk0, v0) + 1j*7*Bm.matvec(wk0, w0)

    #from IPython import embed; embed()
    assert np.allclose(uu, b)

    uk0 = uk0.repeat(4*4).reshape((N, 4, 4)) + 1j*uk0.repeat(4*4).reshape((N, 4, 4))
    vk0 = vk0.repeat(4*4).reshape((N, 4, 4)) + 1j*vk0.repeat(4*4).reshape((N, 4, 4))
    wk0 = wk0.repeat(4*4).reshape((N, 4, 4)) + 1j*wk0.repeat(4*4).reshape((N, 4, 4))
    b = np.zeros((N, 4, 4), dtype=np.complex)
    m = np.zeros((4, 4))+7
    n = np.zeros((4, 4))+7
    LUsolve.Mult_Div_3D(N, m, n, uk0[:N-2], vk0[:N-2], wk0[:N-2], b[1:N-2])

    uu = np.zeros_like(uk0)
    v0 = np.zeros_like(vk0)
    w0 = np.zeros_like(wk0)
    uu = Cm.matvec(uk0, uu)
    uu += 1j*7*Bm.matvec(vk0, v0) + 1j*7*Bm.matvec(wk0, w0)

    assert np.allclose(uu, b)
Beispiel #11
0
def get_context():
    """Set up context for solver"""

    # Get points and weights for Chebyshev weighted integrals
    ST = ShenDirichletBasis(params.N[0], quad=params.Dquad)
    SB = ShenBiharmonicBasis(params.N[0], quad=params.Bquad)
    CT = ST.CT  # Chebyshev transform

    Nu = params.N[0] - 2  # Number of velocity modes in Shen basis
    Nb = params.N[0] - 4  # Number of velocity modes in Shen biharmonic basis
    u_slice = slice(0, Nu)
    v_slice = slice(0, Nb)

    FST = SlabShen_R2C(params.N,
                       params.L,
                       comm,
                       threads=params.threads,
                       communication=params.communication,
                       planner_effort=params.planner_effort,
                       dealias_cheb=params.dealias_cheb)

    float, complex, mpitype = datatypes("double")

    ST.plan(FST.complex_shape(), 0, complex, {
        'threads': params.threads,
        'planner_effort': params.planner_effort["dct"]
    })
    SB.plan(FST.complex_shape(), 0, complex, {
        'threads': params.threads,
        'planner_effort': params.planner_effort["dct"]
    })

    # Mesh variables
    X = FST.get_local_mesh(ST)
    x0, x1, x2 = FST.get_mesh_dims(ST)
    K = FST.get_local_wavenumbermesh(scaled=True)

    K2 = K[1] * K[1] + K[2] * K[2]
    K_over_K2 = zeros((2, ) + FST.complex_shape())
    for i in range(2):
        K_over_K2[i] = K[i + 1] / np.where(K2 == 0, 1, K2)

    # Solution variables
    U = zeros((3, ) + FST.real_shape(), dtype=float)
    U0 = zeros((3, ) + FST.real_shape(), dtype=float)
    U_hat = zeros((3, ) + FST.complex_shape(), dtype=complex)
    U_hat0 = zeros((3, ) + FST.complex_shape(), dtype=complex)
    g = zeros(FST.complex_shape(), dtype=complex)

    # primary variable
    u = (U_hat, g)

    H_hat = zeros((3, ) + FST.complex_shape(), dtype=complex)
    H_hat0 = zeros((3, ) + FST.complex_shape(), dtype=complex)
    H_hat1 = zeros((3, ) + FST.complex_shape(), dtype=complex)

    dU = zeros((3, ) + FST.complex_shape(), dtype=complex)
    hv = zeros(FST.complex_shape(), dtype=complex)
    hg = zeros(FST.complex_shape(), dtype=complex)
    Source = zeros((3, ) + FST.real_shape(), dtype=float)
    Sk = zeros((3, ) + FST.complex_shape(), dtype=complex)

    work = work_arrays()

    nu, dt, N = params.nu, params.dt, params.N
    K4 = K2**2
    kx = K[0][:, 0, 0]

    # Collect all linear algebra solvers
    la = config.AttributeDict(
        dict(HelmholtzSolverG=Helmholtz(N[0], np.sqrt(K2[0] + 2.0 / nu / dt),
                                        ST),
             BiharmonicSolverU=Biharmonic(N[0],
                                          -nu * dt / 2.,
                                          1. + nu * dt * K2[0],
                                          -(K2[0] + nu * dt / 2. * K4[0]),
                                          quad=SB.quad,
                                          solver="cython"),
             HelmholtzSolverU0=Helmholtz(N[0], np.sqrt(2. / nu / dt), ST),
             TDMASolverD=TDMA(inner_product((ST, 0), (ST, 0)))))

    alfa = K2[0] - 2.0 / nu / dt
    # Collect all matrices
    mat = config.AttributeDict(
        dict(
            CDD=inner_product((ST, 0), (ST, 1)),
            AB=HelmholtzCoeff(N[0], 1.0, -alfa, ST.quad),
            AC=BiharmonicCoeff(N[0],
                               nu * dt / 2., (1. - nu * dt * K2[0]),
                               -(K2[0] - nu * dt / 2. * K4[0]),
                               quad=SB.quad),
            # Matrices for biharmonic equation
            CBD=inner_product((SB, 0), (ST, 1)),
            ABB=inner_product((SB, 0), (SB, 2)),
            BBB=inner_product((SB, 0), (SB, 0)),
            SBB=inner_product((SB, 0), (SB, 4)),
            # Matrices for Helmholtz equation
            ADD=inner_product((ST, 0), (ST, 2)),
            BDD=inner_product((ST, 0), (ST, 0)),
            BBD=inner_product((SB, 0), (ST, 0)),
            CDB=inner_product((ST, 0), (SB, 1))))

    hdf5file = KMMWriter({
        "U": U[0],
        "V": U[1],
        "W": U[2]
    },
                         chkpoint={
                             'current': {
                                 'U': U
                             },
                             'previous': {
                                 'U': U0
                             }
                         },
                         filename=params.solver + ".h5",
                         mesh={
                             "x": x0,
                             "y": x1,
                             "z": x2
                         })

    return config.AttributeDict(locals())
Beispiel #12
0
from shenfun.chebyshev.bases import ShenDirichletBasis
from shenfun.fourier.bases import FourierBasis
from shenfun import Function , TensorProductSpace
# TensorProductSpace class is used to construct W , 
# Function is a subclass of numpy.ndarray used to hold solution arrays.
from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD
N = (32, 33)

K0 = ShenDirichletBasis(N[0])
K1 = FourierBasis(N[1], dtype=np.float)
W = TensorProductSpace(comm, (K0, K1))
print(W)

# Alternatively, switch order for periodic in first direction instead
# W = TensorProductSpace(comm, (K1, K0), axes=(1, 0))

#
# w_hat = Function(W, forward_output=True) 
#	to create an array consistent with the output of W.forward (solution in spectral space)
# w = Function(W, forward_output=False) 
#	to create an array consistent with the input (solution in real space).

#
# uh = np.zeros_like(w_hat)
# w_hat = Function(W, buffer=uh) 
#  can be used to wrap a Function instance around a regular Numpy array uh. 
#  Note that uh and w_hat now will share the same data, and modifying one will 
#  naturally modify also the other.
Beispiel #13
0
from sympy import Symbol, sin, lambdify
import numpy as np
from shenfun import inner, div, grad, TestFunction, TrialFunction
from shenfun.chebyshev.bases import ShenDirichletBasis

# Use sympy to compute a rhs, given an analytical solution
x = Symbol("x")
ue = sin(np.pi * x) * (1 - x**2)
fe = ue.diff(x, 2)

# Lambdify for faster evaluation
ul = lambdify(x, ue, 'numpy')
fl = lambdify(x, fe, 'numpy')

N = 32
SD = ShenDirichletBasis(N, plan=True)
X = SD.mesh(N)
u = TrialFunction(SD)
v = TestFunction(SD)
fj = fl(X)

# Compute right hand side of Poisson equation
f_hat = inner(v, fj)  # array

# Get left hand side of Poisson equation and solve
A = inner(v, div(grad(u)))  # matrix
f_hat = A.solve(f_hat)
uj = SD.backward(f_hat)

# Compare with analytical solution
ue = ul(X)