Exemple #1
0
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()
Exemple #2
0
def vV1(squaremesh_5):
    return dolfinx.VectorFunctionSpace(squaremesh_5, ("P", 1))
Exemple #3
0

# 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))
Exemple #6
0
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
Exemple #7
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