Example #1
0
def test_curl(typecode):
    K0 = FunctionSpace(N[0], 'F', dtype=typecode.upper())
    K1 = FunctionSpace(N[1], 'F', dtype=typecode.upper())
    K2 = FunctionSpace(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 = shenfun.TrialFunction(Tk)
    v = shenfun.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)
    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)
Example #2
0
def test_solve(quad):
    SD = Basis(N, 'C', bc=(0, 0), quad=quad, plan=True)
    u = TrialFunction(SD)
    v = TestFunction(SD)
    A = inner(div(grad(u)), v)
    b = np.ones(N)
    u_hat = Function(SD)
    u_hat = A.solve(b, u=u_hat)

    w_hat = Function(SD)
    B = SparseMatrix(dict(A), (N - 2, N - 2))
    w_hat[:-2] = B.solve(b[:-2], w_hat[:-2])
    assert np.all(abs(w_hat[:-2] - u_hat[:-2]) < 1e-8)

    ww = w_hat[:-2].repeat(N - 2).reshape((N - 2, N - 2))
    bb = b[:-2].repeat(N - 2).reshape((N - 2, N - 2))
    ww = B.solve(bb, ww, axis=0)
    assert np.all(
        abs(ww - u_hat[:-2].repeat(N - 2).reshape((N - 2, N - 2))) < 1e-8)

    bb = bb.transpose()
    ww = B.solve(bb, ww, axis=1)
    assert np.all(
        abs(ww - u_hat[:-2].repeat(N - 2).reshape(
            (N - 2, N - 2)).transpose()) < 1e-8)
Example #3
0
    def _setup_variational_problem(self):
        self._setup_function_space()
        u = sf.TrialFunction(self._V)
        v = sf.TestFunction(self._V)

        self._elastic_law.set_material_parameters(self._material_parameters)
        self._dw_int = self._elastic_law.dw_int(u, v)

        self._dw_ext = inner(
            v, sf.Array(self._V.get_orthogonal(), buffer=(0, ) * self._dim))

        if self._body_forces is not None:
            V_body_forces = self._V.get_orthogonal()
            body_forces_quad = sf.Array(V_body_forces,
                                        buffer=self._body_forces)
            self._dw_ext = inner(v, body_forces_quad)
Example #4
0
def test_project_1D(basis):
    ue = sin(2*np.pi*x)*(1-x**2)
    T = basis(12)
    u = shenfun.TrialFunction(T)
    v = shenfun.TestFunction(T)
    u_tilde = shenfun.Function(T)
    X = T.mesh()
    ua = shenfun.Array(T, buffer=ue)
    u_tilde = shenfun.inner(v, ua, output_array=u_tilde)
    M = shenfun.inner(u, v)
    u_p = shenfun.Function(T)
    u_p = M.solve(u_tilde, u=u_p)
    u_0 = shenfun.Function(T)
    u_0 = shenfun.project(ua, T)
    assert np.allclose(u_0, u_p)
    u_1 = shenfun.project(ue, T)
    assert np.allclose(u_1, u_p)
Example #5
0
def ComputeRHS(rhs, u_hat, rk, solver, H_hat, VFSp, FSTp, FCTp, VCp, work, K,
               K2, u_dealias, curl_dealias, curl_hat, mat, la, vt, Sk, hv, a,
               b, mask, **context):
    """Compute right hand side of Navier Stokes

    Parameters
    ----------
        rhs : array
            The right hand side to be returned
        u_hat : array
            The velocity vector at current time
        solver : module
            The current solver module

    Remaining args are extracted from context

    """
    w0 = work[(u_hat[0], 0, False)]

    # Nonlinear convection term at current u_hat
    H_hat = solver.conv(H_hat, u_hat, K, VFSp, VCp, FSTp, FCTp, work,
                        u_dealias, curl_dealias, curl_hat, mat, la)

    if mask is not None:
        H_hat.mask_nyquist(mask)

    # Assemble rhs
    rhs[:] = 0
    rhs_u, rhs_p = rhs
    if context['ST'].family() == 'chebyshev':
        rhs_u[0] = mat.AB[rk].matvec(u_hat[0], rhs_u[0])
        rhs_u[1] = mat.AB[rk].matvec(u_hat[1], rhs_u[1])
        rhs_u[2] = mat.AB[rk].matvec(u_hat[2], rhs_u[2])
    else:
        #rhs_u[:] = inner(vt, (2./params.nu/params.dt/(a[rk]+b[rk]))*u_hat)
        #rhs_u += inner(vt, div(grad(u_hat)))
        rhs_u[0] = -(K2 - 2. / params.nu / params.dt /
                     (a[rk] + b[rk])) * mat.BDD.matvec(u_hat[0], w0)
        rhs_u[1] = -(K2 - 2. / params.nu / params.dt /
                     (a[rk] + b[rk])) * mat.BDD.matvec(u_hat[1], w0)
        rhs_u[2] = -(K2 - 2. / params.nu / params.dt /
                     (a[rk] + b[rk])) * mat.BDD.matvec(u_hat[2], w0)
        rhs_u[0] += mat.ADD.matvec(u_hat[0], w0)
        rhs_u[1] += mat.ADD.matvec(u_hat[1], w0)
        rhs_u[2] += mat.ADD.matvec(u_hat[2], w0)

    # Convection
    hv[1] = inner(vt, H_hat)

    # Source
    hv[1, 1] -= Sk[1]

    rhs_u[:] += (hv[1] * a[rk] + hv[0] * b[rk]) * 2. / params.nu / (a[rk] +
                                                                    b[rk])

    hv[0] = hv[1]

    return rhs
Example #6
0
def test_TwoDMA():
    N = 12
    SD = FunctionSpace(N, 'C', basis='ShenDirichlet')
    HH = FunctionSpace(N, 'C', basis='Heinrichs')
    u = TrialFunction(HH)
    v = TestFunction(SD)
    points, weights = SD.points_and_weights(N)
    fj = Array(SD, buffer=np.random.randn(N))
    f_hat = Function(SD)
    f_hat = inner(v, fj, output_array=f_hat)
    A = inner(v, div(grad(u)))
    sol = TwoDMA(A)
    u_hat = Function(HH)
    u_hat = sol(f_hat, u_hat)
    sol2 = la.Solve(A, HH)
    u_hat2 = Function(HH)
    u_hat2 = sol2(f_hat, u_hat2)
    assert np.allclose(u_hat2, u_hat)
Example #7
0
def test_PDMA(quad):
    SB = FunctionSpace(N, 'C', bc=(0, 0, 0, 0), quad=quad)
    u = TrialFunction(SB)
    v = TestFunction(SB)
    points, weights = SB.points_and_weights(N)
    fj = Array(SB, buffer=np.random.randn(N))
    f_hat = Function(SB)
    f_hat = inner(v, fj, output_array=f_hat)
    A = inner(v, div(grad(u)))
    B = inner(v, u)
    s = SB.slice()
    H = A + B
    P = PDMA(A, B, A.scale, B.scale, solver='cython')
    u_hat = Function(SB)
    u_hat[s] = solve(H.diags().toarray()[s, s], f_hat[s])
    u_hat2 = Function(SB)
    u_hat2 = P(u_hat2, f_hat)
    assert np.allclose(u_hat2, u_hat)
def main(N, family, bci, bcj, plotting=False):
    global fe, ue
    BX = FunctionSpace(N, family=family, bc=bcx[bci], domain=xdomain)
    BY = FunctionSpace(N, family=family, bc=bcy[bcj], domain=ydomain)
    T = TensorProductSpace(comm, (BX, BY))
    u = TrialFunction(T)
    v = TestFunction(T)

    # Get f on quad points
    fj = Array(T, buffer=fe)

    # Compare with analytical solution
    ua = Array(T, buffer=ue)

    if T.use_fixed_gauge:
        mean = dx(ua, weighted=True) / inner(1, Array(T, val=1))

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

    # Get left hand side of Poisson equation
    A = inner(v, -div(grad(u)))

    u_hat = Function(T)

    sol = la.Solver2D(A, fixed_gauge=mean if T.use_fixed_gauge else None)
    u_hat = sol(f_hat, u_hat)
    uj = u_hat.backward()

    assert np.allclose(uj, ua), np.linalg.norm(uj - ua)
    print("Error=%2.16e" % (np.sqrt(dx((uj - ua)**2))))

    if 'pytest' not in os.environ and plotting is True:
        import matplotlib.pyplot as plt
        X, Y = T.local_mesh(True)
        plt.contourf(X, Y, uj, 100)
        plt.colorbar()
        plt.figure()
        plt.contourf(X, Y, ua, 100)
        plt.colorbar()
        plt.figure()
        plt.contourf(X, Y, ua - uj, 100)
        plt.colorbar()
Example #9
0
def test_biharmonic3D(family, axis):
    la = lla
    if family == 'chebyshev':
        la = cla
    N = (16, 16, 16)
    SD = shenfun.Basis(N[allaxes3D[axis][0]], family=family, bc='Biharmonic')
    K1 = shenfun.Basis(N[allaxes3D[axis][1]], family='F', dtype='D')
    K2 = shenfun.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 = shenfun.TensorProductSpace(subcomms, bases, axes=allaxes3D[axis])
    u = shenfun.TrialFunction(T)
    v = shenfun.TestFunction(T)
    if family == 'chebyshev':
        mat = shenfun.inner(
            v, shenfun.div(shenfun.grad(shenfun.div(shenfun.grad(u)))))
    else:
        mat = shenfun.inner(shenfun.div(shenfun.grad(v)),
                            shenfun.div(shenfun.grad(u)))

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

    g0 = shenfun.Function(T)
    g1 = shenfun.Function(T)
    g2 = shenfun.Function(T)
    M = {d.get_key(): d for d in mat}
    amat = 'ABBmat' if family == 'chebyshev' else 'PBBmat'
    g0 = M['SBBmat'].matvec(u, g0)
    g1 = M[amat].matvec(u, g1)
    g2 = M['BBBmat'].matvec(u, g2)

    assert np.linalg.norm(f - (g0 + g1 + g2)) < 1e-8, np.linalg.norm(f -
                                                                     (g0 + g1 +
                                                                      g2))
    def check_with_pde(self, u_hat, material_parameters, body_forces):
        assert isinstance(u_hat, sf.Function)
        assert len(material_parameters) == self._n_material_parameters
        for comp in body_forces:
            assert isinstance(comp, (sp.Expr, float, int))

        lambd, mu = material_parameters
        V = u_hat.function_space().get_orthogonal()
        # left hand side of pde
        lhs = (lambd + mu) * grad(div(u_hat)) + mu * div(grad(u_hat))

        error_array = sf.Array(V, buffer=body_forces)
        error_array += sf.project(lhs, V).backward()

        error = np.sqrt(inner((1, 1), error_array ** 2))
        # scale by magnitude of solution
        scale = np.sqrt(inner((1, 1), u_hat.backward() ** 2))

        return error / scale
Example #11
0
def test_div2(basis, quad):
    B = basis(8, quad=quad)
    u = shenfun.TrialFunction(B)
    v = shenfun.TestFunction(B)
    m = inner(u, v)
    z = Function(B, val=1)
    c = m / z
    m2 = m.diags('csr')
    c2 = spsolve(m2, z[B.slice()])
    assert np.allclose(c2, c[B.slice()])
Example #12
0
def test_helmholtz3D(family, axis):
    la = lla
    if family == 'chebyshev':
        la = cla
    N = (8, 9, 10)
    SD = FunctionSpace(N[allaxes3D[axis][0]], family=family, bc=(0, 0))
    K1 = FunctionSpace(N[allaxes3D[axis][1]], family='F', dtype='D')
    K2 = FunctionSpace(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],
                           modify_spaces_inplace=True)
    u = shenfun.TrialFunction(T)
    v = shenfun.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['ASDSDmat'].matvec(u, g0)
    g1 = M['BSDSDmat'].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
Example #13
0
def get_pressure(context, solver):
    FCT = context.FCT
    FST = context.FST

    U_hat = context.U_hat
    U_hat0 = context.U_hat0
    Um = Function(context.FST)
    Um[:] = 0.5*(U_hat[0] + U_hat0[0])
    U = U_hat.backward(context.U)
    U0 = U_hat0.backward(context.U0)
    dt = solver.params.dt

    Hx = Function(context.FST)
    Hx[:] = solver.get_convection(**context)[0]

    v = TestFunction(FCT)
    p = TrialFunction(FCT)
    rhs_hat = inner(context.nu*div(grad(Um)), v)
    Hx -= 1./dt*(U_hat[0]-U_hat0[0])
    rhs_hat += inner(Hx, v)

    CT = inner(Dx(p, 0, 1), v)

    # Should implement fast solver. Just a backwards substitution
    # Apply integral constraint
    A = CT.mats[0]
    N = A.shape[0]
    A[-(N-1)] = 1

    p_hat = Function(context.FCT)
    p_hat = CT.solve(rhs_hat, p_hat)

    p = Array(FCT)
    p = FCT.backward(p_hat, p)

    uu = 0.
    if params.convection == 'Vortex':
        uu = np.sum((0.5*(U+U0))**2, 0)
        uu *= 0.5


    return p-uu
Example #14
0
def get_pressure(context, solver):
    FCT = context.FCT
    FST = context.FST

    U = solver.get_velocity(**context)
    U0 = context.VFS.backward(context.U_hat0, context.U0)
    dt = solver.params.dt

    H_hat = solver.get_convection(**context)
    Hx = Array(FST)
    Hx = FST.backward(H_hat[0], Hx)

    v = TestFunction(FCT)
    p = TrialFunction(FCT)
    U = U.as_function()
    U0 = U0.as_function()

    rhs_hat = inner((0.5*context.nu)*div(grad(U[0]+U0[0])), v)
    Hx -= 1./dt*(U[0]-U0[0])
    rhs_hat += inner(Hx, v)

    CT = inner(Dx(p, 0), v)

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

    p_hat = Function(context.FCT)

    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 = Array(FCT)
    p = FCT.backward(p_hat, p)

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

    return p-uu+3./16.
def main(N, family, bci):
    bc = bcs[bci]
    if bci == 0:
        SD = FunctionSpace(N,
                           family=family,
                           bc=bc,
                           domain=domain,
                           mean=mean[family.lower()])
    else:
        SD = FunctionSpace(N, family=family, bc=bc, domain=domain)

    u = TrialFunction(SD)
    v = TestFunction(SD)

    # Get f on quad points
    fj = Array(SD, buffer=fe)

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

    # Get left hand side of Poisson equation
    A = inner(v, div(grad(u)))

    u_hat = Function(SD).set_boundary_dofs()
    if isinstance(A, list):
        bc_mat = extract_bc_matrices([A])
        A = A[0]
        f_hat -= bc_mat[0].matvec(u_hat, Function(SD))

    u_hat = A.solve(f_hat, u_hat)
    uj = u_hat.backward()
    uh = uj.forward()

    # Compare with analytical solution
    ua = Array(SD, buffer=ue)
    assert np.allclose(uj, ua), np.linalg.norm(uj - ua)
    if 'pytest' not in os.environ:
        print("Error=%2.16e" % (np.sqrt(dx((uj - ua)**2))))
        import matplotlib.pyplot as plt
        plt.plot(SD.mesh(), uj, 'b', SD.mesh(), ua, 'r')
Example #16
0
def get_pressure(context, solver):
    FCT = context.FCT
    FST = context.FST

    U = solver.get_velocity(**context)
    U0 = context.VFS.backward(context.U_hat0, context.U0)
    dt = solver.params.dt

    H_hat = solver.get_convection(**context)
    Hx = Array(FST)
    Hx = FST.backward(H_hat[0], Hx)

    v = TestFunction(FCT)
    p = TrialFunction(FCT)
    U = U.as_function()
    U0 = U0.as_function()

    rhs_hat = inner((0.5 * context.nu) * div(grad(U[0] + U0[0])), v)
    Hx -= 1. / dt * (U[0] - U0[0])
    rhs_hat += inner(Hx, v)

    CT = inner(Dx(p, 0), v)

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

    p_hat = Function(context.FCT)

    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 = Array(FCT)
    p = FCT.backward(p_hat, p)

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

    return p - uu + 3. / 16.
Example #17
0
def compute_numerical_error(u_ana, u_hat):
    assert isinstance(u_hat, sf.Function)

    V = u_hat.function_space()
    # evaluate u_ana at quadrature points
    error_array = sf.Array(V, buffer=u_ana)
    # subtract numerical solution
    error_array -= u_hat.backward()
    # compute integral error
    error = np.sqrt(sf.inner((1, 1), error_array**2))

    return error
Example #18
0
def test_assign(fam):
    x, y = symbols("x,y")
    for bc in (None, 'Dirichlet', 'Biharmonic'):
        dtype = 'D' if fam == 'F' else 'd'
        bc = 'periodic' if fam == 'F' else bc
        if bc == 'Biharmonic' and fam in ('La', 'H'):
            continue
        tol = 1e-12 if fam in ('C', 'L', 'F') else 1e-5
        N = (10, 12)
        B0 = Basis(N[0], fam, dtype=dtype, bc=bc)
        B1 = Basis(N[1], fam, dtype=dtype, bc=bc)
        u_hat = Function(B0)
        u_hat[1:4] = 1
        ub_hat = Function(B1)
        u_hat.assign(ub_hat)
        assert abs(inner(1, u_hat)-inner(1, ub_hat)) < tol
        T = TensorProductSpace(comm, (B0, B1))
        u_hat = Function(T)
        u_hat[1:4, 1:4] = 1
        Tp = T.get_refined((2*N[0], 2*N[1]))
        ub_hat = Function(Tp)
        u_hat.assign(ub_hat)
        assert abs(inner(1, u_hat)-inner(1, ub_hat)) < tol
        VT = VectorTensorProductSpace(T)
        u_hat = Function(VT)
        u_hat[:, 1:4, 1:4] = 1
        Tp = T.get_refined((2*N[0], 2*N[1]))
        VTp = VectorTensorProductSpace(Tp)
        ub_hat = Function(VTp)
        u_hat.assign(ub_hat)
        assert abs(inner((1, 1), u_hat)-inner((1, 1), ub_hat)) < tol
    def dw_int(self, u, v):
        assert isinstance(u, sf.TrialFunction)
        assert isinstance(v, sf.TestFunction)
        assert hasattr(self, "_material_parameters")
        assert len(self._material_parameters) == self._n_material_parameters

        self.dim = u.dimensions
        lmbda, mu, c1, c2, c3, c4, c5 = self._material_parameters
        dw_int = []

        if c1 != 0.0:
            dw_int += inner(c1 * div(grad(u)), div(grad(v)))
        if c2 != 0.0:
            dw_int += inner(c2 * div(grad(u)), grad(div(v)))
        if c3 != 0.0:
            dw_int += inner(c3 * grad(div(u)), grad(div(v)))
        if c4 != 0.0:
            for i in range(self.dim):
                for j in range(self.dim):
                    for k in range(self.dim):
                        mat = inner(c4 * Dx(Dx(u[i], j), k),
                                    Dx(Dx(v[i], j), k))
                        if isinstance(mat, list):
                            dw_int += mat
                        else:
                            dw_int += [mat]
        if c5 != 0.0:
            for i in range(self.dim):
                for j in range(self.dim):
                    for k in range(self.dim):
                        mat = inner(c5 * Dx(Dx(u[j], i), k),
                                    Dx(Dx(v[i], j), k))
                        if isinstance(mat, list):
                            dw_int += mat
                        else:
                            dw_int += [mat]

        # add the classical cauchy-terms
        dw_int += inner(mu * grad(u), grad(v))

        for i in range(self.dim):
            for j in range(self.dim):
                mat = inner(mu * Dx(u[i], j), Dx(v[j], i))
                if isinstance(mat, list):
                    dw_int += mat
                else:
                    dw_int += [mat]
        dw_int += inner(lmbda * div(u), div(v))

        return dw_int
    def dw_int(self, u, v):
        assert isinstance(u, sf.TrialFunction)
        assert isinstance(v, sf.TestFunction)
        assert hasattr(self, "_material_parameters")
        assert len(self._material_parameters) == self._n_material_parameters

        self.dim = u.dimensions
        lmbda, mu = self._material_parameters

        A = inner(mu * grad(u), grad(v))
        B = []
        for i in range(self.dim):
            for j in range(self.dim):
                mat = inner(mu * Dx(u[i], j), Dx(v[j], i))
                if isinstance(mat, list):
                    B += mat
                else:
                    B += [mat]
        C = inner(lmbda * div(u), div(v))
        dw_int = A + B + C

        return dw_int
Example #21
0
def test_quasiTau(bc):
    N = 40
    T = FunctionSpace(N, 'C')
    u = TrialFunction(T)
    v = TestFunction(T)
    A = inner(v, div(grad(u)))
    B = inner(v, u)
    Q = chebyshev.quasi.QITmat(N)
    A = Q*A
    B = Q*B
    bb = Q*np.ones(N)
    assert abs(np.sum(bb[:8])) < 1e-8
    M = B-A
    M0 = M.diags().tolil()
    if bc == 'Dirichlet':
        M0[0] = np.ones(N)
        nn = np.ones(N)
        nn[1::2] = -1
        M0[1] = nn
    elif bc == 'Neumann':
        nn = np.arange(N)**2
        M0[0] = nn.copy()
        nn[1::2] *= -1
        M0[1] = nn
    M0 = M0.tocsc()
    f_hat = inner(v, Array(T, buffer=fe))
    gh = Q.diags('csc')*f_hat
    gh[:2] = 0
    u_hat = Function(T)
    u_hat[:] = scp.linalg.spsolve(M0, gh)
    uj = u_hat.backward()
    ua = Array(T, buffer=ue)

    if bc == 'Neumann':
        xj, wj = T.points_and_weights()
        ua -= np.sum(ua*wj)/np.pi # normalize
        uj -= np.sum(uj*wj)/np.pi # normalize
    assert np.sqrt(inner(1, (uj-ua)**2)) < 1e-5
Example #22
0
def test_vector_laplace(space):
    """Test that

    div(grad(u)) = grad(div(u)) - curl(curl(u))

    """
    T = get_function_space(space)
    V = VectorSpace(T)
    u = TrialFunction(V)
    v = _TestFunction(V)
    du = div(grad(u))
    dv = grad(div(u)) - curl(curl(u))
    u_hat = Function(V)
    u_hat[:] = np.random.random(u_hat.shape) + np.random.random(u_hat.shape)*1j
    A0 = inner(v, du)
    A1 = inner(v, dv)
    a0 = BlockMatrix(A0)
    a1 = BlockMatrix(A1)
    b0 = Function(V)
    b1 = Function(V)
    b0 = a0.matvec(u_hat, b0)
    b1 = a1.matvec(u_hat, b1)
    assert np.linalg.norm(b0-b1) < 1e-8
Example #23
0
def test_inner(f0, f1):
    if f0 == 'F' and f1 == 'F':
        B0 = Basis(8, f0, dtype='D', domain=(-2*np.pi, 2*np.pi))
    else:
        B0 = Basis(8, f0)
    c = Array(B0, val=1)
    d = inner(1, c)
    assert abs(d-(B0.domain[1]-B0.domain[0])) < 1e-7

    B1 = Basis(8, f1)
    T = TensorProductSpace(comm, (B0, B1))
    a0 = Array(T, val=1)
    c0 = inner(1, a0)
    L = np.array([b.domain[1]-b.domain[0] for b in (B0, B1)])
    assert abs(c0-np.prod(L)) < 1e-7

    if not (f0 == 'F' or f1 == 'F'):
        B2 = Basis(8, f1, domain=(-2, 2))
        T = TensorProductSpace(comm, (B0, B1, B2))
        a0 = Array(T, val=1)
        c0 = inner(1, a0)
        L = np.array([b.domain[1]-b.domain[0] for b in (B0, B1, B2)])
        assert abs(c0-np.prod(L)) < 1e-7
Example #24
0
def test_helmholtz2D(family, axis):
    la = lla
    if family == 'chebyshev':
        la = cla
    N = (8, 9)
    SD = FunctionSpace(N[axis], family=family, bc=(0, 0))
    K1 = FunctionSpace(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 = shenfun.TrialFunction(T)
    v = shenfun.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
Example #25
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 = FunctionSpace(8, "L", bc=(0, 0), scaled=True)
    u = shenfun.TrialFunction(SD)
    v = shenfun.TestFunction(SD)
    mat = inner(grad(u), grad(v))
    z = Function(SD, val=1)
    c = mat * z
    assert np.allclose(c[:6], 1)
Example #26
0
def test_helmholtz3D(family, axis):
    la = lla
    if family == 'chebyshev':
        la = cla
    N = (8, 9, 10)
    SD = shenfun.Basis(N[allaxes3D[axis][0]], family=family, bc=(0, 0))
    K1 = shenfun.Basis(N[allaxes3D[axis][1]], family='F', dtype='D')
    K2 = shenfun.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 = shenfun.TensorProductSpace(subcomms, bases, axes=allaxes3D[axis])
    u = shenfun.TrialFunction(T)
    v = shenfun.TestFunction(T)
    if family == 'chebyshev':
        mat = shenfun.inner(v, shenfun.div(shenfun.grad(u)))
    else:
        mat = shenfun.inner(shenfun.grad(v), shenfun.grad(u))

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

    g0 = shenfun.Function(T)
    g1 = shenfun.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))
Example #27
0
    def solve(self):
        if self._dim == 2:
            map_boundary_to_component_index = {
                'right': 0,
                'top': 1,
                'left': 0,
                'bottom': 1
            }
            map_boundary_to_start_end_index = {
                'right': 1,
                'top': 1,
                'left': -1,
                'bottom': -1
            }
        if self._traction_bcs:
            boundary_traction_term = Function(self._V.get_orthogonal())

            # b: boundary, c: component
            for b, c, value in self._traction_bcs:
                if self._dim == 2:
                    side_index = map_boundary_to_component_index[b]
                    bdry_basis_index = 1 if side_index == 0 else 0
                    boundary_basis = self._function_spaces[c][bdry_basis_index]
                    start_or_end_index = map_boundary_to_start_end_index[b]
                    # test function for boundary integral
                    v_boundary = sf.TestFunction(boundary_basis)
                    if isinstance(value, (float, int)):
                        trac = Array(boundary_basis, val=value)
                    else:
                        trac = Array(boundary_basis, buffer=value)
                    evaluate_on_boundary = self._function_spaces[c][
                        side_index].evaluate_basis_all(start_or_end_index)
                    project_traction = inner(trac, v_boundary)
                    if side_index == 0:
                        boundary_traction_term[c] += np.outer(
                            evaluate_on_boundary, project_traction)
                    elif side_index == 1:
                        boundary_traction_term[c] += np.outer(
                            project_traction, evaluate_on_boundary)
                    else:
                        raise ValueError()

        M = sf.BlockMatrix(self._dw_int)
        if self._traction_bcs:
            self._dw_ext += boundary_traction_term
        u_hat = M.solve(self._dw_ext)

        return u_hat
Example #28
0
def ComputeRHS(rhs, u_hat, solver,
               H_hat, H_hat1, H_hat0, VFSp, FSTp, FCTp, VCp, work, K, K2,
               u_dealias, curl_dealias, curl_hat, mat, la, vt, Sk, mask, **context):
    """Compute right hand side of Navier Stokes

    Parameters
    ----------
        rhs : array
            The right hand side to be returned
        u_hat : array
            The velocity vector at current time
        solver : module
            The current solver module

    Remaining args are extracted from context

    """
    # Nonlinear convection term at current u_hat
    H_hat = solver.conv(H_hat, u_hat, K, VFSp, VCp, FSTp, FCTp, work,
                        u_dealias, curl_dealias, curl_hat, mat, la)

    # Assemble convection with Adams-Bashforth at time = n+1/2
    H_hat0 = solver.assembleAB(H_hat0, H_hat, H_hat1)

    if mask is not None:
        H_hat0.mask_nyquist(mask)

    # Assemble rhs
    rhs_u, rhs_p = rhs
    rhs_u[0] = mat.AB.matvec(u_hat[0], rhs_u[0])
    rhs_u[1] = mat.AB.matvec(u_hat[1], rhs_u[1])
    rhs_u[2] = mat.AB.matvec(u_hat[2], rhs_u[2])

    # Convection
    rhs_u[:] += 2./params.nu*inner(vt, H_hat0)

    # Source
    rhs_u[1] -= 2./params.nu*Sk[1]
    return rhs
Example #29
0
        err += " & {:2.2e}  & {:2.2e} ".format(errb/M, errs/M)
    err += " \\\ "
    print(err)

print("\hline")
for z in Z:
    err = str(z)
    for n in N:
        errh = 0
        vh = zeros(n)
        sh = zeros(n)
        alfa = sqrt(z**2+2.0/nu/dt)
        basis = chebyshev.bases.ShenDirichletBasis(n, plan=True, quad='GC')
        u = TrialFunction(basis)
        v = TestFunction(basis)
        A = inner(v, div(grad(u)))
        A.axis = 0
        B = inner(v, u)
        B.axis = 0
        HS = chebyshev.la.Helmholtz(A, B, array([1.]), array([alfa]))
        for m in range(M):
            u = random.randn(n)
            u[-2:] = 0
            vh = HS.matvec(u, vh)
            sh = HS(sh, vh)
            errh += max(abs(sh-u)) / max(abs(u))
        err += " & {:2.2e} ".format(errh/M)
    err += " \\\ "
    print(err)

Example #30
0
def get_context():
    """Set up context for solver"""

    collapse_fourier = False if params.dealias == '3/2-rule' else True
    family = 'C'
    ST = FunctionSpace(params.N[0], family, bc=(0, 0), quad=params.Dquad)
    CT = FunctionSpace(params.N[0], family, quad=params.Dquad)
    CP = FunctionSpace(params.N[0], family, quad=params.Dquad)
    K0 = FunctionSpace(params.N[1], 'F', domain=(0, params.L[1]), dtype='D')
    K1 = FunctionSpace(params.N[2], 'F', domain=(0, params.L[2]), dtype='d')
    #CP.slice = lambda: slice(0, CP.N-2)

    constraints = ((3, 0, 0), (3, params.N[0] - 1, 0))

    kw0 = {
        'threads': params.threads,
        'planner_effort': params.planner_effort["dct"],
        'slab': (params.decomposition == 'slab'),
        'collapse_fourier': collapse_fourier
    }
    FST = TensorProductSpace(comm, (ST, K0, K1), **kw0)  # Dirichlet
    FCT = TensorProductSpace(comm, (CT, K0, K1), **kw0)  # Regular Chebyshev N
    FCP = TensorProductSpace(comm, (CP, K0, K1),
                             **kw0)  # Regular Chebyshev N-2
    VFS = VectorSpace(FST)
    VCT = VectorSpace(FCT)
    VQ = CompositeSpace([VFS, FCP])

    mask = FST.get_mask_nyquist() if params.mask_nyquist else None

    # 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 = FunctionSpace(params.N[0], family, bc=(0, 0), quad=params.Dquad)
        CTp = FunctionSpace(params.N[0], family, quad=params.Dquad)
    else:
        STp, CTp = ST, CT
    K0p = FunctionSpace(params.N[1],
                        'F',
                        dtype='D',
                        domain=(0, params.L[1]),
                        **kw)
    K1p = FunctionSpace(params.N[2],
                        'F',
                        dtype='d',
                        domain=(0, params.L[2]),
                        **kw)
    FSTp = TensorProductSpace(comm, (STp, K0p, K1p), **kw0)
    FCTp = TensorProductSpace(comm, (CTp, K0p, K1p), **kw0)
    VFSp = VectorSpace(FSTp)
    VCp = CompositeSpace([FSTp, FCTp, FCTp])

    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
    UP_hat = Function(VQ)
    UP_hat0 = Function(VQ)
    U_hat, P_hat = UP_hat
    U_hat0, P_hat0 = UP_hat0

    UP = Array(VQ)
    UP0 = Array(VQ)
    U, P = UP
    U0, P0 = UP0

    # RK parameters
    a = (8. / 15., 5. / 12., 3. / 4.)
    b = (0.0, -17. / 60., -5. / 12.)

    # primary variable
    u = UP_hat

    H_hat = Function(VFS)

    dU = Function(VQ)
    hv = np.zeros((2, ) + H_hat.shape, dtype=np.complex)

    Source = Array(
        VFS)  # Note - not using VQ. Only used for constant pressure gradient
    Sk = Function(VFS)

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

    for i in range(3):
        K[i] = K[i].astype(float)

    work = work_arrays()
    u_dealias = Array(VFSp)
    curl_hat = Function(VCp)
    curl_dealias = Array(VCp)

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

    up = TrialFunction(VQ)
    vq = TestFunction(VQ)

    ut, pt = up
    vt, qt = vq

    M = []
    for rk in range(3):
        a0 = inner(vt, (2. / nu / dt / (a[rk] + b[rk])) * ut - div(grad(ut)))
        a1 = inner(vt, (2. / nu / (a[rk] + b[rk])) * grad(pt))
        a2 = inner(qt, (2. / nu / (a[rk] + b[rk])) * div(ut))
        M.append(BlockMatrix(a0 + a1 + a2))

    # Collect all matrices
    if ST.family() == 'chebyshev':
        mat = config.AttributeDict(
            dict(AB=[
                HelmholtzCoeff(N[0], 1.,
                               -(K2 - 2. / nu / dt / (a[rk] + b[rk])), 0,
                               ST.quad) for rk in range(3)
            ], ))
    else:
        mat = config.AttributeDict(
            dict(ADD=inner_product((ST, 0), (ST, 2)),
                 BDD=inner_product((ST, 0), (ST, 0))))

    la = None

    hdf5file = CoupledRK3File(config.params.solver,
                              checkpoint={
                                  'space': VQ,
                                  'data': {
                                      '0': {
                                          'UP': [UP_hat]
                                      }
                                  }
                              },
                              results={
                                  'space': VFS,
                                  'data': {
                                      'U': [U]
                                  }
                              })

    del rk
    return config.AttributeDict(locals())
Example #31
0
# Size of discretization
N = (36, 36)

S0 = Basis(N[0], family=family, bc='Biharmonic')
S1 = Basis(N[1], family=family, bc='Biharmonic')
T = TensorProductSpace(comm, (S0, S1), axes=(0, 1))
X = T.local_mesh(True)
u = TrialFunction(T)
v = TestFunction(T)

# Get f on quad points
fj = Array(T, buffer=fl(*X))

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

# Get left hand side of biharmonic equation
if family == 'chebyshev':  # No integration by parts due to weights
    matrices = inner(v, div(grad(div(grad(u)))))
else:  # Use form with integration by parts.
    matrices = inner(div(grad(v)), div(grad(u)))

# Create linear algebra solver
H = SolverGeneric2NP(matrices)

# Solve and transform to real space
u_hat = Function(T)  # Solution spectral space
u_hat = H(f_hat, u_hat)  # Solve
uq = u_hat.backward()
Example #32
0
ue = hermite(4, x) * exp(-x**2 / 2)
fe = ue.diff(x, 2)

# Size of discretization
N = int(sys.argv[-1])

SD = FunctionSpace(N, 'Hermite')
u = TrialFunction(SD)
v = TestFunction(SD)

# Get f on quad points
fj = Array(SD, buffer=fe)

# Compute right hand side of Poisson equation
f_hat = Function(SD)
f_hat = inner(v, -fj, output_array=f_hat)

# Get left hand side of Poisson equation
A = inner(grad(v), grad(u))

f_hat = A / f_hat
uj = f_hat.backward()
uh = uj.forward()

# Compare with analytical solution
ua = Array(SD, buffer=ue)
print("Error=%2.16e" % (np.linalg.norm(uj - ua)))
assert np.allclose(uj, ua, atol=1e-5)

point = np.array([0.1, 0.2])
p = SD.eval(point, f_hat)