def main(n):
    '''Solves grad-div problem in 2d with HypreAMS preconditioning'''
    # Exact solution
    x, y = sp.symbols('x[0] x[1]')
    
    u = sp.sin(pi*x*(1-x)*y*(1-y))

    sp_div = lambda f: f[0].diff(x, 1) + f[1].diff(y, 1)

    sp_grad = lambda f: sp.Matrix([f.diff(x, 1), f.diff(y, 1)])

    sigma = sp_grad(u)    
    f = -sp_div(sigma) + u

    sigma_expr, u_expr, f_expr = map(as_expression, (sigma, u, f))

    # The discrete problem
    mesh = UnitSquareMesh(n, n)
    
    V = FunctionSpace(mesh, 'RT', 1)
    Q = FunctionSpace(mesh, 'DG', 0)
    W = (V, Q)

    sigma, u = map(TrialFunction, W)
    tau, v = map(TestFunction, W)

    a00 = inner(sigma, tau)*dx
    a01 = inner(div(tau), u)*dx
    a10 = inner(div(sigma), v)*dx
    a11 = -inner(u, v)*dx

    L0 = inner(Constant((0, 0)), tau)*dx
    L1 = inner(-f_expr, v)*dx

    AA = block_assemble([[a00, a01], [a10, a11]])
    bb = block_assemble([L0, L1])

    # b00 = inner(sigma, tau)*dx + inner(div(sigma), div(tau))*dx
    # B00 = LU(assemble(b00))
    B00 = HypreAMS(V)
    
    b11 = inner(u, v)*dx
    B11 = LumpedInvDiag(assemble(b11))

    BB = block_mat([[B00, 0], [0, B11]])
    
    AAinv = MinRes(AA, precond=BB, tolerance=1e-10, maxiter=500, show=2)

    # Compute solution
    sigma_h, u_h = AAinv * bb
    sigma_h, u_h = Function(V, sigma_h), Function(Q, u_h)

    niters = len(AAinv.residuals) - 1
    # error = sqrt(errornorm(sigma_expr, sigma_h, 'Hdiv', degree_rise=1)**2 +
    #              errornorm(u_expr, u_h, 'L2', degree_rise=1)**2)

    hmin = mesh.mpi_comm().tompi4py().allreduce(mesh.hmin(), pyMPI.MIN)
    error = 1.

    return hmin, V.dim()+Q.dim(), niters, error
Example #2
0
def main(n):
    '''Solves grad-div problem in 2d with HypreAMS preconditioning'''
    # Exact solution
    x, y = sp.symbols('x[0] x[1]')

    u = sp.sin(pi * x * (1 - x) * y * (1 - y))

    sp_div = lambda f: f[0].diff(x, 1) + f[1].diff(y, 1)

    sp_grad = lambda f: sp.Matrix([f.diff(x, 1), f.diff(y, 1)])

    sigma = sp_grad(u)
    f = -sp_div(sigma) + u

    sigma_expr, u_expr, f_expr = list(map(as_expression, (sigma, u, f)))

    # The discrete problem
    mesh = UnitSquareMesh(n, n)

    V = FunctionSpace(mesh, 'RT', 1)
    Q = FunctionSpace(mesh, 'DG', 0)
    W = (V, Q)

    sigma, u = list(map(TrialFunction, W))
    tau, v = list(map(TestFunction, W))

    a00 = inner(sigma, tau) * dx
    a01 = inner(div(tau), u) * dx
    a10 = inner(div(sigma), v) * dx
    a11 = -inner(u, v) * dx

    L0 = inner(Constant((0, 0)), tau) * dx
    L1 = inner(-f_expr, v) * dx

    AA = block_assemble([[a00, a01], [a10, a11]])
    bb = block_assemble([L0, L1])

    # b00 = inner(sigma, tau)*dx + inner(div(sigma), div(tau))*dx
    # B00 = LU(assemble(b00))
    B00 = HypreAMS(V)

    b11 = inner(u, v) * dx
    B11 = LumpedInvDiag(assemble(b11))

    BB = block_mat([[B00, 0], [0, B11]])

    AAinv = MinRes(AA, precond=BB, tolerance=1e-10, maxiter=500, show=2)

    # Compute solution
    sigma_h, u_h = AAinv * bb
    sigma_h, u_h = Function(V, sigma_h), Function(Q, u_h)

    niters = len(AAinv.residuals) - 1
    # error = sqrt(errornorm(sigma_expr, sigma_h, 'Hdiv', degree_rise=1)**2 +
    #              errornorm(u_expr, u_h, 'L2', degree_rise=1)**2)

    hmin = mesh.mpi_comm().tompi4py().allreduce(mesh.hmin(), pyMPI.MIN)
    error = 1.

    return hmin, V.dim() + Q.dim(), niters, error
Example #3
0
def speed(ncells):
    mesh = UnitSquareMesh(ncells, ncells)

    V = VectorFunctionSpace(mesh, 'CG', 2)
    Q = FunctionSpace(mesh, 'CG', 1)
    W = [V, Q]

    u, p = list(map(TrialFunction, W))
    v, q = list(map(TestFunction, W))

    a = [[0] * len(W) for _ in range(len(W))]
    a[0][0] = inner(grad(u), grad(v)) * dx
    a[0][1] = inner(p, div(v)) * dx
    a[1][0] = inner(q, div(u)) * dx

    x, y = SpatialCoordinate(mesh)
    L = [
        inner(as_vector((y * x**2, sin(pi * (x + y)))), v) * dx,
        inner(x + y, q) * dx
    ]

    A0 = block_assemble(a)
    b0 = block_assemble(L)

    # First method
    bc = DirichletBC(V, Constant((0, 0)), 'on_boundary')
    bcs = [[bc], []]
    t = Timer('first')
    block_bc(bcs, True).apply(A0).apply(b0)
    dt0 = t.stop()

    dimW = sum(Wi.dim() for Wi in W)

    A, b = list(map(block_assemble, (a, L)))

    t = Timer('second')
    A, b = apply_bc(A, b, bcs)
    dt1 = t.stop()

    print('>>>', (b - b0).norm())

    # First method
    A, c = list(map(block_assemble, (a, L)))
    block_rhs_bc(bcs, A).apply(c)

    print('>>>', (b - c).norm())

    return dimW, dt0, dt1, dt0 / dt1
Example #4
0
def identity(ncells):
    mesh = UnitSquareMesh(ncells, ncells)

    V = VectorFunctionSpace(mesh, 'CG', 2)
    Q = FunctionSpace(mesh, 'CG', 1)
    W = [V, Q]

    u, p = list(map(TrialFunction, W))
    v, q = list(map(TestFunction, W))

    a = [[0] * len(W) for _ in range(len(W))]
    a[0][0] = inner(grad(u), grad(v)) * dx
    a[0][1] = inner(p, div(v)) * dx
    a[1][0] = inner(q, div(u)) * dx

    x, y = SpatialCoordinate(mesh)
    L = [
        inner(as_vector((y * x**2, sin(pi * (x + y)))), v) * dx,
        inner(x + y, q) * dx
    ]

    A0 = block_assemble(a)
    b0 = block_assemble(L)

    # First methog
    bcs = [[], []]

    A, b = apply_bc(A0, b0, bcs)

    b0_ = np.hstack([bi.get_local() for bi in b0])
    b_ = np.hstack([bi.get_local() for bi in b])

    eb = (b - b0).norm()

    for i in range(len(W)):
        for j in range(len(W)):
            Aij = A[i][j]  # Always matrix

            x = Vector(mpi_comm_world(), Aij.size(1))
            x.set_local(np.random.rand(x.local_size()))

            y = Aij * x
            y0 = A0[i][j] * x

            print(i, j, '>>>', (y - y0).norm('linf'))
    return eb
Example #5
0
a20 = inner(q, div(u))*dx
a21 = inner(q, div(b))*dx 

f = Constant((0, 0))
# Rhs components
L0 = inner(f, v)*dx
L1 = inner(f, c)*dx

from block import block_assemble, block_bc, block_mat
from block.iterative import MinRes
from block.algebraic.petsc import ML, Cholesky

# lhs
AA = block_assemble([[a00, a01, a02],
                     [a10, a11, a12],
                     [a20, a21,   0]])
# rhs
b = block_assemble([L0, L1, 0])

# Collect boundary conditions
bcs = [[bc0, bc1], [], []]
block_bc(bcs, True).apply(AA).apply(b)

b22 = inner(p, q)*dx
B22 = assemble(b22)
# Possible action of preconditioner
BB = block_mat([[ML(AA[0, 0]), 0, 0],
                [0, Cholesky(AA[1, 1]), 0],
                [0, 0, Cholesky(B22)]])
Example #6
0
# Upper triangular part of A
a00 = inner(grad(u), grad(v)) * dx
a01 = inner(grad(b), grad(v)) * dx
a02 = inner(p, div(v)) * dx
a11 = inner(grad(b), grad(c)) * dx
a12 = inner(p, div(c)) * dx

f = Constant((0, 0))
# Rhs components
L0 = inner(f, v) * dx
L1 = inner(f, c) * dx

from block import block_assemble

bb = block_assemble([L0, L1, 0])

# # Collect boundary conditions
# bcs = [bc0, bc1]
#
# # Define variational problem
# (u, p) = TrialFunctions(W)
# (v, q) = TestFunctions(W)
# f = Constant((0, 0))
# a = (inner(grad(u), grad(v)) - div(v)*p + q*div(u))*dx
# L = inner(f, v)*dx
#
# # Compute solution
# w = Function(W)
# solve(a == L, w, bcs)
#
Example #7
0
# Upper triangular part of A
a00 = inner(grad(u), grad(v))*dx
a01 = inner(grad(b), grad(v))*dx
a02 = inner(p, div(v))*dx
a11 = inner(grad(b), grad(c))*dx
a12 = inner(p, div(c))*dx

f = Constant((0, 0))
# Rhs components
L0 = inner(f, v)*dx
L1 = inner(f, c)*dx

from block import block_assemble

bb = block_assemble([L0, L1, 0])


# # Collect boundary conditions
# bcs = [bc0, bc1]
# 
# # Define variational problem
# (u, p) = TrialFunctions(W)
# (v, q) = TestFunctions(W)
# f = Constant((0, 0))
# a = (inner(grad(u), grad(v)) - div(v)*p + q*div(u))*dx
# L = inner(f, v)*dx
# 
# # Compute solution
# w = Function(W)
# solve(a == L, w, bcs)
Example #8
0
def mini_block(n):
    '''Just check MMS'''
    mesh = UnitSquareMesh(n, n)
    # Just approx
    f_space = VectorFunctionSpace(mesh, 'DG', 1)
    h_space = TensorFunctionSpace(mesh, 'DG', 1)

    u_int = interpolate(u_exact, VectorFunctionSpace(mesh, 'CG', 2))
    p_int = interpolate(p_exact, FunctionSpace(mesh, 'CG', 2))

    f = project(-div(grad(u_int)) + grad(p_int), f_space)
    h = project(-p_int * Identity(2) + grad(u_int), h_space)

    # ----------------

    V = VectorFunctionSpace(mesh, 'Lagrange', 1)
    Vb = VectorFunctionSpace(mesh, 'Bubble', 3)
    Q = FunctionSpace(mesh, 'Lagrange', 1)
    W = [V, Vb, Q]

    u, ub, p = list(map(TrialFunction, W))
    v, vb, q = list(map(TestFunction, W))

    n = FacetNormal(mesh)

    a = [[0] * len(W) for _ in range(len(W))]
    a[0][0] = inner(grad(u), grad(v)) * dx
    a[0][2] = -inner(div(v), p) * dx
    a[2][0] = -inner(div(u), q) * dx

    a[1][1] = inner(grad(ub), grad(vb)) * dx
    a[1][2] = -inner(div(vb), p) * dx
    a[2][1] = -inner(div(ub), q) * dx

    a[0][1] = inner(grad(v), grad(ub)) * dx
    a[1][0] = inner(grad(vb), grad(u)) * dx

    # NOTE: bubbles don't contribute to surface
    L = [
        inner(dot(h, n), v) * ds + inner(f, v) * dx,
        inner(f, vb) * dx,
        inner(Constant(0), q) * dx
    ]
    # Bubbles don't have bcs on the surface
    bcs = [[DirichletBC(W[0], u_exact, 'near(x[0], 0)')], [], []]

    AA = block_assemble(a)
    bb = block_assemble(L)

    block_bc(bcs, True).apply(AA).apply(bb)

    # Preconditioner
    B0 = AMG(AA[0][0])

    H1_Vb = inner(grad(ub), grad(vb)) * dx + inner(ub, vb) * dx
    B1 = LumpedInvDiag(assemble(H1_Vb))

    L2_Q = assemble(inner(p, q) * dx)
    B2 = LumpedInvDiag(L2_Q)

    BB = block_mat([[B0, 0, 0], [0, B1, 0], [0, 0, B2]])

    x0 = AA.create_vec()
    x0.randomize()

    AAinv = MinRes(AA,
                   precond=BB,
                   tolerance=1e-10,
                   maxiter=500,
                   relativeconv=True,
                   show=2,
                   initial_guess=x0)

    # Compute solution
    u, ub, p = AAinv * bb

    uh_ = Function(V, u)
    uhb = Function(Vb, ub)
    ph = Function(Q, p)

    uh = Sum([uh_, uhb], degree=1)

    return uh, ph, sum(Wi.dim() for Wi in W)
Example #9
0
a12 = inner(p, div(c)) * dx

a20 = inner(q, div(u)) * dx
a21 = inner(q, div(b)) * dx

f = Constant((0, 0))
# Rhs components
L0 = inner(f, v) * dx
L1 = inner(f, c) * dx

from block import block_assemble, block_bc, block_mat
from block.iterative import MinRes
from block.algebraic.petsc import ML, Cholesky

# lhs
AA = block_assemble([[a00, a01, a02], [a10, a11, a12], [a20, a21, 0]])
# rhs
b = block_assemble([L0, L1, 0])

# Collect boundary conditions
bcs = [[bc0, bc1], [], []]
block_bc(bcs, True).apply(AA).apply(b)

b22 = inner(p, q) * dx
B22 = assemble(b22)
# Possible action of preconditioner
BB = block_mat([[ML(AA[0, 0]), 0, 0], [0, Cholesky(AA[1, 1]), 0],
                [0, 0, Cholesky(B22)]])

AAinv = MinRes(AA, precond=BB, tolerance=1E-10, maxiter=500)
U, B, P = AAinv * b
Example #10
0
def mini_block(n):
    '''Just check MMS'''
    mesh = UnitSquareMesh(n, n)
    # Just approx
    f_space = VectorFunctionSpace(mesh, 'DG', 1)
    h_space = TensorFunctionSpace(mesh, 'DG', 1)

    u_int = interpolate(u_exact, VectorFunctionSpace(mesh, 'CG', 2))
    p_int = interpolate(p_exact, FunctionSpace(mesh, 'CG', 2))
        
    f = project(-div(grad(u_int)) + grad(p_int), f_space)
    h = project(-p_int*Identity(2) + grad(u_int), h_space)

    # ----------------

    V = VectorFunctionSpace(mesh, 'Lagrange', 1)
    Vb = VectorFunctionSpace(mesh, 'Bubble', 3)
    Q = FunctionSpace(mesh, 'Lagrange', 1)
    W = [V, Vb, Q]

    u, ub, p = map(TrialFunction, W)
    v, vb, q = map(TestFunction, W)

    n = FacetNormal(mesh)

    a = [[0]*len(W) for _ in range(len(W))]
    a[0][0] = inner(grad(u), grad(v))*dx
    a[0][2] = - inner(div(v), p)*dx
    a[2][0] = - inner(div(u), q)*dx

    a[1][1] = inner(grad(ub), grad(vb))*dx
    a[1][2] = - inner(div(vb), p)*dx
    a[2][1] = - inner(div(ub), q)*dx

    a[0][1] = inner(grad(v), grad(ub))*dx
    a[1][0] = inner(grad(vb), grad(u))*dx

    # NOTE: bubbles don't contribute to surface
    L = [inner(dot(h, n), v)*ds + inner(f, v)*dx,
         inner(f, vb)*dx,
         inner(Constant(0), q)*dx]
    # Bubbles don't have bcs on the surface
    bcs = [[DirichletBC(W[0], u_exact, 'near(x[0], 0)')], [], []]

    AA = block_assemble(a)
    bb = block_assemble(L)

    block_bc(bcs, True).apply(AA).apply(bb)

    # Preconditioner
    B0 = AMG(AA[0][0])
    
    H1_Vb = inner(grad(ub), grad(vb))*dx + inner(ub, vb)*dx
    B1 = LumpedInvDiag(assemble(H1_Vb))
    
    L2_Q = assemble(inner(p, q)*dx)
    B2 = LumpedInvDiag(L2_Q)

    BB = block_mat([[B0, 0, 0],
                    [0, B1, 0],
                    [0, 0, B2]])
    
    x0 = AA.create_vec()
    x0.randomize()

    AAinv = MinRes(AA, precond=BB, tolerance=1e-10, maxiter=500, relativeconv=True, show=2,
                   initial_guess=x0)

    # Compute solution
    u, ub, p = AAinv * bb

    uh_ = Function(V, u)
    uhb = Function(Vb, ub)
    ph = Function(Q, p)
    
    uh = Sum([uh_, uhb], degree=1)
                
    return uh, ph, sum(Wi.dim() for Wi in W)
Example #11
0

# -------------------------------------------------------------------

if __name__ == '__main__':
    from block import block_assemble
    from dolfin import *

    mesh = UnitSquareMesh(10, 10)
    V = FunctionSpace(mesh, 'CG', 2)
    Q = FunctionSpace(mesh, 'CG', 1)
    W = [V, Q]

    vq = list(map(TestFunction, W))

    bb = block_assemble([inner(Constant(1), v) * dx for v in vq])

    vec = PETSc.Vec().create()
    vec.setSizes((V.dim() + Q.dim(), ) * 2)
    vec.setUp()

    #print vec.array
    vec = petsc_vector(vec, bb)

    bb0 = bb.copy()

    bb = block_vector(bb, vec)

    for x, y in zip(bb, bb0):
        print((x - y).norm('linf'), x.norm('l2'))