def test_facet_integral(cell_type):
    """Test that the integral of a function over a facet is correct"""
    for count in range(5):
        mesh = unit_cell(cell_type)
        tdim = mesh.topology.dim

        V = FunctionSpace(mesh, ("Lagrange", 2))
        v = Function(V)

        map_f = mesh.topology.index_map(tdim - 1)
        num_facets = map_f.size_local + map_f.num_ghosts
        indices = np.arange(0, num_facets)
        values = np.arange(0, num_facets, dtype=np.intc)
        marker = MeshTags(mesh, tdim - 1, indices, values)

        # Functions that will have the same integral over each facet
        if cell_type == CellType.triangle:
            root = 3 ** 0.25  # 4th root of 3
            v.interpolate(lambda x: (x[0] - 1 / root) ** 2 + (x[1] - root / 3) ** 2)
        elif cell_type == CellType.quadrilateral:
            v.interpolate(lambda x: x[0] * (1 - x[0]) + x[1] * (1 - x[1]))
        elif cell_type == CellType.tetrahedron:
            s = 2 ** 0.5 * 3 ** (1 / 3)  # side length
            v.interpolate(lambda x: (x[0] - s / 2) ** 2 + (x[1] - s / 2 / np.sqrt(3)) ** 2
                          + (x[2] - s * np.sqrt(2 / 3) / 4) ** 2)
        elif cell_type == CellType.hexahedron:
            v.interpolate(lambda x: x[0] * (1 - x[0]) + x[1] * (1 - x[1]) + x[2] * (1 - x[2]))

        # assert that the integral of these functions over each face are equal
        out = []
        for j in range(num_facets):
            a = v * ds(subdomain_data=marker, subdomain_id=j)
            result = fem.assemble_scalar(a)
            out.append(result)
            assert np.isclose(result, out[0])
Exemple #2
0
def test_interpolate_subset(order, dim, affine):
    if dim == 2:
        ct = CellType.triangle if affine else CellType.quadrilateral
        mesh = create_unit_square(MPI.COMM_WORLD, 3, 4, ct)
    elif dim == 3:
        ct = CellType.tetrahedron if affine else CellType.hexahedron
        mesh = create_unit_cube(MPI.COMM_WORLD, 3, 2, 2, ct)

    V = FunctionSpace(mesh, ("DG", order))
    u = Function(V)

    cells = locate_entities(mesh, mesh.topology.dim,
                            lambda x: x[1] <= 0.5 + 1e-10)
    num_local_cells = mesh.topology.index_map(mesh.topology.dim).size_local
    cells_local = cells[cells < num_local_cells]

    x = ufl.SpatialCoordinate(mesh)
    f = x[1]**order
    expr = Expression(f, V.element.interpolation_points)
    u.interpolate(expr, cells_local)
    mt = MeshTags(mesh, mesh.topology.dim, cells_local,
                  np.ones(cells_local.size, dtype=np.int32))
    dx = ufl.Measure("dx", domain=mesh, subdomain_data=mt)
    assert np.isclose(
        np.abs(form(assemble_scalar(form(ufl.inner(u - f, u - f) * dx(1))))),
        0)
    integral = mesh.comm.allreduce(assemble_scalar(form(u * dx)), op=MPI.SUM)
    assert np.isclose(integral, 1 / (order + 1) * 0.5**(order + 1), 0)
Exemple #3
0
def test_facet_normals(cell_type):
    """Test that FacetNormal is outward facing"""
    for count in range(5):
        mesh = unit_cell(cell_type)
        tdim = mesh.topology.dim

        V = VectorFunctionSpace(mesh, ("Lagrange", 1))
        normal = FacetNormal(mesh)
        v = Function(V)

        map_f = mesh.topology.index_map(tdim - 1)
        num_facets = map_f.size_local + map_f.num_ghosts
        indices = np.arange(0, num_facets)
        values = np.arange(0, num_facets, dtype=np.intc)
        marker = MeshTags(mesh, tdim - 1, indices, values)

        # For each facet, check that the inner product of the normal and
        # the vector that has a positive normal component on only that facet
        # is positive
        for i in range(num_facets):
            if cell_type == CellType.interval:
                co = mesh.geometry.x[i]
                v.interpolate(lambda x: x[0] - co[0])
            if cell_type == CellType.triangle:
                co = mesh.geometry.x[i]
                # Vector function that is zero at `co` and points away from `co`
                # so that there is no normal component on two edges and the integral
                # over the other edge is 1
                v.interpolate(lambda x: ((x[0] - co[0]) / 2,
                                         (x[1] - co[1]) / 2))
            elif cell_type == CellType.tetrahedron:
                co = mesh.geometry.x[i]
                # Vector function that is zero at `co` and points away from `co`
                # so that there is no normal component on three faces and the integral
                # over the other edge is 1
                v.interpolate(lambda x: ((x[0] - co[0]) / 3, (x[1] - co[1]) /
                                         3, (x[2] - co[2]) / 3))
            elif cell_type == CellType.quadrilateral:
                # function that is 0 on one edge and points away from that edge
                # so that there is no normal component on three edges
                v.interpolate(lambda x: tuple(x[j] - i % 2 if j == i // 2 else
                                              0 * x[j] for j in range(2)))
            elif cell_type == CellType.hexahedron:
                # function that is 0 on one face and points away from that face
                # so that there is no normal component on five faces
                v.interpolate(lambda x: tuple(x[j] - i % 2 if j == i // 3 else
                                              0 * x[j] for j in range(3)))

            # assert that the integrals these functions dotted with the normal over a face
            # is 1 on one face and 0 on the others
            ones = 0
            for j in range(num_facets):
                a = inner(v, normal) * ds(subdomain_data=marker,
                                          subdomain_id=j)
                result = fem.assemble_scalar(a)
                if np.isclose(result, 1):
                    ones += 1
                else:
                    assert np.isclose(result, 0)
            assert ones == 1
def test_assembly_dx_domains(mode):
    mesh = create_unit_square(MPI.COMM_WORLD, 10, 10, ghost_mode=mode)
    V = FunctionSpace(mesh, ("Lagrange", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    # Prepare a marking structures
    # indices cover all cells
    # values are [1, 2, 3, 3, ...]
    cell_map = mesh.topology.index_map(mesh.topology.dim)
    num_cells = cell_map.size_local + cell_map.num_ghosts
    indices = np.arange(0, num_cells)
    values = np.full(indices.shape, 3, dtype=np.intc)
    values[0] = 1
    values[1] = 2
    marker = MeshTags(mesh, mesh.topology.dim, indices, values)
    dx = ufl.Measure('dx', subdomain_data=marker, domain=mesh)
    w = Function(V)
    w.x.array[:] = 0.5

    # Assemble matrix
    a = form(w * ufl.inner(u, v) * (dx(1) + dx(2) + dx(3)))
    A = assemble_matrix(a)
    A.assemble()
    a2 = form(w * ufl.inner(u, v) * dx)
    A2 = assemble_matrix(a2)
    A2.assemble()
    assert (A - A2).norm() < 1.0e-12

    bc = dirichletbc(Function(V), range(30))

    # Assemble vector
    L = form(ufl.inner(w, v) * (dx(1) + dx(2) + dx(3)))
    b = assemble_vector(L)

    apply_lifting(b, [a], [[bc]])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                  mode=PETSc.ScatterMode.REVERSE)
    set_bc(b, [bc])

    L2 = form(ufl.inner(w, v) * dx)
    b2 = assemble_vector(L2)
    apply_lifting(b2, [a], [[bc]])
    b2.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                   mode=PETSc.ScatterMode.REVERSE)
    set_bc(b2, [bc])
    assert (b - b2).norm() < 1.0e-12

    # Assemble scalar
    L = form(w * (dx(1) + dx(2) + dx(3)))
    s = assemble_scalar(L)
    s = mesh.comm.allreduce(s, op=MPI.SUM)
    assert s == pytest.approx(0.5, 1.0e-12)
    L2 = form(w * dx)
    s2 = assemble_scalar(L2)
    s2 = mesh.comm.allreduce(s2, op=MPI.SUM)
    assert s == pytest.approx(s2, 1.0e-12)
Exemple #5
0
def test_3d(tempdir, cell_type, encoding):
    filename = os.path.join(tempdir, "meshtags_3d.xdmf")
    comm = MPI.COMM_WORLD
    mesh = UnitCubeMesh(comm, 4, 4, 4, cell_type)

    bottom_facets = locate_entities(mesh, 2, lambda x: np.isclose(x[1], 0.0))
    bottom_values = np.full(bottom_facets.shape, 1, dtype=np.intc)
    left_facets = locate_entities(mesh, 2, lambda x: np.isclose(x[0], 0.0))
    left_values = np.full(left_facets.shape, 2, dtype=np.intc)

    indices, pos = np.unique(np.hstack((bottom_facets, left_facets)), return_index=True)
    mt = MeshTags(mesh, 2, indices, np.hstack((bottom_values, left_values))[pos])
    mt.name = "facets"

    top_lines = locate_entities(mesh, 1, lambda x: np.isclose(x[2], 1.0))
    top_values = np.full(top_lines.shape, 3, dtype=np.intc)
    right_lines = locate_entities(mesh, 1, lambda x: np.isclose(x[0], 1.0))
    right_values = np.full(right_lines.shape, 4, dtype=np.intc)

    indices, pos = np.unique(np.hstack((top_lines, right_lines)), return_index=True)
    mt_lines = MeshTags(mesh, 1, indices, np.hstack((top_values, right_values))[pos])
    mt_lines.name = "lines"

    with XDMFFile(comm, filename, "w", encoding=encoding) as file:
        mesh.topology.create_connectivity_all()
        file.write_mesh(mesh)
        file.write_meshtags(mt)
        file.write_meshtags(mt_lines)
        file.write_information("units", "mm")

    with XDMFFile(comm, filename, "r", encoding=encoding) as file:
        mesh_in = file.read_mesh()
        mesh_in.topology.create_connectivity_all()
        mt_in = file.read_meshtags(mesh_in, "facets")
        mt_lines_in = file.read_meshtags(mesh_in, "lines")
        units = file.read_information("units")
        assert units == "mm"
        assert mt_in.name == "facets"
        assert mt_lines_in.name == "lines"

    with XDMFFile(comm, os.path.join(tempdir, "meshtags_3d_out.xdmf"), "w", encoding=encoding) as file:
        file.write_mesh(mesh_in)
        file.write_meshtags(mt_lines_in)
        file.write_meshtags(mt_in)

    # Check number of owned and marked entities
    lines_local = comm.allreduce((mt_lines.indices < mesh.topology.index_map(1).size_local).sum(), op=MPI.SUM)
    lines_local_in = comm.allreduce(
        (mt_lines_in.indices < mesh_in.topology.index_map(1).size_local).sum(), op=MPI.SUM)

    assert lines_local == lines_local_in

    # Check that only owned data is written to file
    facets_local = comm.allreduce((mt.indices < mesh.topology.index_map(2).size_local).sum(), op=MPI.SUM)
    parser = ElementTree.XMLParser()
    tree = ElementTree.parse(os.path.join(tempdir, "meshtags_3d_out.xdmf"), parser)
    num_lines = int(tree.findall(".//Grid[@Name='lines']/Topology")[0].get("NumberOfElements"))
    num_facets = int(tree.findall(".//Grid[@Name='facets']/Topology")[0].get("NumberOfElements"))
    assert(num_lines == lines_local)
    assert(num_facets == facets_local)
Exemple #6
0
def plot_meshtags():
    # MeshTags and using subplots
    # ===========================

    mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, cell_type=CellType.quadrilateral)

    # We continue using the mesh from the previous section, and find all
    # cells satisfying the condition below

    def in_circle(x):
        """True for points inside circle with radius 2"""
        return np.array((x.T[0] - 0.5)**2 + (x.T[1] - 0.5)**2 < 0.2**2, dtype=np.int32)

    # Create a dolfinx.MeshTag for all cells. If midpoint is inside the
    # circle, it gets value 1, otherwise 0.
    num_cells = mesh.topology.index_map(mesh.topology.dim).size_local
    midpoints = compute_midpoints(mesh, mesh.topology.dim, list(np.arange(num_cells, dtype=np.int32)))
    cell_tags = MeshTags(mesh, mesh.topology.dim, np.arange(num_cells), in_circle(midpoints))

    cells, types, x = plot.create_vtk_mesh(mesh, mesh.topology.dim)
    grid = pyvista.UnstructuredGrid(cells, types, x)

    # As the dolfinx.MeshTag contains a value for every cell in the
    # geometry, we can attach it directly to the grid
    grid.cell_data["Marker"] = cell_tags.values
    grid.set_active_scalars("Marker")

    # We create a plotter consisting of two windows, and add a plot of the
    # Meshtags to the first window.
    subplotter = pyvista.Plotter(shape=(1, 2))
    subplotter.subplot(0, 0)
    subplotter.add_text("Mesh with markers", font_size=14, color="black", position="upper_edge")
    subplotter.add_mesh(grid, show_edges=True, show_scalar_bar=False)
    subplotter.view_xy()

    # We can also visualize subsets of data, by creating a smaller topology,
    # only consisting of those entities that has value one in the
    # dolfinx.MeshTag
    cells, types, x = plot.create_vtk_mesh(
        mesh, mesh.topology.dim, cell_tags.indices[cell_tags.values == 1])

    # We add this grid to the second plotter
    sub_grid = pyvista.UnstructuredGrid(cells, types, x)
    subplotter.subplot(0, 1)
    subplotter.add_text("Subset of mesh", font_size=14, color="black", position="upper_edge")
    subplotter.add_mesh(sub_grid, show_edges=True, edge_color="black")

    if pyvista.OFF_SCREEN:
        subplotter.screenshot("2D_markers.png", transparent_background=transparent,
                              window_size=[2 * figsize, figsize])
    else:
        subplotter.show()
Exemple #7
0
def merge_meshtags(mts, dim):
    """ Merge multiple MeshTags into one.

    Parameters
    ----------
    mts:
        List of meshtags
    dim:
        Dimension of MeshTags which should be merged. Note it is
        not possible to merge MeshTags with different dimensions into one
        MeshTags object.

    """
    mts = [(mt, name) for name, mt in mts.items() if mt.dim == dim]
    if len(mts) == 0:
        raise RuntimeError(f"Cannot find MeshTags of dimension {dim}")

    indices = numpy.hstack([mt.indices for mt, name in mts])
    values = numpy.hstack([mt.values for mt, name in mts])

    keys = {}
    for mt, name in mts:
        comm = mt.mesh.mpi_comm()
        # In some cases this process could receive a MeshTags which are empty
        # We need to return correct "keys" mapping on each process, so this
        # communicates the value from processes which don't have empty meshtags
        if len(mt.values) == 0:
            value = -1
        else:
            if numpy.max(mt.values) < 0:
                raise RuntimeError(
                    "Not expecting negative values for MeshTags")
            value = int(mt.values[0])
        value = comm.allreduce(value, op=MPI.MAX)

        keys[name] = value

    indices, pos = numpy.unique(indices, return_index=True)
    mt = MeshTags(mts[0][0].mesh, dim, indices, values[pos])

    return mt, keys
Exemple #8
0
def test_3d(tempdir, cell_type, encoding):
    filename = os.path.join(tempdir, "meshtags_3d.xdmf")
    comm = MPI.COMM_WORLD
    mesh = UnitCubeMesh(comm, 4, 4, 4, cell_type)

    bottom_facets = locate_entities(mesh, 2, lambda x: np.isclose(x[1], 0.0))
    bottom_values = np.full(bottom_facets.shape, 1, dtype=np.intc)
    left_facets = locate_entities(mesh, 2, lambda x: np.isclose(x[0], 0.0))
    left_values = np.full(left_facets.shape, 2, dtype=np.intc)

    indices, pos = np.unique(np.hstack((bottom_facets, left_facets)), return_index=True)
    mt = MeshTags(mesh, 2, indices, np.hstack((bottom_values, left_values))[pos])
    mt.name = "facets"

    top_lines = locate_entities(mesh, 1, lambda x: np.isclose(x[2], 1.0))
    top_values = np.full(top_lines.shape, 3, dtype=np.intc)
    right_lines = locate_entities(mesh, 1, lambda x: np.isclose(x[0], 1.0))
    right_values = np.full(right_lines.shape, 4, dtype=np.intc)

    indices, pos = np.unique(np.hstack((top_lines, right_lines)), return_index=True)
    mt_lines = MeshTags(mesh, 1, indices, np.hstack((top_values, right_values))[pos])
    mt_lines.name = "lines"

    with XDMFFile(comm, filename, "w", encoding=encoding) as file:
        mesh.topology.create_connectivity_all()
        file.write_mesh(mesh)
        file.write_meshtags(mt)
        file.write_meshtags(mt_lines)

    with XDMFFile(comm, filename, "r", encoding=encoding) as file:
        mesh_in = file.read_mesh()
        mesh_in.topology.create_connectivity_all()
        mt_in = file.read_meshtags(mesh_in, "facets")
        mt_lines_in = file.read_meshtags(mesh_in, "lines")
        assert mt_in.name == "facets"
        assert mt_lines_in.name == "lines"

    with XDMFFile(comm, os.path.join(tempdir, "meshtags_3d_out.xdmf"), "w", encoding=encoding) as file:
        file.write_mesh(mesh_in)
        file.write_meshtags(mt_lines_in)
        file.write_meshtags(mt_in)

    # Check number of owned and marked entities
    lines_local = comm.allreduce((mt_lines.indices < mesh.topology.index_map(1).size_local).sum(), op=MPI.SUM)
    lines_local_in = comm.allreduce(
        (mt_lines_in.indices < mesh_in.topology.index_map(1).size_local).sum(), op=MPI.SUM)

    assert lines_local == lines_local_in
Exemple #9
0
               [np.array([0.0, 0.0, 0.0]),
                np.array([xdim, ydim, zdim])], [Nx, Ny, Nz])


def right_side(x):
    return np.isclose(x[1], ydim)


def left_side(x):
    return np.isclose(x[1], 0.0)


left_side_facets = locate_entities_boundary(mesh, 2, left_side)
right_side_facets = locate_entities_boundary(mesh, 2, right_side)

mt = MeshTags(mesh, 2, right_side_facets, 1)

# External boundary facets
ds = ufl.Measure("ds", domain=mesh, subdomain_data=mt)
dx = ufl.Measure("dx", domain=mesh)

load_area = mesh.mpi_comm().allreduce(
    assemble_scalar(1.0 * ds(1, domain=mesh)), MPI.SUM)

if rank == 0:
    logger.info("Mesh hmin={} hmax={}".format(mesh.hmin(), mesh.hmax()))
    logger.info(f"Load area = {load_area}")

assert np.isclose(xdim * zdim, load_area)

w0, w1, intern_var0, intern_var1 = fecoda.main.initialize_functions(mesh)
u, v = ufl.TrialFunction(U), ufl.TestFunction(U)


def free_end(x):
    """Marks the leftmost points of the cantilever"""
    return np.isclose(x[0], 48.0)


def left(x):
    """Marks left part of boundary, where cantilever is attached to wall"""
    return np.isclose(x[0], 0.0)


# Locate all facets at the free end and assign them value 1
free_end_facets = locate_entities_boundary(mesh, 1, free_end)
mt = MeshTags(mesh, 1, free_end_facets, 1)

ds = ufl.Measure("ds", subdomain_data=mt)

# Homogeneous boundary condition in displacement
u_bc = Function(U)
u_bc.x.array[:] = 0.0

# Displacement BC is applied to the left side
left_facets = locate_entities_boundary(mesh, 1, left)
bdofs = locate_dofs_topological(U, 1, left_facets)
bc = dirichletbc(u_bc, bdofs)

# Elastic stiffness tensor and Poisson ratio
E, nu = 1.0, 1.0 / 3.0
Exemple #11
0

def bottom_left_corner(x):
    return np.logical_and(np.isclose(x[1], 0.0), np.isclose(x[2], zdim - 0.1))


def bottom_right_corner(x):
    return np.logical_and(np.isclose(x[1], 0.0), np.isclose(x[2], 0.1))


line_load_facets = locate_entities_boundary(mesh, 2, line_load)
bottom_left_lines = locate_entities_boundary(mesh, 1, bottom_left_corner)
bottom_right_lines = locate_entities_boundary(mesh, 1, bottom_right_corner)
top_load_facets = locate_entities_boundary(mesh, 2, top_load)

mt_line_load = MeshTags(mesh, 2, line_load_facets, 1)

# External boundary facets
ds = ufl.Measure("ds", domain=mesh, subdomain_data=mt_line_load)
dx = ufl.Measure("dx", domain=mesh, subdomain_data=mt_cell)

load_area = mesh.mpi_comm().allreduce(
    assemble_scalar(1.0 * ds(1, domain=mesh)), MPI.SUM)

if rank == 0:
    logger.info(f"[Timer] Mesh reading {time() - t0}")
    logger.info(f"Mesh hmin={mesh.hmin()} hmax={mesh.hmax()}")

w0, w1, intern_var0, intern_var1 = fecoda.main.initialize_functions(mesh)

# Beginning time for simulation
Exemple #12
0
def plot_higher_order():
    # Plotting higher order Functions
    # ===============================

    # In the previous sections we have considered degree 1 Lagrange spaces.
    # We can also plot higher degree functions.

    mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, cell_type=CellType.quadrilateral)

    # We continue using the mesh from the previous section, and find all
    # cells satisfying the condition below

    def in_circle(x):
        """Mark sphere with radius < sqrt(2)"""
        return np.array((x.T[0] - 0.5)**2 + (x.T[1] - 0.5)**2 < 0.2**2, dtype=np.int32)

    # Create a dolfinx.MeshTag for all cells. If midpoint is inside the
    # circle, it gets value 1, otherwise 0.
    num_cells = mesh.topology.index_map(mesh.topology.dim).size_local
    midpoints = compute_midpoints(mesh, mesh.topology.dim, list(np.arange(num_cells, dtype=np.int32)))
    cell_tags = MeshTags(mesh, mesh.topology.dim, np.arange(num_cells), in_circle(midpoints))

    # We start by interpolating a discontinuous function into a second order
    # discontinuous Lagrange  space Note that we use the `cell_tags` from
    # the previous section to get the cells for each of the regions
    cells0 = cell_tags.indices[cell_tags.values == 0]
    cells1 = cell_tags.indices[cell_tags.values == 1]
    V = FunctionSpace(mesh, ("Discontinuous Lagrange", 2))
    u = Function(V, dtype=np.float64)
    u.interpolate(lambda x: x[0], cells0)
    u.interpolate(lambda x: x[1] + 1, cells1)

    # To get a topology that has a 1-1 correspondence with the
    # degrees-of-freedom in the function space, we call
    # `dolfinx.plot.create_vtk_mesh`.
    cells, types, x = plot.create_vtk_mesh(V)

    # Create a pyvista mesh from the topology and geometry, and attach
    # the coefficients of the degrees of freedom
    grid = pyvista.UnstructuredGrid(cells, types, x)
    grid.point_data["u"] = u.x.array
    grid.set_active_scalars("u")

    # We would also like to visualize the underlying mesh and obtain
    # that as we have done previously
    num_cells = mesh.topology.index_map(mesh.topology.dim).size_local
    cell_entities = np.arange(num_cells, dtype=np.int32)
    cells, types, x = plot.create_vtk_mesh(mesh, mesh.topology.dim, cell_entities)
    org_grid = pyvista.UnstructuredGrid(cells, types, x)

    # We visualize the data
    plotter = pyvista.Plotter()
    plotter.add_text("Second-order (P2) discontinuous elements",
                     position="upper_edge", font_size=14, color="black")
    sargs = dict(height=0.1, width=0.8, vertical=False, position_x=0.1, position_y=0, color="black")
    plotter.add_mesh(grid, show_edges=False, scalar_bar_args=sargs, line_width=0)
    plotter.add_mesh(org_grid, color="white", style="wireframe", line_width=5)
    plotter.add_mesh(grid.copy(), style="points", point_size=15, render_points_as_spheres=True, line_width=0)
    plotter.view_xy()
    if pyvista.OFF_SCREEN:
        plotter.screenshot(f"DG_{MPI.COMM_WORLD.rank}.png",
                           transparent_background=transparent, window_size=[figsize, figsize])
    else:
        plotter.show()
def test_assembly_ds_domains(mode):
    mesh = create_unit_square(MPI.COMM_WORLD, 10, 10, ghost_mode=mode)
    V = FunctionSpace(mesh, ("Lagrange", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    def bottom(x):
        return np.isclose(x[1], 0.0)

    def top(x):
        return np.isclose(x[1], 1.0)

    def left(x):
        return np.isclose(x[0], 0.0)

    def right(x):
        return np.isclose(x[0], 1.0)

    bottom_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1,
                                             bottom)
    bottom_vals = np.full(bottom_facets.shape, 1, np.intc)

    top_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, top)
    top_vals = np.full(top_facets.shape, 2, np.intc)

    left_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, left)
    left_vals = np.full(left_facets.shape, 3, np.intc)

    right_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, right)
    right_vals = np.full(right_facets.shape, 6, np.intc)

    indices = np.hstack((bottom_facets, top_facets, left_facets, right_facets))
    values = np.hstack((bottom_vals, top_vals, left_vals, right_vals))

    indices, pos = np.unique(indices, return_index=True)
    marker = MeshTags(mesh, mesh.topology.dim - 1, indices, values[pos])

    ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh)

    w = Function(V)
    w.x.array[:] = 0.5

    bc = dirichletbc(Function(V), range(30))

    # Assemble matrix
    a = form(w * ufl.inner(u, v) * (ds(1) + ds(2) + ds(3) + ds(6)))
    A = assemble_matrix(a)
    A.assemble()
    norm1 = A.norm()
    a2 = form(w * ufl.inner(u, v) * ds)
    A2 = assemble_matrix(a2)
    A2.assemble()
    norm2 = A2.norm()
    assert norm1 == pytest.approx(norm2, 1.0e-12)

    # Assemble vector
    L = form(ufl.inner(w, v) * (ds(1) + ds(2) + ds(3) + ds(6)))
    b = assemble_vector(L)

    apply_lifting(b, [a], [[bc]])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                  mode=PETSc.ScatterMode.REVERSE)
    set_bc(b, [bc])

    L2 = form(ufl.inner(w, v) * ds)
    b2 = assemble_vector(L2)
    apply_lifting(b2, [a2], [[bc]])
    b2.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                   mode=PETSc.ScatterMode.REVERSE)
    set_bc(b2, [bc])

    assert b.norm() == pytest.approx(b2.norm(), 1.0e-12)

    # Assemble scalar
    L = form(w * (ds(1) + ds(2) + ds(3) + ds(6)))
    s = assemble_scalar(L)
    s = mesh.comm.allreduce(s, op=MPI.SUM)
    L2 = form(w * ds)
    s2 = assemble_scalar(L2)
    s2 = mesh.comm.allreduce(s2, op=MPI.SUM)
    assert (s == pytest.approx(s2, 1.0e-12)
            and 2.0 == pytest.approx(s, 1.0e-12))
Exemple #14
0
def top_load(x):
    return np.isclose(x[1], ydim)


left_support_lines = locate_entities_boundary(mesh, 1, left_support)
right_support_lines = locate_entities_boundary(mesh, 1, right_support)
top_load_facets = locate_entities_boundary(mesh, 2, top_load)
replaced_part_cells = locate_entities(
    mesh, 3, lambda x: np.greater_equal(x[2], zdim - alpha * zdim))
replaced_part_interface = locate_entities(
    mesh, 2, lambda x: np.isclose(x[2], zdim - alpha * zdim))
right_side_facets = locate_entities_boundary(mesh, 2,
                                             lambda x: np.isclose(x[2], zdim))

mt_top_load = MeshTags(mesh, 2, top_load_facets, 1)

# External boundary facets
ds = ufl.Measure("ds",
                 domain=mesh,
                 subdomain_data=mt_top_load,
                 metadata={"quadrature_degree": 2})
dx = ufl.Measure("dx",
                 domain=mesh,
                 subdomain_data=mt_cell,
                 metadata={"quadrature_degree": 6})

load_area = mesh.mpi_comm().allreduce(
    assemble_scalar(1.0 * ds(1, domain=mesh)), MPI.SUM)

if rank == 0: