예제 #1
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
예제 #2
0
def test_Biharmonic(quad):
    M = 128
    SB = ShenBiharmonicBasis(M, quad=quad)
    x = Symbol("x")
    u = sin(6*pi*x)**2
    a = 1.0
    b = 1.0
    f = -u.diff(x, 4) + a*u.diff(x, 2) + b*u

    ul = lambdify(x, u, 'numpy')
    fl = lambdify(x, f, 'numpy')
    points, _ = SB.points_and_weights(M)
    uj = ul(points)
    fj = fl(points)

    A = inner_product((SB, 0), (SB, 4))
    B = inner_product((SB, 0), (SB, 0))
    C = inner_product((SB, 0), (SB, 2))

    AA = -A.diags() + C.diags() + B.diags()
    f_hat = np.zeros(M)
    f_hat = SB.scalar_product(fj, f_hat)
    u_hat = np.zeros(M)
    u_hat[:-4] = la.spsolve(AA, f_hat[:-4])
    u1 = np.zeros(M)
    u1 = SB.backward(u_hat, u1)
    #from IPython import embed; embed()

    assert np.allclose(u1, uj)
def test_Mult_CTD_3D(quad):
    SD = ShenDirichlet(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 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 test_Mult_Div():

    SD = ShenDirichlet(N, "GC")
    SN = ShenNeumann(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)
예제 #6
0
파일: la.py 프로젝트: tjz2026/spectralDNS
 def __init__(self, N, alfa, basis):
     # Prepare LU Helmholtz solver for velocity
     self.N = N
     self.alfa = alfa
     self.basis = basis
     self.neumann = True if isinstance(basis, bases.ShenNeumannBasis) else False
     quad = basis.quad
     M = (N-4)//2 if self.neumann else (N-3)//2
     self.s = basis.slice()
     if hasattr(alfa, "__len__"):
         Ny, Nz = alfa.shape
         self.u0 = zeros((2, M+1, Ny, Nz), float)   # Diagonal entries of U
         self.u1 = zeros((2, M, Ny, Nz), float)     # Diagonal+1 entries of U
         self.u2 = zeros((2, M-1, Ny, Nz), float)   # Diagonal+2 entries of U
         self.L  = zeros((2, M, Ny, Nz), float)     # The single nonzero row of L
         LUsolve.LU_Helmholtz_3D(N, self.neumann, quad=="GL", self.alfa, self.u0, self.u1, self.u2, self.L)
     else:
         self.u0 = zeros((2, M+1), float)   # Diagonal entries of U
         self.u1 = zeros((2, M), float)     # Diagonal+1 entries of U
         self.u2 = zeros((2, M-1), float)   # Diagonal+2 entries of U
         self.L  = zeros((2, M), float)     # The single nonzero row of L
         LUsolve.LU_Helmholtz_1D(N, self.neumann, quad=="GL", self.alfa, self.u0, self.u1, self.u2, self.L)
     if not self.neumann:
         self.B = inner_product((basis, 0), (basis, 0))
         self.A = inner_product((basis, 0), (basis, 2))
예제 #7
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)
예제 #8
0
    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()
예제 #9
0
def test_CDDmat(quad):
    M = 128
    SD = cbases.ShenDirichletBasis(M, quad=quad)
    u = (1 - x**2) * sin(np.pi * 6 * x)
    dudx = u.diff(x, 1)
    points, weights = SD.points_and_weights(M)

    ul = lambdify(x, u, 'numpy')
    dudx_l = lambdify(x, dudx, 'numpy')
    dudx_j = dudx_l(points)
    uj = ul(points)

    u_hat = shenfun.Function(SD)
    u_hat = SD.forward(uj, u_hat)
    uj = SD.backward(u_hat, uj)
    u_hat = SD.forward(uj, u_hat)

    uc_hat = shenfun.Function(SD)
    uc_hat = SD.CT.forward(uj, uc_hat)
    dudx_j = SD.CT.fast_derivative(uj)

    Cm = inner_product((SD, 0), (SD, 1))
    B = inner_product((SD, 0), (SD, 0))
    TDMASolver = TDMA(B)

    cs = np.zeros_like(u_hat)
    cs = Cm.matvec(u_hat, cs)

    # Should equal (but not exact so use extra resolution)
    cs2 = np.zeros(M)
    cs2 = SD.scalar_product(dudx_j, cs2)
    s = SD.slice()
    assert np.allclose(cs[s], cs2[s])

    cs = TDMASolver(cs)
    du = np.zeros(M)
    du = SD.backward(cs, du)

    assert np.linalg.norm(du[s] - dudx_j[s]) / M < 1e-10

    # Multidimensional version
    u3_hat = u_hat.repeat(4 * 4).reshape(
        (M, 4, 4)) + 1j * u_hat.repeat(4 * 4).reshape((M, 4, 4))
    cs = np.zeros_like(u3_hat)
    cs = Cm.matvec(u3_hat, cs)
    cs2 = np.zeros((M, 4, 4), dtype=np.complex)
    du3 = dudx_j.repeat(4 * 4).reshape(
        (M, 4, 4)) + 1j * dudx_j.repeat(4 * 4).reshape((M, 4, 4))
    SD.plan((M, 4, 4), 0, np.complex, {})
    cs2 = SD.scalar_product(du3, cs2)

    assert np.allclose(cs[s], cs2[s], 1e-10)

    cs = TDMASolver(cs)
    d3 = np.zeros((M, 4, 4), dtype=np.complex)
    d3 = SD.backward(cs, d3)

    assert np.linalg.norm(du3[s] - d3[s]) / (M * 16) < 1e-10
예제 #10
0
 def __init__(self, N, alfa, beta, quad="GL"):
     """alfa*ADD + beta*BDD
     """
     self.quad = quad
     self.shape = (N - 2, N - 2)
     SD = bases.ShenDirichletBasis(N, quad)
     self.B = inner_product((SD, 0), (SD, 0))
     self.A = inner_product((SD, 0), (SD, 2))
     self.alfa = alfa
     self.beta = beta
예제 #11
0
 def __init__(self, N, a0, alfa, beta, quad="GL"):
     self.quad = quad
     self.shape = (N - 4, N - 4)
     SB = bases.ShenBiharmonicBasis(N, quad)
     self.S = inner_product((SB, 0), (SB, 4))
     self.B = inner_product((SB, 0), (SB, 0))
     self.A = inner_product((SB, 0), (SB, 2))
     self.a0 = a0
     self.alfa = alfa
     self.beta = beta
예제 #12
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)
예제 #13
0
 def __init__(self, K, alfa, beta, quad="GL"):
     """alfa*ADD + beta*BDD
     """
     self.quad = quad
     N = self.N = K.shape[0] - 2
     self.shape = (N, N)
     SD = bases.ShenDirichletBasis(N + 2, quad)
     self.B = inner_product((SD, 0), (SD, 0))
     self.A = inner_product((SD, 0), (SD, 2))
     self.alfa = alfa
     self.beta = beta
예제 #14
0
 def __init__(self, N, alfa, beta, axis, quad="GL"):
     """alfa*ADD + beta*BDD
     """
     self.quad = quad
     self.shape = (N-2, N-2)
     SD = bases.ShenDirichletBasis(N, quad)
     self.B = inner_product((SD, 0), (SD, 0))
     self.A = inner_product((SD, 0), (SD, 2))
     self.axis = axis
     self.alfa = np.broadcast_to(alfa, beta.shape).copy()
     self.beta = beta
예제 #15
0
 def __init__(self, N, alfa, beta, axis, quad="GL"):
     """alfa*ADD + beta*BDD
     """
     self.quad = quad
     self.shape = (N - 2, N - 2)
     SD = bases.ShenDirichletBasis(N, quad)
     self.B = inner_product((SD, 0), (SD, 0))
     self.A = inner_product((SD, 0), (SD, 2))
     self.axis = axis
     self.alfa = np.broadcast_to(alfa, beta.shape).copy()
     self.beta = beta
예제 #16
0
 def __init__(self, N, a0, alfa, beta, axis, quad="GL"):
     self.quad = quad
     self.shape = (N-4, N-4)
     SB = bases.ShenBiharmonicBasis(N, quad)
     self.S = inner_product((SB, 0), (SB, 4))
     self.B = inner_product((SB, 0), (SB, 0))
     self.A = inner_product((SB, 0), (SB, 2))
     self.axis = axis
     self.a0 = a0
     self.alfa = alfa
     self.beta = beta
예제 #17
0
def test_massmatrices(test, trial, quad):
    test = test(N, quad=quad)
    trial = trial(N, quad=quad)

    f_hat = np.zeros(N)
    fj = np.random.random(N)
    f_hat = trial.forward(fj, f_hat)
    fj = trial.backward(f_hat, fj)

    BBD = inner_product((test, 0), (trial, 0))

    f_hat = trial.forward(fj, f_hat)
    u2 = np.zeros_like(f_hat)
    u2 = BBD.matvec(f_hat, u2)
    u0 = np.zeros(N)
    u0 = test.scalar_product(fj, u0)
    s = test.slice()
    assert np.allclose(u0[s], u2[s], rtol=1e-5, atol=1e-6)

    # Multidimensional version
    fj = fj.repeat(N * N).reshape((N, N, N)) + 1j * fj.repeat(N * N).reshape(
        (N, N, N))
    f_hat = f_hat.repeat(N * N).reshape(
        (N, N, N)) + 1j * f_hat.repeat(N * N).reshape((N, N, N))

    test.plan((N, ) * 3, 0, np.complex, {})
    test.tensorproductspace = ABC(3, test.coors)
    u0 = np.zeros((N, ) * 3, dtype=np.complex)

    u0 = test.scalar_product(fj, u0)
    u2 = np.zeros_like(f_hat)
    u2 = BBD.matvec(f_hat, u2)
    assert np.linalg.norm(u2[s] - u0[s]) / (N * N * N) < 1e-8
    del BBD
예제 #18
0
def test_axis(ST, quad, axis):
    kwargs = {}
    if not ST.family() == 'fourier':
        kwargs['quad'] = quad
    ST = ST(N, **kwargs)
    points, weights = ST.points_and_weights(N)
    f_hat = shenfun.Function(ST)
    f_hat[:] = np.random.random(f_hat.shape[0])

    B = inner_product((ST, 0), (ST, 0))
    c = shenfun.Function(ST)
    c = B.solve(f_hat, c)

    # Multidimensional version
    f0 = shenfun.Array(ST)
    bc = [np.newaxis,]*3
    bc[axis] = slice(None)
    ST.tensorproductspace = ABC(3, ST.coors)
    ST.plan((N,)*3, axis, f0.dtype, {})
    if ST.has_nonhomogeneous_bcs:
        ST.bc.set_tensor_bcs(ST, ST) # To set Dirichlet boundary conditions on multidimensional array
    ck = shenfun.Function(ST)
    fk = np.broadcast_to(f_hat[tuple(bc)], ck.shape).copy()
    ck = B.solve(fk, ck, axis=axis)
    cc = [1,]*3
    cc[axis] = slice(None)
    assert np.allclose(ck[tuple(cc)], c, rtol=1e-5, atol=1e-6)
예제 #19
0
def test_jmatvec(b0, b1, quad, format, dim, k0, k1):
    """Testq matrix-vector product"""
    global c, c1
    b0 = b0(N, quad=quad)
    b1 = b1(N, quad=quad)
    mat = inner_product((b0, k0), (b1, k1))
    c = mat.matvec(a, c, format='csr')
    c1 = mat.matvec(a, c1, format=format)
    assert np.allclose(c, c1)
    for axis in range(0, dim):
        b, d, d1 = work[dim]
        d.fill(0)
        d1.fill(0)
        d = mat.matvec(b, d, format='csr', axis=axis)
        d1 = mat.matvec(b, d1, format=format, axis=axis)
        assert np.allclose(d, d1)

        # Test multidimensional with axis equals 1D case
        d1.fill(0)
        bc = [
            np.newaxis,
        ] * dim
        bc[axis] = slice(None)
        fj = np.broadcast_to(a[tuple(bc)], (N, ) * dim).copy()
        d1 = mat.matvec(fj, d1, format=format, axis=axis)
        cc = [
            0,
        ] * dim
        cc[axis] = slice(None)
        assert np.allclose(c, d1[tuple(cc)])
예제 #20
0
def test_massmatrices(test, trial, quad):
    test = test(N, quad=quad, plan=True)
    trial = trial(N, quad=quad, plan=True)

    f_hat = np.zeros(N)
    fj = np.random.random(N)
    f_hat = trial.forward(fj, f_hat)
    fj = trial.backward(f_hat, fj)

    BBD = inner_product((test, 0), (trial, 0))

    f_hat = trial.forward(fj, f_hat)
    u2 = np.zeros_like(f_hat)
    u2 = BBD.matvec(f_hat, u2)
    u0 = np.zeros(N)
    u0 = test.scalar_product(fj, u0)
    s = test.slice()
    #from IPython import embed; embed()
    assert np.allclose(u0[s], u2[s])

    # Multidimensional version
    fj = fj.repeat(N * N).reshape((N, N, N)) + 1j * fj.repeat(N * N).reshape(
        (N, N, N))
    f_hat = f_hat.repeat(N * N).reshape(
        (N, N, N)) + 1j * f_hat.repeat(N * N).reshape((N, N, N))

    test.plan((N, ) * 3, 0, np.complex, {})
    u0 = np.zeros((N, ) * 3, dtype=np.complex)
    u0 = test.scalar_product(fj, u0)
    u2 = np.zeros_like(f_hat)
    u2 = BBD.matvec(f_hat, u2)
    assert np.linalg.norm(u2[s] - u0[s]) / (N * N * N) < 1e-12
    del BBD
예제 #21
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
예제 #22
0
def test_axis(ST, quad, axis):
    kwargs = {'plan': True}
    if not ST.family() == 'fourier':
        kwargs['quad'] = quad
    ST = ST(N, **kwargs)
    points, weights = ST.points_and_weights(N)
    f_hat = shenfun.Function(ST)
    f_hat[:] = np.random.random(f_hat.shape[0])

    B = inner_product((ST, 0), (ST, 0))
    c = shenfun.Function(ST)
    c = B.solve(f_hat, c)

    # Multidimensional version
    f0 = shenfun.Array(ST)
    bc = [
        np.newaxis,
    ] * 3
    bc[axis] = slice(None)
    ST.plan((N, ) * 3, axis, f0.dtype, {})
    if hasattr(ST, 'bc'):
        ST.bc.set_tensor_bcs(
            ST
        )  # To set Dirichlet boundary conditions on multidimensional array
    ck = shenfun.Function(ST)
    fk = np.broadcast_to(f_hat[bc], ck.shape).copy()
    ck = B.solve(fk, ck, axis=axis)
    cc = [
        0,
    ] * 3
    cc[axis] = slice(None)
    assert np.allclose(ck[cc], c)
예제 #23
0
def test_ASDSDmat(ST, quad):
    M = 2*N
    ST = ST(M, quad=quad)
    u = (1-x**2)*sin(np.pi*x)
    f = u.diff(x, 2)
    ul = lambdify(x, u, 'numpy')
    fl = lambdify(x, f, 'numpy')
    points, weights = ST.points_and_weights(M)
    uj = ul(points)
    fj = fl(points)
    s = ST.slice()

    if ST.family() == 'chebyshev':
        A = inner_product((ST, 0), (ST, 2))
    else:
        A = inner_product((ST, 1), (ST, 1))

    f_hat = np.zeros(M)
    f_hat = ST.scalar_product(fj, f_hat)
    if ST.family() == 'legendre':
        f_hat *= -1

    # Test both solve interfaces
    c_hat = f_hat.copy()
    c_hat = A.solve(c_hat)

    u_hat = np.zeros_like(f_hat)
    u_hat = A.solve(f_hat, u_hat)

    assert np.allclose(c_hat[s], u_hat[s], rtol=1e-5, atol=1e-6)

    u0 = np.zeros(M)
    u0 = ST.backward(u_hat, u0)
    assert np.allclose(u0, uj)

    u1 = np.zeros(M)
    u1 = ST.forward(uj, u1)
    c = np.zeros_like(u1)
    c = A.matvec(u1, c)
    s = ST.slice()
    assert np.allclose(c[s], f_hat[s], rtol=1e-5, atol=1e-6)

    # Multidimensional
    c_hat = f_hat.copy()
    c_hat = c_hat.repeat(M).reshape((M, M)).transpose().copy()
    c_hat = A.solve(c_hat, axis=1)
    assert np.allclose(c_hat[0, s], u_hat[s], rtol=1e-5, atol=1e-6)
예제 #24
0
def get_pressure(context, solver):
    c = context
    dt = solver.params.dt
    FST = c.FST

    U = solver.get_velocity(**c)
    c.U0[0] = FST.backward(c.U_hat0[0], c.U0[0], c.SB)
    for i in range(1, 3):
        c.U0[i] = FST.backward(c.U_hat0[i], c.U0[i], c.ST)

    H_hat = solver.get_convection(**c)
    Hx = zeros(FST.real_shape(), dtype=float)
    Hx = FST.backward(H_hat[0], Hx, c.ST)
    Hx -= 1. / dt * (c.U[0] - c.U0[0])

    rhs_hat = zeros(FST.complex_shape(), dtype=complex)
    w0 = zeros(FST.complex_shape(), dtype=complex)

    ATB = inner_product((c.CT, 0), (c.SB, 2))
    BTB = inner_product((c.CT, 0), (c.SB, 0))
    rhs_hat = ATB.matvec(c.U_hat[0] + c.U_hat0[0], rhs_hat)
    rhs_hat -= c.K2 * BTB.matvec(c.U_hat[0] + c.U_hat0[0], w0)
    rhs_hat *= 0.5 * context.nu

    rhs_hat += FST.scalar_product(Hx, w0, c.CT)

    CT = inner_product((c.CT, 0), (c.CT, 1))

    # Should implement fast solver. Just a backwards substitution
    A = CT.diags().toarray()
    A[-1, 0] = 1
    a_i = np.linalg.inv(A)

    p_hat = zeros(FST.complex_shape(), dtype=complex)

    for j in range(p_hat.shape[1]):
        for k in range(p_hat.shape[2]):
            p_hat[:, j, k] = np.dot(a_i, rhs_hat[:, j, k])

    p = zeros(FST.real_shape(), dtype=float)
    p = FST.backward(p_hat, p, c.CT)

    uu = np.sum((0.5 * (c.U + c.U0))**2, 0)
    uu *= 0.5

    return p - uu + 3. / 16.
예제 #25
0
    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
예제 #26
0
def test_SBBmat(SB, quad):
    M = 72
    SB = SB(M, quad=quad)
    u = sin(4 * pi * x)**2
    f = u.diff(x, 4)
    ul = lambdify(x, u, 'numpy')
    fl = lambdify(x, f, 'numpy')
    points, weights = SB.points_and_weights(M)
    uj = ul(points)
    fj = fl(points)

    if isinstance(SB, shenfun.chebyshev.bases.ChebyshevBase):
        A = inner_product((SB, 0), (SB, 4))
    else:
        A = inner_product((SB, 2), (SB, 2))
    f_hat = np.zeros(M)
    f_hat = SB.scalar_product(fj, f_hat)
    u_hat = np.zeros(M)
    u_hat = A.solve(f_hat, u_hat)

    u0 = np.zeros(M)
    u0 = SB.backward(u_hat, u0)

    assert np.allclose(u0, uj, rtol=1e-5, atol=1e-6)

    u1 = np.zeros(M)
    u1 = SB.forward(uj, u1)

    c = np.zeros_like(u1)
    c = A.matvec(u1, c)

    assert np.all(abs(c - f_hat) / c.max() < 1e-10)

    # Multidimensional
    c2 = (c.repeat(16).reshape((M, 4, 4)) + 1j * c.repeat(16).reshape(
        (M, 4, 4)))
    u1 = (u1.repeat(16).reshape((M, 4, 4)) + 1j * u1.repeat(16).reshape(
        (M, 4, 4)))

    c = np.zeros_like(u1)
    c = A.matvec(u1, c)

    assert np.allclose(c, c2)
예제 #27
0
    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
예제 #28
0
    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
예제 #29
0
def test_Mult_CTD_3D(quad):
    SD = FunctionSpace(N, 'C', bc=(0, 0))
    F0 = FunctionSpace(4, 'F', dtype='D')
    F1 = FunctionSpace(4, 'F', dtype='d')
    T = TensorProductSpace(comm, (SD, F0, F1))

    TO = T.get_orthogonal()
    CT = TO.bases[0]

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

    vk = Array(T)
    wk = Array(T)
    vk[:] = np.random.random(vk.shape)
    wk[:] = np.random.random(vk.shape)

    bv = Function(T)
    bw = Function(T)

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

    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)
예제 #30
0
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
예제 #31
0
def test_jmatvec(b0, b1, quad, format, k0, k1):
    """Testq matrix-vector product"""
    global c, c1
    b0 = b0(N, quad=quad)
    b1 = b1(N, quad=quad)
    mat = inner_product((b0, k0), (b1, k1))
    c = mat.matvec(a, c, format='csr')
    formats = mat._matvec_methods + ['python', 'csr']
    for format in formats:
        c1 = mat.matvec(a, c1, format=format)
        assert np.allclose(c, c1)
    dim = 2
    b, d, d1 = work[dim]
    for axis in range(0, dim):
        d = mat.matvec(b, d, format='csr', axis=axis)
        for format in formats:
            d1 = mat.matvec(b, d1, format=format, axis=axis)
            assert np.allclose(d, d1)
예제 #32
0
def test_cmatvec(b0, b1, quad, k):
    """Test matrix-vector product"""
    global c, c1
    if quad == 'GL' and (b0 in cBasisGC or b1 in cBasisGC):
        return
    b0 = b0(N, quad=quad)
    b1 = b1(N, quad=quad)
    mat = inner_product((b0, 0), (b1, k))
    formats = mat._matvec_methods + ['python', 'csr']
    c = mat.matvec(a, c, format='csr')
    for format in formats:
        c1 = mat.matvec(a, c1, format=format)
        assert np.allclose(c, c1)
    for dim in (2, 3):
        b, d, d1 = work[dim]
        for axis in range(0, dim):
            d = mat.matvec(b, d, format='csr', axis=axis)
            for format in formats:
                d1 = mat.matvec(b, d1, format=format, axis=axis)
                assert np.allclose(d, d1)
예제 #33
0
def test_massmatrices(test, trial, quad):
    test = test(N, quad=quad)
    trial = trial(N, quad=quad)

    f_hat = np.zeros(N)
    fj = np.random.random(N)

    f_hat = trial.forward(fj, f_hat)

    fj = trial.backward(f_hat, fj)

    BBD = inner_product((test, 0), (trial, 0))
    f_hat = trial.forward(fj, f_hat)
    u2 = np.zeros_like(f_hat)
    u2 = BBD.matvec(f_hat, u2)
    u0 = np.zeros(N)
    u0 = test.scalar_product(fj, u0)
    s = test.slice()
    assert np.allclose(u0[s], u2[s], rtol=1e-5, atol=1e-6)

    del BBD
예제 #34
0
def test_CXXmat(test, trial):
    test = test(N)
    trial = trial(N)

    CT = cBasis[0](N)

    Cm = inner_product((test, 0), (trial, 1))
    S2 = Cm.trialfunction[0]
    S1 = Cm.testfunction[0]

    fj = np.random.randn(N)
    # project to S2
    f_hat = np.zeros(N)
    f_hat = S2.forward(fj, f_hat)
    fj = S2.backward(f_hat, fj)

    # Check S1.scalar_product(f) equals Cm*S2.forward(f)
    f_hat = S2.forward(fj, f_hat)
    cs = np.zeros_like(f_hat)
    cs = Cm.matvec(f_hat, cs)
    df = CT.fast_derivative(fj)
    cs2 = np.zeros(N)
    cs2 = S1.scalar_product(df, cs2)
    s = S1.slice()
    assert np.allclose(cs[s], cs2[s])

    # Multidimensional version
    f_hat = f_hat.repeat(4 * 4).reshape(
        (N, 4, 4)) + 1j * f_hat.repeat(4 * 4).reshape((N, 4, 4))
    df = df.repeat(4 * 4).reshape((N, 4, 4)) + 1j * df.repeat(4 * 4).reshape(
        (N, 4, 4))
    cs = np.zeros_like(f_hat)
    cs = Cm.matvec(f_hat, cs)
    cs2 = np.zeros((N, 4, 4), dtype=np.complex)
    S1.tensorproductspace = ABC(3)
    S1.plan((N, 4, 4), 0, np.complex, {})
    cs2 = S1.scalar_product(df, cs2)

    assert np.allclose(cs[s], cs2[s])
예제 #35
0
def test_CXXmat(test, trial):
    test = test(N)
    trial = trial(N)

    CT = cBasis[0](N)

    Cm = inner_product((test, 0), (trial, 1))
    S2 = Cm.trialfunction[0]
    S1 = Cm.testfunction[0]

    fj = shenfun.Array(S2, buffer=np.random.randn(N))
    # project to S2
    f_hat = fj.forward()
    fj = f_hat.backward(fj)

    # Check S1.scalar_product(f) equals Cm*S2.forward(f)
    f_hat = S2.forward(fj, f_hat)
    cs = np.zeros_like(f_hat)
    cs = Cm.matvec(f_hat, cs)
    df = shenfun.project(shenfun.grad(f_hat), CT).backward()
    cs2 = np.zeros(N)
    cs2 = S1.scalar_product(df, cs2)
    s = S1.slice()
    assert np.allclose(cs[s], cs2[s], rtol=1e-5, atol=1e-6)

    # Multidimensional version
    f_hat = f_hat.repeat(4 * 4).reshape(
        (N, 4, 4)) + 1j * f_hat.repeat(4 * 4).reshape((N, 4, 4))
    df = df.repeat(4 * 4).reshape((N, 4, 4)) + 1j * df.repeat(4 * 4).reshape(
        (N, 4, 4))
    cs = np.zeros_like(f_hat)
    cs = Cm.matvec(f_hat, cs)
    cs2 = np.zeros((N, 4, 4), dtype=np.complex)
    S1.tensorproductspace = ABC(3, S1.coors)
    S1.plan((N, 4, 4), 0, np.complex, {})
    cs2 = S1.scalar_product(df, cs2)

    assert np.allclose(cs[s], cs2[s], rtol=1e-5, atol=1e-6)
예제 #36
0
def get_context():
    """Set up context for solver"""

    # Get points and weights for Chebyshev weighted integrals
    assert params.Dquad == params.Bquad
    collapse_fourier = False if params.dealias == '3/2-rule' else True
    ST = Basis(params.N[2], 'C', bc=(0, 0), quad=params.Dquad)
    SB = Basis(params.N[2], 'C', bc='Biharmonic', quad=params.Bquad)
    CT = Basis(params.N[2], 'C', quad=params.Dquad)
    ST0 = Basis(params.N[2], 'C', bc=(0, 0), quad=params.Dquad) # For 1D problem
    K0 = Basis(params.N[0], 'F', domain=(0, params.L[0]), dtype='D')
    K1 = Basis(params.N[1], 'F', domain=(0, params.L[1]), dtype='d')

    kw0 = {'threads':params.threads,
           'planner_effort':params.planner_effort["dct"],
           'slab': (params.decomposition == 'slab'),
           'collapse_fourier': collapse_fourier}
    FST = TensorProductSpace(comm, (K0, K1, ST), axes=(2, 0, 1), **kw0)    # Dirichlet
    FSB = TensorProductSpace(comm, (K0, K1, SB), axes=(2, 0, 1), **kw0)    # Biharmonic
    FCT = TensorProductSpace(comm, (K0, K1, CT), axes=(2, 0, 1), **kw0)    # Regular Chebyshev
    VFS = MixedTensorProductSpace([FST, FST, FSB])
    VFST = MixedTensorProductSpace([FST, FST, FST])
    VUG = MixedTensorProductSpace([FST, FSB])

    # Padded
    kw = {'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
          'dealias_direct': params.dealias == '2/3-rule'}
    if params.dealias == '3/2-rule':
        # Requires new bases due to planning and transforms on different size arrays
        STp = Basis(params.N[2], 'C', bc=(0, 0), quad=params.Dquad)
        SBp = Basis(params.N[2], 'C', bc='Biharmonic', quad=params.Bquad)
        CTp = Basis(params.N[2], 'C', quad=params.Dquad)
    else:
        STp, SBp, CTp = ST, SB, CT
    K0p = Basis(params.N[0], 'F', dtype='D', domain=(0, params.L[0]), **kw)
    K1p = Basis(params.N[1], 'F', dtype='d', domain=(0, params.L[1]), **kw)
    FSTp = TensorProductSpace(comm, (K0p, K1p, STp), axes=(2, 0, 1), **kw0)
    FSBp = TensorProductSpace(comm, (K0p, K1p, SBp), axes=(2, 0, 1), **kw0)
    FCTp = TensorProductSpace(comm, (K0p, K1p, CTp), axes=(2, 0, 1), **kw0)
    VFSp = MixedTensorProductSpace([FSTp, FSTp, FSBp])

    Nu = params.N[2]-2   # Number of velocity modes in Shen basis
    Nb = params.N[2]-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)
    U0 = Array(VFS)
    U_hat = Function(VFS)
    U_hat0 = Function(VFS)
    g = Function(FST)

    # primary variable
    u = (U_hat, g)

    H_hat = Function(VFST)
    H_hat0 = Function(VFST)
    H_hat1 = Function(VFST)

    dU = Function(VUG)
    hv = Function(FST)
    hg = Function(FST)
    Source = Array(VFS)
    Sk = Function(VFS)

    K2 = K[0]*K[0]+K[1]*K[1]
    K4 = K2**2

    # Set Nyquist frequency to zero on K that is used for odd derivatives in nonlinear terms
    Kx = FST.local_wavenumbers(scaled=True, eliminate_highest_freq=True)
    K_over_K2 = np.zeros((2,)+g.shape)
    for i in range(2):
        K_over_K2[i] = K[i] / np.where(K2 == 0, 1, K2)

    work = work_arrays()
    u_dealias = Array(VFSp)
    u0_hat = np.zeros((2, params.N[2]), dtype=complex)
    h0_hat = np.zeros((2, params.N[2]), dtype=complex)
    w = np.zeros((params.N[2], ), dtype=complex)
    w1 = np.zeros((params.N[2], ), dtype=complex)

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

    # Collect all matrices
    mat = config.AttributeDict(
        dict(CDD=inner_product((ST, 0), (ST, 1)),
             CTD=inner_product((CT, 0), (ST, 1)),
             BTT=inner_product((CT, 0), (CT, 0)),
             AB=HelmholtzCoeff(N[2], 1.0, -(K2 - 2.0/nu/dt), 2, ST.quad),
             AC=BiharmonicCoeff(N[2], nu*dt/2., (1. - nu*dt*K2), -(K2 - nu*dt/2.*K4), 2, 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))))

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

    hdf5file = KMMFile(config.params.solver,
                       checkpoint={'space': VFS,
                                   'data': {'0': {'U': [U_hat]},
                                            '1': {'U': [U_hat0]}}},
                       results={'space': VFS,
                                'data': {'U': [U]}})

    return config.AttributeDict(locals())