Example #1
0
def test_cylinder():
    T = get_function_space('cylinder')
    u = TrialFunction(T)
    du = div(grad(u))
    assert du.tolatex() == '\\frac{\\partial^2 u}{\\partial x^2 }+\\frac{1}{x}\\frac{\\partial  u}{\\partial x  }+\\frac{1}{x^{2}}\\frac{\\partial^2 u}{\\partial y^2 }+\\frac{\\partial^2 u}{\\partial z^2 }'
    V = VectorSpace(T)
    u = TrialFunction(V)
    du = div(grad(u))
    assert du.tolatex() == '\\left( \\frac{\\partial^2 u^{x}}{\\partial x^2 }+\\frac{1}{x}\\frac{\\partial  u^{x}}{\\partial x  }+\\frac{1}{x^{2}}\\frac{\\partial^2 u^{x}}{\\partial y^2 }- \\frac{2}{x}\\frac{\\partial  u^{y}}{\\partial y  }- \\frac{1}{x^{2}}u^{x}+\\frac{\\partial^2 u^{x}}{\\partial z^2 }\\right) \\mathbf{b}_{x} \\\\+\\left( \\frac{\\partial^2 u^{y}}{\\partial x^2 }+\\frac{3}{x}\\frac{\\partial  u^{y}}{\\partial x  }+\\frac{2}{x^{3}}\\frac{\\partial  u^{x}}{\\partial y  }+\\frac{1}{x^{2}}\\frac{\\partial^2 u^{y}}{\\partial y^2 }+\\frac{\\partial^2 u^{y}}{\\partial z^2 }\\right) \\mathbf{b}_{y} \\\\+\\left( \\frac{\\partial^2 u^{z}}{\\partial x^2 }+\\frac{1}{x}\\frac{\\partial  u^{z}}{\\partial x  }+\\frac{1}{x^{2}}\\frac{\\partial^2 u^{z}}{\\partial y^2 }+\\frac{\\partial^2 u^{z}}{\\partial z^2 }\\right) \\mathbf{b}_{z} \\\\'
Example #2
0
    def setup(self, dt):
        self.params['dt'] = dt
        u = TrialFunction(self.T)
        v = TestFunction(self.T)

        # Note that we are here assembling implicit left hand side matrices,
        # as well as matrices that can be used to assemble the right hande side
        # much faster through matrix-vector products

        a, b = self.a, self.b
        self.solver = []
        for rk in range(3):
            mats = inner(v, u - ((a[rk]+b[rk])*dt/2)*self.LinearRHS(u))
            if len(mats[0].naxes) == 1:
                self.solver.append(la.SolverGeneric1ND(mats))
            elif len(mats[0].naxes) == 2:
                self.solver.append(la.SolverGeneric2ND(mats))
            else:
                raise NotImplementedError

        self.rhs_mats = []
        for rk in range(3):
            self.rhs_mats.append(inner(v, u + ((a[rk]+b[rk])*dt/2)*self.LinearRHS(u)))

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

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

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

    assert np.linalg.norm(f - (g0 + g1 + g2)) < 1e-8
Example #4
0
def test_quasiGalerkin(basis):
    N = 40
    T = FunctionSpace(N, 'C')
    S = FunctionSpace(N, 'C', basis=basis)
    u = TrialFunction(S)
    v = TestFunction(T)
    A = inner(v, div(grad(u)))
    B = inner(v, u)
    Q = chebyshev.quasi.QIGmat(N)
    A = Q*A
    B = Q*B
    M = B-A
    sol = la.Solve(M, S)
    f_hat = inner(v, Array(T, buffer=fe))
    f_hat[:-2] = Q.diags('csc')*f_hat[:-2]
    u_hat = Function(S)
    u_hat = sol(f_hat, u_hat)
    uj = u_hat.backward()
    ua = Array(S, buffer=ue)
    bb = Q*np.ones(N)
    assert abs(np.sum(bb[:8])) < 1e-8
    if S.boundary_condition().lower() == 'neumann':
        xj, wj = S.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 #5
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 #6
0
def test_curl(typecode):
    K0 = Basis(N[0], 'F', dtype=typecode.upper())
    K1 = Basis(N[1], 'F', dtype=typecode.upper())
    K2 = Basis(N[2], 'F', dtype=typecode)
    T = TensorProductSpace(comm, (K0, K1, K2), dtype=typecode)
    X = T.local_mesh(True)
    K = T.local_wavenumbers()
    Tk = VectorTensorProductSpace(T)
    u = TrialFunction(Tk)
    v = TestFunction(Tk)

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

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

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

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

    curl_ = Tk.backward(curl_hat, curl_)

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

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

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

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

    assert allclose(u_hat, U_hat)
Example #7
0
def test_div2(basis, quad):
    B = basis(8, quad=quad)
    u = TrialFunction(B)
    v = 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 #8
0
def test_mul2():
    mat = SparseMatrix({0: 1}, (3, 3))
    v = np.ones(3)
    c = mat * v
    assert np.allclose(c, 1)
    mat = SparseMatrix({-2: 1, -1: 1, 0: 1, 1: 1, 2: 1}, (3, 3))
    c = mat * v
    assert np.allclose(c, 3)
    SD = Basis(8, "L", bc=(0, 0), scaled=True)
    u = TrialFunction(SD)
    v = TestFunction(SD)
    mat = inner(grad(u), grad(v))
    z = Function(SD, val=1)
    c = mat * z
    assert np.allclose(c[:6], 1)
Example #9
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)
Example #10
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)
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 #12
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 #13
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 #15
0
def test_helmholtz3D(family, axis):
    la = lla
    if family == 'chebyshev':
        la = cla
    N = (8, 9, 10)
    SD = Basis(N[allaxes3D[axis][0]], family=family, bc=(0, 0))
    K1 = Basis(N[allaxes3D[axis][1]], family='F', dtype='D')
    K2 = Basis(N[allaxes3D[axis][2]], family='F', dtype='d')
    subcomms = mpi4py_fft.pencil.Subcomm(MPI.COMM_WORLD, [0, 1, 1])
    bases = [0] * 3
    bases[allaxes3D[axis][0]] = SD
    bases[allaxes3D[axis][1]] = K1
    bases[allaxes3D[axis][2]] = K2
    T = TensorProductSpace(subcomms, bases, axes=allaxes3D[axis])
    u = TrialFunction(T)
    v = TestFunction(T)
    if family == 'chebyshev':
        mat = inner(v, div(grad(u)))
    else:
        mat = inner(grad(v), grad(u))

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

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

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

    uc = Function(T)
    uc = H(uc, f)
    assert np.linalg.norm(uc - u) < 1e-12
Example #16
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 #17
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 #18
0
dt = 5e-5
c = -(k**2+nu*dt/2*k**4)
b = 1.0+nu*dt*k**2
a = -nu*dt/2.
fe = a*ue.diff(x, 4) + b*ue.diff(x, 2) + c*ue

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

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

SD = Basis(N, family=family, bc='Biharmonic', domain=domain)
X = SD.mesh()
u = TrialFunction(SD)
v = TestFunction(SD)

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

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

# Get left hand side of biharmonic equation (no integration by parts)
S = inner(v, a*Dx(u, 0, 4))
A = inner(v, b*Dx(u, 0, 2))
B = inner(v, c*u)

# Create linear algebra solver
H = Solver(S, A, B)
     -ua[1].diff(x, 2) - ua[1].diff(y, 2))

neumann_condition_x = ua[0].diff(x).evalf(subs={x: -1})
neumann_condition_y = ua[1].diff(y).evalf(subs={y: 1})

FXX = FunctionSpace(20, family='legendre', bc=(None, 0))
FXY = FunctionSpace(20, family='legendre', bc=(0, 0))
FYX = FunctionSpace(20, family='legendre', bc=(0, 0))
FYY = FunctionSpace(20, family='legendre', bc=(0, None))

TX = TensorProductSpace(comm, (FXX, FXY))
TY = TensorProductSpace(comm, (FYX, FYY))

V = VectorSpace([TX, TY])

u = TrialFunction(V)
v = TestFunction(V)
mat = inner(grad(u), grad(v))
fj = Array(V, buffer=f)
rhs = inner(v, fj)

# boundary integrals
# x - component
v_bndry_x = TestFunction(FXY)
gn_x = Array(FXY, buffer=neumann_condition_x)
evaluate_bndry_x = FXX.evaluate_basis_all(-1)
project_gn_x = inner(gn_x, v_bndry_x)
bndry_integral_x = -np.outer(evaluate_bndry_x, project_gn_x)
# y - component
v_bndry_y = TestFunction(FYX)
gn_y = Array(FYX, buffer=neumann_condition_y)
Example #20
0
    Array, Function, FunctionSpace

assert len(sys.argv) == 2, 'Call with one command-line argument'
assert isinstance(int(sys.argv[-1]), int)

# Use sympy to compute a rhs, given an analytical solution
x = symbols("x", real=True)
#ue = sin(4*x)*exp(-x**2)
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()
Example #21
0
import numpy as np
from shenfun import inner, grad, TestFunction, TrialFunction, Basis, Function, \
    Array

# Use sympy to compute a rhs, given an analytical solution
x = Symbol("x")
ue = cos(4 * x) + 1j * sin(6 * x)
#ue = cos(4*x)
fe = ue.diff(x, 2)

# Size of discretization
N = 40

dtype = {True: np.complex, False: np.float}[ue.has(1j)]
ST = Basis(N, dtype=dtype, domain=(-2 * np.pi, 2 * np.pi))
u = TrialFunction(ST)
v = TestFunction(ST)

X = ST.mesh()

# Get f on quad points and exact solution
fj = Array(ST, buffer=fe)
uj = Array(ST, buffer=ue)

# Compute right hand side
f_hat = Function(ST)
f_hat = inner(v, fj, output_array=f_hat)

# Solve Poisson equation
A = inner(grad(v), grad(u))
u_hat = Function(ST)
Example #22
0
from shenfun.chebyshev.bases import ShenBiharmonicBasis, Basis
from shenfun.fourier.bases import R2CBasis, C2CBasis
from shenfun.chebyshev.la import Biharmonic as Solver
from shenfun import inner, div, grad, TestFunction, TrialFunction, project, Dx
from shenfun import Function, TensorProductSpace
from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD

N = (32, 33, 34)
K0 = ShenBiharmonicBasis(N[0])
K1 = C2CBasis(N[1])
K2 = R2CBasis(N[2])
W = TensorProductSpace(comm, (K0, K1, K2))
u = TrialFunction(W)
v = TestFunction(W)
matrices = inner(v, div(grad(div(grad(u)))))
fj = Function(W, False)
fj[:] = np.random.random(fj.shape)

f_hat = inner(v, fj)  # Some right hand side
B = Solver(**matrices)

# Solve and transform to real space
u_hat = Function(W)  # Solution spectral space
u_hat = B(u_hat, f_hat)  # Solve
u = Function(W, False)
u = W.backward(u_hat, u)

# compute dudx of the solution
Example #23
0
        (y + 0.04) / a) + 1)))) + 0.5
v0 = 0.25 * (0.5 * (erf((x - 0.04) / a) + 1) - 0.5 * (erf(
    (x + 0.04) / a) + 1)) * (0.5 * (erf((y - 0.04) / a) + 1) - 0.5 * (erf(
        (y + 0.04) / a) + 1))

ul = lambdify((x, y), u0, modules=['numpy', {'erf': scipy.special.erf}])
vl = lambdify((x, y), v0, modules=['numpy', {'erf': scipy.special.erf}])

# Size of discretization
N = (200, 200)

K0 = Basis(N[0], 'F', dtype='D', domain=(-1., 1.))
K1 = Basis(N[1], 'F', dtype='d', domain=(-1., 1.))
T = TensorProductSpace(comm, (K0, K1))
X = T.local_mesh(True)
u = TrialFunction(T)
v = TestFunction(T)

# For nonlinear term we can use the 3/2-rule with padding
Tp = T.get_dealiased((1.5, 1.5))

# Turn on padding by commenting
#Tp = T

# Create vector spaces and a test function for the regular vector space
TV = VectorTensorProductSpace(T)
TVp = VectorTensorProductSpace(Tp)
vv = TestFunction(TV)
uu = TrialFunction(TV)

# Declare solution arrays and work arrays
Example #24
0
x, y = symbols("x,y")
ue = (sin(2 * np.pi * x) * sin(4 * np.pi * y)) * (1 - x**2) * (1 - y**2)
fe = ue.diff(x, 4) + ue.diff(y, 4) + 2 * ue.diff(x, 2, y, 2)

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

# 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
Example #25
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[0], 'C', bc=(0, 0), quad=params.Dquad)
    CT = Basis(params.N[0], 'C', quad=params.Dquad)
    CP = Basis(params.N[0], 'C', quad=params.Dquad)
    K0 = Basis(params.N[1], 'F', domain=(0, params.L[1]), dtype='D')
    K1 = Basis(params.N[2], 'F', domain=(0, params.L[2]), dtype='d')
    CP.slice = lambda: slice(0, CT.N)

    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 = VectorTensorProductSpace(FST)
    VCT = VectorTensorProductSpace(FCT)
    VQ = MixedTensorProductSpace([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 = Basis(params.N[0], 'C', bc=(0, 0), quad=params.Dquad)
        CTp = Basis(params.N[0], 'C', quad=params.Dquad)
    else:
        STp, CTp = ST, CT
    K0p = Basis(params.N[1], 'F', dtype='D', domain=(0, params.L[1]), **kw)
    K1p = Basis(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 = VectorTensorProductSpace(FSTp)
    VCp = MixedTensorProductSpace([FSTp, FCTp, FCTp])

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

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

    # 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

    # primary variable
    u = UP_hat

    H_hat = Function(VFS)
    H_hat0 = Function(VFS)
    H_hat1 = Function(VFS)

    dU = Function(VQ)
    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

    alfa = 2./nu/dt
    a0 = inner(vt, (2./nu/dt)*ut-div(grad(ut)))
    a1 = inner(vt, (2./nu)*grad(pt))
    a2 = inner(qt, (2./nu)*div(ut))

    M = BlockMatrix(a0+a1+a2)

    # Collect all matrices
    mat = config.AttributeDict(
        dict(CDD=inner_product((ST, 0), (ST, 1)),
             AB=HelmholtzCoeff(N[0], 1., alfa-K2, 0, ST.quad),))

    la = None

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

    return config.AttributeDict(locals())
Example #26
0
import shenfun
from shenfun import inner, TestFunction, TrialFunction, div, grad
import numpy as np

N = 8

B = shenfun.chebyshev.bases.ShenDirichletBasis(N, plan=True)
#B = FFT = shenfun.fourier.bases.R2CBasis(N, plan=True)

u = TrialFunction(B)
v = TestFunction(B)
mass = inner(u, v) # spectral matrix, i.e. a dict
print(type(mass)) 
print(mass)

# linear and bilinear form
K = inner(v, div(grad(u)))

# solves Ku=b
fj = np.random.random(N)
bhat = inner(v, fj) # transform of fj, same as B.forward(fj) 
#bhat2 = B.forward(fj) 
print(type(mass)) 
arint(type(mass)) 
uhat = np.zeros_like(bhat)
uhat = K.solve(bhat, uhat) # solution in spectral space
u = B.backward(uhat) # back to physical space

# on a three dimensional cube, t
# the matrix solve is applied along the first dimension since this is the default behaviour.
Example #27
0
            ###
        #err += " & {:2.2e} ".format(errb/M)
        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 #28
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 #29
0
def initialize(solver, context):
    # Initialize with pertubation ala perturbU (https://github.com/wyldckat/perturbU) for openfoam
    U = context.U
    X = context.X
    U_hat = context.U_hat
    params = config.params
    Y = np.where(X[0] < 0, 1+X[0], 1-X[0])
    utau = params.nu*params.Re_tau
    Um = 46.9091*utau # For Re_tau=180
    #Um = 56.*utau
    Xplus = Y*params.Re_tau
    Yplus = X[1]*params.Re_tau
    Zplus = X[2]*params.Re_tau
    duplus = Um*0.2/utau  #Um*0.25/utau
    alfaplus = params.L[1]/200.  # May have to adjust these two for different Re
    betaplus = params.L[2]/100.  #
    sigma = 0.00055 # 0.00055
    epsilon = Um/200.   #Um/200.
    U[:] = 0
    U[1] = Um*(Y-0.5*Y**2)
    dev = 1+0.0000001*np.random.randn(Y.shape[0], Y.shape[1], Y.shape[2])
    #dev = np.fromfile('dev.dat').reshape((64, 64, 64))
    dd = utau*duplus/2.0*Xplus/40.*np.exp(-sigma*Xplus**2+0.5)*np.cos(betaplus*Zplus)*dev[:, slice(0, 1), :]
    U[1] += dd
    U[2] += epsilon*np.sin(alfaplus*Yplus)*Xplus*np.exp(-sigma*Xplus**2)*dev[:, :, slice(0, 1)]
    U_hat = U.forward(U_hat)
    U = U_hat.backward(U)
    U_hat = U.forward(U_hat)

    if "KMM" in params.solver:
        context.g[:] = 1j*context.K[1]*U_hat[2] - 1j*context.K[2]*U_hat[1]

    # Set the flux
    #flux[0] = context.FST.dx(U[1], context.ST.quad)
    #solver.comm.Bcast(flux)

    # project to zero divergence
    div_u = solver.get_divergence(**context)
    print('div0 ', dx(div_u**2, context.FST))
    u = TrialFunction(context.FST)
    v = TestFunction(context.FST)
    A = inner(v, div(grad(u)))
    b = inner(v, div(U_hat))
    from shenfun.chebyshev.la import Helmholtz
    sol = Helmholtz(*A)
    phi = Function(context.FST)
    phi = sol(phi, b)
    U_hat -= project(grad(phi), context.VFS)
    U = U_hat.backward(U)
    div_u = solver.get_divergence(**context)
    print('div1 ', dx(div_u**2, context.FST))

    if solver.rank == 0:
        print("Flux {}".format(flux[0]))

    if not 'KMM' in params.solver:
        P_hat = solver.compute_pressure(**context)
        P = P_hat.backward(context.P)

    if not 'RK3' in params.solver:
        context.U_hat0[:] = context.U_hat[:]
        context.H_hat1[:] = solver.get_convection(**context)