Example #1
0
def solve_system(N):
    fenics_mesh = dolfinx.UnitCubeMesh(fenicsx_comm, N, N, N)
    fenics_space = dolfinx.FunctionSpace(fenics_mesh, ("CG", 1))
    u = ufl.TrialFunction(fenics_space)
    v = ufl.TestFunction(fenics_space)
    k = 2
    # print(u*v*ufl.ds)
    form = (ufl.inner(ufl.grad(u), ufl.grad(v)) -
            k**2 * ufl.inner(u, v)) * ufl.dx

    # locate facets on the cube boundary
    facets = locate_entities_boundary(
        fenics_mesh, 2, lambda x: np.logical_or(
            np.logical_or(
                np.logical_or(np.isclose(x[2], 0.0), np.isclose(x[2], 1.0)),
                np.logical_or(np.isclose(x[1], 0.0), np.isclose(x[1], 1.0))),
            np.logical_or(np.isclose(x[0], 0.0), np.isclose(x[0], 1.0))))

    facets.sort()

    # alternative - more general approach
    boundary = entities_to_geometry(
        fenics_mesh,
        fenics_mesh.topology.dim - 1,
        exterior_facet_indices(fenics_mesh),
        True,
    )
    # print(len(facets)
    assert len(facets) == len(exterior_facet_indices(fenics_mesh))

    u0 = fem.Function(fenics_space)

    with u0.vector.localForm() as u0_loc:
        u0_loc.set(0)
    # solution vector
    bc = DirichletBC(u0, locate_dofs_topological(fenics_space, 2, facets))

    A = 1 + 1j
    f = Function(fenics_space)
    f.interpolate(lambda x: A * k**2 * np.cos(k * x[0]) * np.cos(k * x[1]))

    L = ufl.inner(f, v) * ufl.dx
    u0.name = "u"
    problem = fem.LinearProblem(form,
                                L,
                                u=u0,
                                petsc_options={
                                    "ksp_type": "preonly",
                                    "pc_type": "lu"
                                })
    # problem = fem.LinearProblem(form, L, bcs=[bc], u=u0, petsc_options={"ksp_type": "preonly", "pc_type": "lu"})

    start_time = time.time()
    soln = problem.solve()
    if world_rank == 0:
        print("--- fenics solve done in %s seconds ---" %
              (time.time() - start_time))
Example #2
0
def boundary_grid_from_fenics_mesh(fenics_mesh):
    """
    Create a Bempp boundary grid from a FEniCS Mesh.

    Return the Bempp grid and a map from the node numberings of the FEniCS
    mesh to the node numbers of the boundary grid.
    """
    import bempp.api
    import numpy as np
    from dolfinx.cpp.mesh import entities_to_geometry, exterior_facet_indices

    boundary = entities_to_geometry(
        fenics_mesh,
        fenics_mesh.topology.dim - 1,
        exterior_facet_indices(fenics_mesh),
        True,
    )

    bm_nodes = set()
    for tri in boundary:
        for node in tri:
            bm_nodes.add(node)
    bm_nodes = list(bm_nodes)
    bm_cells = np.array([[bm_nodes.index(i) for i in tri] for tri in boundary])
    bm_coords = fenics_mesh.geometry.x[bm_nodes]

    bempp_boundary_grid = bempp.api.Grid(bm_coords.transpose(),
                                         bm_cells.transpose())

    return bempp_boundary_grid, bm_nodes
Example #3
0
def bm_from_fenics_mesh(fenics_mesh):
    boundary = entities_to_geometry(
        fenics_mesh,
        fenics_mesh.topology.dim - 1,
        exterior_facet_indices(fenics_mesh),
        True,
    )

    # print("number of facets ", len(exterior_facet_indices(fenics_mesh)))
    bm_nodes = set()
    for tri in boundary:
        for node in tri:
            bm_nodes.add(node)
    bm_nodes = list(bm_nodes)
    # bm_cells - remap cell indices between 0-len(bm_nodes)
    bm_cells = np.array([[bm_nodes.index(i) for i in tri] for tri in boundary])
    bm_coords = fenics_mesh.geometry.x[bm_nodes]

    # print(boundary)
    # print("fenics mesh dofs\n", fm_dofs)
    # # print("type of bm_coords ", type(bm_nodes), len(bm_nodes))
    # print('shape bm_cells ', bm_cells.shape)
    # print('type bm_cells ', type(bm_cells))
    # print('bm_cells \n', bm_cells)
    # print('bm_nodes \n', bm_nodes)
    return bm_nodes, bm_cells, bm_coords
Example #4
0
def get_num_bdry_verts(fenics_mesh):
    num_fenics_vertices = fenics_mesh.topology.connectivity(0, 0).num_nodes
    fenics_mesh.topology.create_connectivity(2, 0)
    tris = fenics_mesh.topology.connectivity(2, 0)
    local2global_nodes = fenics_mesh.topology.index_map(0).global_indices(
        False)

    exterior_facets = exterior_facet_indices(fenics_mesh)
    exterior_nodes = set()

    for i in exterior_facets:
        for j in tris.links(i):
            exterior_nodes.add(local2global_nodes[j])
    root = 0
    rank = comm.Get_rank()

    ghosts = fenics_mesh.topology.index_map(0).ghosts
    ghost_owner = fenics_mesh.topology.index_map(0).ghost_owner_rank()
    all_global = fenics_mesh.topology.index_map(0).global_indices(False)
    all_indices = fenics_mesh.topology.index_map(0).indices(False)
    # print(sendbuf_vertices)
    ownership = np.ones_like(list(exterior_nodes), dtype=np.int32) * comm.rank
    ext_nodes_list = list(exterior_nodes)
    ghosts_list = list(ghosts)
    for i in range(len(ext_nodes_list)):
        if ext_nodes_list[i] in ghosts_list:
            index = ghosts_list.index(ext_nodes_list[i])
            ownership[i] = ghost_owner[index]
    # print(np.sum(ownership == rank))
    # print(sendbuf_vertices[ownership == rank])
    # print("\n")
    # print("exterior nodes length (global)", len(exterior_nodes))
    sendbuf_vertices = np.asarray(list(exterior_nodes), dtype=np.int64)
    print("ownership ", ownership)
    print("external nodes from exterior_facet_indices ", ext_nodes_list)
    print("size local ", fenics_mesh.topology.index_map(0).size_local)
    print("all indices ", all_indices)
    print("RANK {} \n".format(rank))
    sendbuf_vertices = sendbuf_vertices[ownership == rank]
    # print(sum(sendbuf_vertices))
    sendcounts = np.array(comm.gather(len(sendbuf_vertices), root))
    # print("ghosts", fenics_mesh.topology.index_map(0).ghosts)
    # print("ghost owner rank ", fenics_mesh.topology.index_map(0).ghost_owner_rank())

    print("sendcounts ", sendcounts)
    if rank == root:
        # print("sendcounts: {}, total: {}".format(sendcounts, sum(sendcounts)))
        recvbuf = np.empty(sum(sendcounts), dtype=np.int64)
    else:
        recvbuf = None

    comm.Gatherv(sendbuf=sendbuf_vertices,
                 recvbuf=(recvbuf, sendcounts),
                 root=root)
    if rank == root:
        bdry_vertices = sorted(np.unique(recvbuf))
        # print("Gathered array: {}, unique length: {}".format(bdry_vertices, len(bdry_vertices)))
        # print("unique length: {}".format(len(bdry_vertices)))
        return len(bdry_vertices)
    return 0
def test_mpi():
    N = 2
    comm = MPI.COMM_WORLD
    world_rank = comm.Get_rank()
    world_size = comm.Get_size()
    print("world rank ", world_rank)
    if world_rank == 1:
        print(MPI.COMM_SELF)
        fenics_mesh = dolfinx.UnitCubeMesh(MPI.COMM_SELF, N, N, N)
        facet_indices = exterior_facet_indices(fenics_mesh)
        print(facet_indices)
def bm_from_fenics_mesh_mpi(fenics_mesh, fenics_space):
    boundary = entities_to_geometry(
        fenics_mesh,
        fenics_mesh.topology.dim - 1,
        exterior_facet_indices(fenics_mesh),
        True,
    )

    dofmap = fenics_space.dofmap.index_map.global_indices(False)
    geom_map = fenics_mesh.geometry.index_map().global_indices(False)
    dofmap_mesh = fenics_mesh.geometry.dofmap

    assert dofmap == geom_map
    # print("dofmap ", dofmap)
    # print("geometry map ", geom_map)
    # print("dofmap mesh", dofmap_mesh)
    # print("number of facets ", len(exterior_facet_indices(fenics_mesh)))
    bm_nodes = set()
    for i, tri in enumerate(boundary):
        for j, node in enumerate(tri):
            # print(node, boundary[i][j])
            glob_geom_node = geom_map[node]
            boundary[i][j] = glob_geom_node
            bm_nodes.add(node)

    bm_nodes_global = [geom_map[i] for i in bm_nodes]
    bm_nodes = list(bm_nodes)
    bm_coords = fenics_mesh.geometry.x[bm_nodes]
    # bm_cells - remap cell indices between 0-len(bm_nodes)
    # bm_cells = np.array([[bm_nodes.index(i) for i in tri] for tri in boundary])
    # print("bm_coords\n", bm_coords)
    # print("bm_nodes\n", bm_nodes)
    # print("boundary\n", boundary)
    # # print("type of bm_coords ", type(bm_nodes), len(bm_nodes))
    # print('shape bm_cells ', bm_cells.shape)
    # print('type bm_cells ', type(bm_cells))
    # print('bm_cells \n', bm_cells)

    # print("dofmap ", fenics_mesh.geometry.dofmap)
    return bm_nodes_global, bm_coords, boundary
Example #7
0
def create_boundary_mesh(mesh, comm, orient=False):
    """
    Create a mesh consisting of all exterior facets of a mesh
    Input:
      mesh   - The mesh
      comm   - The MPI communicator
      orient - Boolean flag for reorientation of facets to have
               consistent outwards-pointing normal (default: True)
    Output:
      bmesh - The boundary mesh
      bmesh_to_geometry - Map from cells of the boundary mesh
                          to the geometry of the original mesh
    """
    ext_facets = cmesh.exterior_facet_indices(mesh)
    boundary_geometry = cmesh.entities_to_geometry(mesh, mesh.topology.dim - 1,
                                                   ext_facets, orient)
    facet_type = dolfinx.cpp.mesh.to_string(
        cmesh.cell_entity_type(mesh.topology.cell_type, mesh.topology.dim - 1))
    facet_cell = ufl.Cell(facet_type, geometric_dimension=mesh.geometry.dim)
    degree = mesh.ufl_domain().ufl_coordinate_element().degree()
    ufl_domain = ufl.Mesh(ufl.VectorElement("Lagrange", facet_cell, degree))
    bmesh = dolfinx.mesh.create_mesh(comm, boundary_geometry, mesh.geometry.x,
                                     ufl_domain)
    return bmesh, boundary_geometry
Example #8
0
tris = mesh.topology.connectivity(2, 0)
mesh.topology.create_connectivity(2, 3)
tri_to_tet = mesh.topology.connectivity(2, 3)

surface_tris = []
for i in range(tris.num_nodes):
    if (len(tri_to_tet.links(i)) == 1):
        surface_tris += [i]
surface_tris = np.array(surface_tris)
len(surface_tris)
print("Surface tris done")

triangles = surface_tris
# print(surface_tris)

facets = exterior_facet_indices(mesh)
# print('facets ', facets)

# now apply boundary conditions
V = FunctionSpace(mesh, ("Lagrange", 1))
u0 = Function(V)
u0.vector.set(0.0)

bc = DirichletBC(u0, locate_dofs_topological(V, 2, facets))

# Define variational problem
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
x = ufl.SpatialCoordinate(mesh)
f = 10 * ufl.exp(-((x[0] - 30)**2 + (x[1] + 50)**2) / 200)
g = ufl.sin(5 * x[0])
Example #9
0
def get_num_bdry_dofs(fenics_mesh):
    exterior_facets = exterior_facet_indices(fenics_mesh)
    boundary = entities_to_geometry(
        fenics_mesh,
        fenics_mesh.topology.dim - 1,
        exterior_facet_indices(fenics_mesh),
        True,
    )
    bm_nodes = set()
    fenics_space = dolfinx.FunctionSpace(fenics_mesh, ("CG", 1))
    global_dofs_map = fenics_space.dofmap.index_map.global_indices(False)

    # print(fenics_space.dofmap.index_map.ghosts)
    mapping, dof_map = vertex_dofmap(fenics_mesh)
    # value of 9
    vertex_err_val = 9

    if vertex_err_val in mapping.keys():
        print("value of corresponding dof is ", mapping[9])

    for i, tri in enumerate(boundary):
        for j, node in enumerate(tri):
            # print(node, boundary[i][j])
            glob_geom_node = global_dofs_map[node]
            # glob_geom_node = geom_map[node]
            boundary[i][j] = glob_geom_node
            bm_nodes.add(node)
    bm_nodes_global = [global_dofs_map[i] for i in bm_nodes]
    ghosts = fenics_space.dofmap.index_map.ghosts
    ghosts_list = list(ghosts)
    ghost_owner = fenics_space.dofmap.index_map.ghost_owner_rank()
    ownership = np.ones_like(bm_nodes_global, dtype=np.int32) * comm.rank
    for i in range(len(bm_nodes_global)):
        if bm_nodes_global[i] in ghosts_list:
            index = ghosts_list.index(bm_nodes_global[i])
            ownership[i] = ghost_owner[index]

    print(ownership)
    print(bm_nodes_global)
    print("RANK {} \n".format(comm.Get_rank()))
    root = 0
    rank = comm.Get_rank()
    sendbuf = np.array(bm_nodes_global)
    # print("sendbuf ", sendbuf)
    sendcounts = np.array(comm.gather(len(sendbuf), root))

    print("sendcounts ", sendcounts)

    if rank == root:
        print("sendcounts: {}, total: {}".format(sendcounts, sum(sendcounts)))
        recvbuf = np.empty(sum(sendcounts), dtype=np.int64)
    else:
        recvbuf = None

    comm.Gatherv(sendbuf=sendbuf, recvbuf=(recvbuf, sendcounts), root=root)
    if rank == root:
        bm_nodes_unique = sorted(np.unique(recvbuf))
        print("Gathered array: {}, unique length: {}".format(
            bm_nodes_unique, len(bm_nodes_unique)))
        return len(bm_nodes_unique)
    return 0
Example #10
0
def play(fenics_mesh):
    exterior_facets = exterior_facet_indices(fenics_mesh)
    num_fenics_vertices = fenics_mesh.topology.connectivity(0, 0).num_nodes
    tets = fenics_mesh.topology.connectivity(3, 0)
    fenics_mesh.topology.create_connectivity(2, 0)
    tris = fenics_mesh.topology.connectivity(2, 0)
    fenics_mesh.topology.create_connectivity(2, 3)
    tri_to_tet = fenics_mesh.topology.connectivity(2, 3)
    exterior_nodes = set()
    local2global_nodes = fenics_mesh.topology.index_map(0).global_indices(
        False)

    # from exterior facets get all nodes (global) on bdry
    # is the bdry triangle index the same as in tris?
    for i in exterior_facets:
        for j in tris.links(i):
            exterior_nodes.add(local2global_nodes[j])

    # print("ghost owner rank ", fenics_mesh.topology.index_map(0))
    # print("index_map ", dir(fenics_mesh.topology.index_map(0)))
    ghosts = fenics_mesh.topology.index_map(0).ghosts
    # print("l2g ", local2global_nodes)
    # ghosts_global = [i for i in ghosts]
    print("ghosts", fenics_mesh.topology.index_map(0).ghosts)
    # print("ghosts_global", fenics_mesh.topology.index_map(0).ghosts)
    print("ghost owner rank ",
          fenics_mesh.topology.index_map(0).ghost_owner_rank())
    print("all global indices on this process",
          fenics_mesh.topology.index_map(0).indices(True))
    # print(dir(fenics_mesh.topology.index_map(0)))
    size_local = fenics_mesh.topology.index_map(0).size_local
    size_global = fenics_mesh.topology.index_map(0).size_global
    # shared = fenics_mesh.topology.index_map(0).shared_indices
    print("size local ", size_local, " size global ", size_global)
    print("exterior nodes (global)", exterior_nodes)
    print("exterior nodes length (global)", len(exterior_nodes))
    sendbuf_nodes = np.asarray(list(exterior_nodes), dtype=np.int64)
    print("length of sendbuf ", len(sendbuf_nodes))
    # print("exterior facets ", exterior_facets)
    # print("exterior facet 0", [ local2global_nodes[i] for i in tris.links(0)])
    print("RANK ", comm.Get_rank())
    # print(local2global_nodes)
    boundary = entities_to_geometry(
        fenics_mesh,
        fenics_mesh.topology.dim - 1,
        exterior_facet_indices(fenics_mesh),
        True,
    )
    bm_nodes = set()
    # this map is wrong:
    geom_map = fenics_mesh.geometry.index_map().global_indices(False)
    # use this instead:
    fenics_space = dolfinx.FunctionSpace(fenics_mesh, ("CG", 1))
    global_dofs_map = fenics_space.dofmap.index_map.global_indices(False)
    mapping_space = space_dofmap(fenics_mesh, fenics_space)
    # print("mapping space ", mapping_space)
    # print(mapping)
    exterior_dofs = []
    for i in exterior_nodes:
        exterior_dofs.append(mapping_space[i])

    print("exterior dofs from vertices", exterior_dofs)
    for i, tri in enumerate(boundary):
        for j, node in enumerate(tri):
            # print(node, boundary[i][j])
            glob_geom_node = global_dofs_map[node]
            # glob_geom_node = geom_map[node]
            boundary[i][j] = glob_geom_node
            bm_nodes.add(node)
    bm_nodes_global = [geom_map[i] for i in bm_nodes]
    print("bm nodes ", bm_nodes_global)
    mapping, dof_map = vertex_dofmap(fenics_mesh)
    # print("geom nodes     ", bm_nodes_global)
    # print(exterior_facets)
    # get mapping between dofs and vertices
    mesh_dofmap = fenics_mesh.geometry.dofmap
    # mapping = vertex_dofmap(fenics_mesh)
    # print(mapping[13])
    mesh_dofs = []
    for i in exterior_nodes:
        # print(i)
        mesh_dofs.append(mapping[i])
    # print("mapping     ", mapping)
    # print("dof_map     ", dof_map)
    ma = [dof_map[i] for i in bm_nodes_global]
    print(ma)
    print("\n")

    # print("bm_nodes global ", sorted(bm_nodes_global))

    print("do a gather")

    recvbuf_nodes = None
    if comm.rank == 0:
        info = MPI.Status()
        recvbuf_nodes = np.empty(comm.Get_size() * len(exterior_nodes),
                                 dtype=np.int64)
    comm.Gather(sendbuf_nodes, recvbuf_nodes, root=0)

    print("received nodes ", len(np.unique(recvbuf_nodes)))
    exit(0)
Example #11
0
def bm_from_fenics_mesh(comm, fenics_comm, fenics_mesh, fenics_space):
    """
    Create a Bempp boundary grid from a FEniCS Mesh.
    Return the Bempp grid and a map from the node numberings of the FEniCS
    mesh to the node numbers of the boundary grid.
    """
    from dolfinx.cpp.mesh import entities_to_geometry, exterior_facet_indices

    boundary = entities_to_geometry(
        fenics_mesh,
        fenics_mesh.topology.dim - 1,
        exterior_facet_indices(fenics_mesh),
        True,
    )

    dofmap = fenics_space.dofmap.index_map.global_indices(False)
    geom_map = fenics_mesh.geometry.index_map().global_indices(False)
    dofmap_mesh = fenics_mesh.geometry.dofmap

    # assert dofmap == geom_map
    # print("number of facets ", len(exterior_facet_indices(fenics_mesh)))
    bm_nodes = set()
    for i, tri in enumerate(boundary):
        for j, node in enumerate(tri):
            # print(node, boundary[i][j])
            glob_dof_node = dofmap[node]
            boundary[i][j] = glob_dof_node
            bm_nodes.add(node)

    bm_nodes_global = [dofmap[i] for i in bm_nodes]
    bm_nodes = list(bm_nodes)
    bm_coords = fenics_mesh.geometry.x[bm_nodes]
    # bm_cells - remap cell indices between 0-len(bm_nodes)
    # bm_cells = np.array([[bm_nodes.index(i) for i in tri] for tri in boundary])
    # print('shape bm_cells ', bm_cells.shape)
    # print('bm_cells \n', bm_cells)
    # print('bm_coords len ', len(bm_coords))
    # print('bm_coords type ', type(bm_coords[0][0]))
    # print("RANK ", fenics_comm.rank)
    gathered_bm_coords = gather(fenics_comm, bm_coords, 3, np.float64)
    gathered_bm_tris = gather(fenics_comm, boundary, 3, np.int32)
    gathered_bm_nodes = gather(fenics_comm,
                               np.asarray(bm_nodes_global, np.int32), 1,
                               np.int32)

    global_alldofs = np.asarray(
        fenics_space.dofmap.index_map.global_indices(False), dtype=np.int32)
    gathered_global_alldofs = gather(fenics_comm, global_alldofs, 1, np.int32)

    if fenics_comm.rank == 0:
        all_bm_coords = gathered_bm_coords.reshape(
            int(len(gathered_bm_coords) / 3), 3)
        all_bm_tris = gathered_bm_tris.reshape(int(len(gathered_bm_tris) / 3),
                                               3)
        all_bm_nodes = gathered_bm_nodes

        # sort gathered nodes and remove repetitions (ghosts on bdry)
        sorted_indices = all_bm_nodes.argsort()
        all_bm_nodes_sorted = all_bm_nodes[sorted_indices]
        all_bm_coords_sorted = all_bm_coords[sorted_indices]
        # print("sorted indices, ", sorted_indices)
        all_bm_nodes, unique = np.unique(all_bm_nodes_sorted,
                                         return_index=True)
        all_bm_coords = all_bm_coords_sorted[unique]
        all_bm_nodes_list = list(all_bm_nodes)
        # bm_cells - remap boundary triangle indices between 0-len(bm_nodes) - this can be improved
        all_bm_cells = np.array([[all_bm_nodes_list.index(i) for i in tri]
                                 for tri in all_bm_tris],
                                dtype=np.int32)
        all_bm_nodes = np.asarray(all_bm_nodes_list, dtype=np.int32)
        # send to Bempp process
        send(comm, all_bm_coords, MPI.DOUBLE, 100)
        send(comm, all_bm_cells, MPI.INT, 101)
        send(comm, all_bm_nodes, MPI.INT, 102)
        # print("all_bm_cells ", type(all_bm_cells))

        num_fenics_vertices = len(np.unique(np.sort(gathered_global_alldofs)))

        # hack - to change
        comm.send(num_fenics_vertices, dest=0, tag=103)