def test_vector_assemble_matrix_interior(): mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 3, 3) V = dolfinx.VectorFunctionSpace(mesh, ("CG", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) a = ufl.inner(ufl.jump(u), ufl.jump(v)) * ufl.dS A = dolfinx.fem.assemble_matrix(a) A.assemble()
def vV1(squaremesh_5): return dolfinx.VectorFunctionSpace(squaremesh_5, ("P", 1))
# In the previous sections, we have considered how to plot scalar valued # functions. This section will show you how to plot vector valued # functions. We start by interpolating an expression into a second order # CG space. def vel(x): vals = np.zeros((2, x.shape[1])) vals[0] = np.sin(x[1]) vals[1] = 0.1 * x[0] return vals mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 6, 6, dolfinx.cpp.mesh.CellType.triangle) V = dolfinx.VectorFunctionSpace(mesh, ("CG", 2)) uh = dolfinx.Function(V) uh.interpolate(vel) # We use the `dolfinx.plot.create_vtk_topology` # function, as in the previous section. However, we input a set of cell # entities, which can restrict the plotting to subsets of our mesh num_cells = mesh.topology.index_map(mesh.topology.dim).size_local cell_entities = np.arange(num_cells, dtype=np.int32) topology, cell_types = dolfinx.plot.create_vtk_topology(V, cell_entities) # As we deal with a vector function space, we need to adjust the values # in the underlying one dimensional array in dolfinx.Function, by # reshaping the data, and add an extra column to make it a 3D vector num_dofs_local = uh.function_space.dofmap.index_map.size_local geometry = uh.function_space.tabulate_dof_coordinates()[:num_dofs_local]
def test_rank0(): """Test evaluation of UFL expression. This test evaluates gradient of P2 function at vertices of reference triangle. Because these points coincide with positions of point evaluation degrees-of-freedom of vector P1 space, values could be used to interpolate the expression into this space. This test also shows simple Numba assembler which accepts the donor P2 function ``f`` as a coefficient and tabulates vector P1 function into tensor ``b``. For a donor function f(x, y) = x^2 + 2*y^2 result is compared with the exact gradient grad f(x, y) = [2*x, 4*y]. """ mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 5, 5) P2 = dolfinx.FunctionSpace(mesh, ("P", 2)) vP1 = dolfinx.VectorFunctionSpace(mesh, ("P", 1)) f = dolfinx.Function(P2) def expr1(x): return x[0] ** 2 + 2.0 * x[1] ** 2 f.interpolate(expr1) ufl_expr = ufl.grad(f) points = np.array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0]]) compiled_expr = dolfinx.jit.ffcx_jit(mesh.mpi_comm(), (ufl_expr, points)) ffi = cffi.FFI() @numba.njit def assemble_expression(b, kernel, mesh, dofmap, coeff, coeff_dofmap): pos, x_dofmap, x = mesh geometry = np.zeros((3, 2)) w = np.zeros(6, dtype=PETSc.ScalarType) constants = np.zeros(1, dtype=PETSc.ScalarType) b_local = np.zeros(6, dtype=PETSc.ScalarType) for i, cell in enumerate(pos[:-1]): num_vertices = pos[i + 1] - pos[i] c = x_dofmap[cell:cell + num_vertices] for j in range(3): for k in range(2): geometry[j, k] = x[c[j], k] for j in range(6): w[j] = coeff[coeff_dofmap[i * 6 + j]] b_local.fill(0.0) kernel(ffi.from_buffer(b_local), ffi.from_buffer(w), ffi.from_buffer(constants), ffi.from_buffer(geometry)) for j in range(3): for k in range(2): b[2 * dofmap[i * 3 + j] + k] = b_local[2 * j + k] # Prepare mesh and dofmap data pos = mesh.geometry.dofmap.offsets x_dofs = mesh.geometry.dofmap.array x = mesh.geometry.x coeff_dofmap = P2.dofmap.list.array dofmap = vP1.dofmap.list.array # Data structure for the result b = dolfinx.Function(vP1) assemble_expression(b.vector.array, compiled_expr.tabulate_expression, (pos, x_dofs, x), dofmap, f.vector.array, coeff_dofmap) def grad_expr1(x): values = np.empty((2, x.shape[1])) values[0] = 2.0 * x[0] values[1] = 4.0 * x[1] return values b2 = dolfinx.Function(vP1) b2.interpolate(grad_expr1) assert np.isclose((b2.vector - b.vector).norm(), 0.0)
r = dolfinx.Function(R, name='r') δu = ufl.TestFunction(U) δw = ufl.TestFunction(W) δr = ufl.TestFunction(R) # Define state as (ordered) list of functions m = [u, w, r] δm = [δu, δw, δr] # GEOMETRY ------------------------------------------------------------------- # Coordinates of undeformed configuration x0 = ufl.SpatialCoordinate(mesh) # Function spaces for geometric quantities extracted from mesh N = dolfinx.VectorFunctionSpace(mesh, ("DG", q), mesh.geometry.dim) B = dolfinx.TensorFunctionSpace(mesh, ("DG", q), (mesh.topology.dim, mesh.topology.dim)) # Normal vector (gdim x 1) and curvature tensor (tdim x tdim) n0i = dolfinx.Function(N) B0i = dolfinx.Function(B) # Jacobi matrix of map reference -> undeformed J0 = ufl.geometry.Jacobian(mesh) # Tangent basis gs = J0[:, 0] gη = ufl.as_vector([0, 1, 0]) # unit vector e_y (assume curve in x-z plane) gξ = ufl.cross(gs, gη) # Unit tangent basis gs /= ufl.sqrt(ufl.dot(gs, gs))
def test_pipes_stokes(): import gmsh gmsh.initialize() gmsh.model.add("test_pipes") geo = gmsh.model.geo p0 = geo.addPoint(0.0, 0.0, 0.0) p1 = geo.addPoint(1.0, 0.0, 0.0) p2 = geo.addPoint(0.0, -1.0, 0.0) p3 = geo.addPoint(1.0, -1.0, 0.0) p4 = geo.addPoint(1.0, -2.0, 0.0) p5 = geo.addPoint(2.0, -2.0, 0.0) p6 = geo.addPoint(2.0, -1.0, 0.0) l0 = geo.addLine(p0, p2) l1 = geo.addCircleArc(p2, p3, p4) l2 = geo.addLine(p4, p5) l3 = geo.addLine(p5, p6) l4 = geo.addLine(p6, p3) l5 = geo.addLine(p3, p1) l6 = geo.addLine(p1, p0) cl = geo.addCurveLoop([l0, l1, l2, l3, l4, l5, l6]) s0 = geo.addPlaneSurface([cl]) # Bottom gmsh.model.addPhysicalGroup(1, [l0, l1, l2], 1) gmsh.model.setPhysicalName(1, 1, "bottom") # Up gmsh.model.addPhysicalGroup(1, [l4, l5], 2) gmsh.model.setPhysicalName(1, 2, "up") # Inflow gmsh.model.addPhysicalGroup(1, [l6], 3) gmsh.model.setPhysicalName(1, 3, "inflow") geo.synchronize() gmsh.model.mesh.generate() gmsh.model.mesh.refine() gmsh.model.mesh.refine() gmsh.model.mesh.generate() mesh, mts = dolfiny.mesh.gmsh_to_dolfin(gmsh.model, 2, prune_z=True) mt1, keys1 = dolfiny.mesh.merge_meshtags(mts, 1) with dolfinx.io.XDMFFile(MPI.COMM_WORLD, "mesh.xdmf", "w") as out: out.write_mesh(mesh) V = dolfinx.VectorFunctionSpace(mesh, ("P", 2)) P = dolfinx.FunctionSpace(mesh, ("P", 1)) L = dolfinx.FunctionSpace(mesh, ("P", 1)) u = dolfinx.Function(V, name="u") v = ufl.TestFunction(V) p = dolfinx.Function(P, name="p") q = ufl.TestFunction(P) lam = dolfinx.Function(L, name="l") m = ufl.TestFunction(L) ds = ufl.Measure("ds", subdomain_data=mt1, domain=mesh) n = ufl.FacetNormal(mesh) F0 = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx(mesh) \ - p * ufl.div(v) * ufl.dx(mesh) + lam * ufl.inner(v, n) * ds(keys1["bottom"]) F1 = ufl.div(u) * q * ufl.dx(mesh) F2 = ufl.inner(u, n) * m * ds(keys1["bottom"]) u_inflow = dolfinx.Function(V) inflowdofsV = dolfiny.mesh.locate_dofs_topological(V, mt1, keys1["inflow"]) u_up = dolfinx.Function(V) updofsV = dolfiny.mesh.locate_dofs_topological(V, mt1, keys1["up"]) def uinflow(x): values = numpy.zeros((2, x.shape[1])) values[0] = 0.0 values[1] = -1.0 return values u_inflow.interpolate(uinflow) p_bc = dolfinx.Function(P) bcdofsP = dolfinx.fem.locate_dofs_geometrical( P, lambda x: numpy.logical_and(numpy.isclose(x[0], 0.0), numpy.isclose(x[1], 0.0))) # Find common dofs at the top corners intersect = numpy.intersect1d(inflowdofsV, updofsV) # Remove for consistency inflowdofsV = numpy.setdiff1d(inflowdofsV, intersect) bcs = [dolfinx.fem.DirichletBC(u_inflow, inflowdofsV)] bcs.append(dolfinx.fem.DirichletBC(u_up, updofsV)) bcs.append(dolfinx.fem.DirichletBC(p_bc, bcdofsP)) lagrangedofsL = dolfiny.mesh.locate_dofs_topological(L, mt1, keys1["bottom"])[:, 0] Vsize = V.dofmap.index_map.block_size * V.dofmap.index_map.size_local Psize = P.dofmap.index_map.block_size * P.dofmap.index_map.size_local rdofsV = numpy.arange(Vsize, dtype=numpy.int32) rdofsP = numpy.arange(Psize, dtype=numpy.int32) r = dolfiny.restriction.Restriction([V, P, L], [rdofsV, rdofsP, lagrangedofsL]) opts = PETSc.Options("pipes") opts["snes_type"] = "newtonls" opts["snes_linesearch_type"] = "basic" opts["snes_rtol"] = 1.0e-08 opts["snes_max_it"] = 10 opts["ksp_type"] = "preonly" opts["pc_type"] = "lu" opts["pc_factor_mat_solver_type"] = "mumps" opts_global = PETSc.Options() opts_global['mat_mumps_icntl_24'] = 1 problem = dolfiny.snesblockproblem.SNESBlockProblem( [F0, F1, F2], [u, p, lam], bcs=bcs, restriction=r, prefix="pipes") s0, s1, s2 = problem.solve() assert problem.snes.getConvergedReason() > 0
def test_sloped_stokes(): path = os.path.dirname(os.path.realpath(__file__)) # Read mesh, subdomains and boundaries with dolfinx.io.XDMFFile(MPI.COMM_WORLD, os.path.join(path, "data", "sloped_triangle_mesh.xdmf"), "r") as infile: mesh = infile.read_mesh(name="Grid") mesh.topology.create_connectivity_all() with dolfinx.io.XDMFFile(MPI.COMM_WORLD, os.path.join(path, "data", "sloped_line_mvc.xdmf"), "r") as infile: boundaries = infile.read_meshtags(mesh, name="Grid") V = dolfinx.VectorFunctionSpace(mesh, ("P", 2)) P = dolfinx.FunctionSpace(mesh, ("P", 1)) L = dolfinx.FunctionSpace(mesh, ("P", 1)) u = dolfinx.Function(V, name="u") v = ufl.TestFunction(V) p = dolfinx.Function(P, name="p") q = ufl.TestFunction(P) lam = dolfinx.Function(L, name="l") m = ufl.TestFunction(L) n = ufl.FacetNormal(mesh) ds = ufl.Measure("ds", subdomain_data=boundaries, domain=mesh) F0 = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx(mesh) \ - p * ufl.div(v) * ufl.dx(mesh) + lam * ufl.inner(v, n) * ds(1) F1 = ufl.div(u) * q * ufl.dx(mesh) F2 = ufl.inner(u, n) * m * ds(1) u_bc = dolfinx.Function(V) bc_facets = numpy.where(boundaries.values == 4)[0] bcdofsV = dolfinx.fem.locate_dofs_topological(V, 1, boundaries.indices[bc_facets]) u_bc_top = dolfinx.Function(V) bctop_facets = numpy.where(boundaries.values == 3)[0] bcdofstopV = dolfinx.fem.locate_dofs_topological(V, 1, boundaries.indices[bctop_facets]) def utop(x): values = numpy.zeros((2, x.shape[1])) values[0] = 1.0 values[1] = 0.0 return values u_bc_top.interpolate(utop) # Find common dofs at the top corners intersect = numpy.intersect1d(bcdofsV, bcdofstopV) # Remove for consistency bcdofstopV = numpy.setdiff1d(bcdofstopV, intersect) bcs = [dolfinx.fem.DirichletBC(u_bc, bcdofsV)] bcs.append(dolfinx.fem.DirichletBC(u_bc_top, bcdofstopV)) r_facets = numpy.where(boundaries.values == 1)[0] rdofsL = dolfinx.fem.locate_dofs_topological(L, 1, boundaries.indices[r_facets])[:, 0] Vsize = V.dofmap.index_map.block_size * (V.dofmap.index_map.size_local) Psize = P.dofmap.index_map.block_size * (P.dofmap.index_map.size_local) rdofsV = numpy.arange(Vsize, dtype=numpy.int32) rdofsP = numpy.arange(Psize, dtype=numpy.int32) r = dolfiny.restriction.Restriction([V, P, L], [rdofsV, rdofsP, rdofsL]) opts = PETSc.Options("stokes") opts["snes_type"] = "newtonls" opts["snes_linesearch_type"] = "basic" opts["snes_rtol"] = 1.0e-08 opts["snes_max_it"] = 10 opts["ksp_type"] = "preonly" opts["pc_type"] = "lu" opts["pc_factor_mat_solver_type"] = "mumps" opts_glob = PETSc.Options() opts_glob['mat_mumps_icntl_24'] = 1 problem = dolfiny.snesblockproblem.SNESBlockProblem( [F0, F1, F2], [u, p, lam], bcs=bcs, restriction=r, prefix="stokes") s0, s1, s2 = problem.solve() assert problem.snes.getConvergedReason() > 0 assert problem.snes.getIterationNumber() == 1