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
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
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
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
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)]])
# 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) #
# 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)
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)
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
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)
# ------------------------------------------------------------------- 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'))