Ejemplo n.º 1
0
def mesh_diameter(mesh):
    # FIXME: Quadratic algorithm is too slow!
    """Return mesh diameter, i.e. \sup_{x,y \in mesh} |x-y|. Algorithm
    loops quadratically over boundary facets."""

    not_working_in_parallel("Function 'mesh_diameter'")
    assert mesh.topology().dim() == mesh.geometry().dim(), \
            "Function 'mesh_diameter' not working on manifolds."

    tdim = mesh.topology().dim()
    mesh.init(tdim-1, tdim)

    diameter = 0.0

    for f0 in facets(mesh):
        if not f0.exterior():
            continue

        for f1 in facets(mesh):
            if not f1.exterior():
                continue

            for v0 in vertices(f0):
                for v1 in vertices(f1):
                    diameter = max(diameter, v0.point().distance(v1.point()))

    return diameter
Ejemplo n.º 2
0
def mesh_fixup(mesh):
    """Refine cells which have all vertices on boundary and
    return a new mesh."""
    cf = CellFunction('bool', mesh)

    tdim = mesh.topology().dim()
    mesh.init(tdim-1, tdim)

    for f in facets(mesh):
        # Boundary facet?
        # TODO: Here we could check supplied facet function or subdomain
        if not f.exterior():
            continue

        # Pick adjacent cell
        c = Cell(mesh, f.entities(tdim)[0])

        # Number of vertices on boundary
        num_bad_vertices = sum(1 for v in vertices(c)
                               if any(fv.exterior() for fv in facets(v)))
        assert num_bad_vertices <= c.num_vertices()

        # Refine cell if all vertices are on boundary
        if num_bad_vertices == c.num_vertices():
            cf[c] = True

    return refine(mesh, cf)
Ejemplo n.º 3
0
def get_long_field(mesh, mesh_type="biv"):

    fiber_params = setup_fiber_parameters()
    fiber_params["fiber_angle_endo"] = -90
    fiber_params["fiber_angle_epi"] = -90

    if mesh_type == "biv":
        # We need to set the markers for then LV and RV facets
        ffun = dolfin.MeshFunction("size_t", mesh, 2, mesh.domains())

        markers = get_fiber_markers("biv")
        # Mark the mesh with same markers on the LV and RV before
        # running the LDRB algorithm
        markers["ENDO_RV"] = markers["ENDO_LV"]
        for facet in dolfin.facets(mesh):
            if ffun[facet] != 0:
                mesh.domains().set_marker(
                    (facet.index(), markers[ffun[facet]]), 2)

    f0 = generate_fibers(mesh, fiber_params)[0]
    f0.rename("longitudinal", "local_basis_function")

    if mesh_type == "biv":
        # Put the correct markers
        markers = get_fiber_markers("biv")
        for facet in dolfin.facets(mesh):
            if ffun[facet] != 0:
                mesh.domains().set_marker(
                    (facet.index(), markers[ffun[facet]]), 2)
    return f0
Ejemplo n.º 4
0
    def create_measures(self):

        for rom_cell_counter, rom_cell in enumerate(df.cells(
                self._mesh_coarse)):

            form = FluxForm(df.Function(self._V), df.Function(self._Vc))
            facetfct = df.MeshFunction('size_t', self._mesh_fine,
                                       self._mesh_fine.topology().dim() - 1)
            facetfct.set_all(0)

            for local_facet_id, rom_facet in enumerate(df.facets(rom_cell)):
                for fom_facet in df.facets(self._mesh_fine):

                    mp = fom_facet.midpoint()

                    p0 = df.Vertex(self._mesh_coarse, rom_facet.entities(0)[0])
                    p1 = df.Vertex(self._mesh_coarse, rom_facet.entities(0)[1])
                    p0 = df.Point(np.array([p0.x(0), p0.x(1)]))
                    p1 = df.Point(np.array([p1.x(0), p1.x(1)]))

                    eps = mp.distance(p0) + mp.distance(p1) - p0.distance(p1)

                    if eps < 1e-12:

                        facetfct.set_value(fom_facet.index(),
                                           local_facet_id + 1)

                if self._rom_exterior_facets[rom_facet.index()]:
                    form.append_ds(
                        df.Measure('ds',
                                   domain=self._mesh_fine,
                                   subdomain_data=facetfct,
                                   subdomain_id=local_facet_id + 1))
                else:
                    form.append_dS(
                        df.Measure('dS',
                                   domain=self._mesh_fine,
                                   subdomain_data=facetfct,
                                   subdomain_id=local_facet_id + 1))

            cellfct = df.MeshFunction('size_t', self._mesh_fine,
                                      self._mesh_fine.topology().dim())
            cellfct.set_all(0)

            for fom_cell in df.cells(self._mesh_fine):
                if rom_cell.contains(fom_cell.midpoint()):
                    cellfct.set_value(fom_cell.index(), 1)

            form.append_dx(
                df.Measure('dx',
                           domain=self._mesh_fine,
                           subdomain_data=cellfct,
                           subdomain_id=1))
            self._flux_forms.append(form)

        self._initialized = True
Ejemplo n.º 5
0
def mesh2d(inner, outer, *meshres, stefan=True):
    origin = dolfin.Point(0., 0.)
    if stefan:
        geometry = mshr.Circle(origin, outer, 2 * meshres[0]) - mshr.Circle(
            origin, inner, int(0.5 * meshres[0]))
        mesh = mshr.generate_mesh(geometry, meshres[0])
        mesh.init()
        # Construct of the facet markers:
        boundary = (dolfin.MeshFunction("size_t", mesh,
                                        mesh.topology().dim() - 1, 0), {})
        for f in dolfin.facets(mesh):
            if f.midpoint().distance(origin) <= inner and f.exterior():
                boundary[0][f] = 1  # inner radius
                boundary[1]['inner'] = 1
            elif f.midpoint().distance(origin) >= (inner +
                                                   outer) / 2 and f.exterior():
                boundary[0][f] = 2  # outer radius
                boundary[1]['outer'] = 2
        # Definition of measures and normal vector:
        n = dolfin.FacetNormal(mesh)
        dx = dolfin.Measure("dx", mesh)
        ds = dolfin.Measure("ds", domain=mesh, subdomain_data=boundary[0])
    else:
        width = inner
        height = outer
        mesh = dolfin.RectangleMesh(origin, Point(width, height), meshres[0],
                                    meshres[1])
        mesh.init()
        boundary = (dolfin.MeshFunction("size_t", mesh,
                                        mesh.topology().dim() - 1, 0), {})
        for f in dolfin.facets(mesh):
            if dolfin.near(f.midpoint()[1], 0.):
                boundary[0][f] = 1  # bottom
                boundary[1]['bottom'] = 1
            elif dolfin.near(f.midpoint()[1], height):
                boundary[0][f] = 2  # top
                boundary[1]['top'] = 2
            elif dolfin.near(f.midpoint()[0], 0.):
                boundary[0][f] = 3  # left
                boundary[1]['left'] = 3
            elif dolfin.near(f.midpoint()[0], width):
                boundary[0][f] = 4  # right
                boundary[1]['right'] = 4
        # Definition of measures and normal vector:
        n = dolfin.FacetNormal(mesh)
        dx = dolfin.Measure("dx", mesh)
        ds = dolfin.Measure("ds", subdomain_data=boundary[0])
    return (mesh, boundary, n, dx, ds)
Ejemplo n.º 6
0
def facet_to_dof_map(V):
    '''facet index -> DLT0 dofs'''
    assert V.ufl_element().family() == 'HDiv Trace'
    assert V.ufl_element().degree() == 0
    assert V.ufl_element().value_shape() == ()

    dm = V.dofmap()

    mesh = V.mesh()
    cdim = mesh.topology().dim()
    fdim = cdim - 1
    mesh.init(fdim, cdim)
    mesh.init(cdim, fdim)

    c2f = mesh.topology()(cdim, fdim)
    mapping = np.zeros(mesh.num_entities(fdim), dtype='uintp')
    for f in facets(mesh):
        c = f.entities(cdim)[0]
        cell_dofs = dm.cell_dofs(c)

        fid = f.index()
        dof = cell_dofs[c2f(c).tolist().index(fid)]
        mapping[fid] = dof

    return mapping
Ejemplo n.º 7
0
def convert_meshfunctions_to_submesh(mesh, submesh, meshfunctions_on_mesh):
    assert meshfunctions_on_mesh is None or (isinstance(
        meshfunctions_on_mesh, list) and len(meshfunctions_on_mesh) > 0)
    if meshfunctions_on_mesh is None:
        return None
    meshfunctions_on_submesh = list()
    # Create submesh subdomains
    for mesh_subdomain in meshfunctions_on_mesh:
        submesh_subdomain = MeshFunction("size_t", submesh,
                                         mesh_subdomain.dim())
        submesh_subdomain.set_all(0)
        assert submesh_subdomain.dim() in (submesh.topology().dim(),
                                           submesh.topology().dim() - 1)
        if submesh_subdomain.dim() == submesh.topology().dim():
            for submesh_cell in cells(submesh):
                submesh_subdomain.array()[
                    submesh_cell.index()] = mesh_subdomain.array()[
                        submesh.submesh_to_mesh_cell_local_indices[
                            submesh_cell.index()]]
        elif submesh_subdomain.dim() == submesh.topology().dim() - 1:
            for submesh_facet in facets(submesh):
                submesh_subdomain.array()[
                    submesh_facet.index()] = mesh_subdomain.array()[
                        submesh.submesh_to_mesh_facet_local_indices[
                            submesh_facet.index()]]
        else:  # impossible to arrive here anyway, thanks to the assert
            raise TypeError(
                "Invalid arguments in convert_meshfunctions_to_submesh.")
        meshfunctions_on_submesh.append(submesh_subdomain)
    return meshfunctions_on_submesh
Ejemplo n.º 8
0
def mesh3d(width, depth, height, nx, ny, nz):
    mesh = dolfin.BoxMesh(Point(0., 0., 0.), Point(width, depth, height), nx,
                          ny, nz)
    boundary = (dolfin.MeshFunction("size_t", mesh,
                                    mesh.topology().dim() - 1, 0), {})
    for f in dolfin.facets(mesh):
        if dolfin.near(f.midpoint()[2], 0.):
            boundary[0][f] = 1  # bottom
            boundary[1]['bottom'] = 1
        elif dolfin.near(f.midpoint()[2], height):
            boundary[0][f] = 2  # top
            boundary[1]['top'] = 2
        elif dolfin.near(f.midpoint()[0], 0.):
            boundary[0][f] = 3  # left
            boundary[1]['left'] = 3
        elif dolfin.near(f.midpoint()[0], width):
            boundary[0][f] = 4  # right
            boundary[1]['right'] = 4
        elif dolfin.near(f.midpoint()[1], 0):
            boundary[0][f] = 5  # front
            boundary[1]['front'] = 5
        elif dolfin.near(f.midpoint()[1], depth):
            boundary[0][f] = 6  # back
            boundary[1]['back'] = 6
    # Definition of measures and normal vector:
    n = dolfin.FacetNormal(mesh)
    dx = dolfin.Measure("dx", mesh)
    ds = dolfin.Measure("ds", subdomain_data=boundary[0])
    mesh_xdmf = dolfin.XDMFFile(mpi_comm_world(), "data/mesh_3D.xdmf")
    mesh_xdmf.write(boundaries[0])
    return (mesh, boundary, n, dx, ds)
def commonEdge(cell1, cell2, mesh):
    facets1 = facets(cell1)
    facets2 = facets(cell2)

    # find common index
    ind_fac1 = []
    for facet in facets1:
        ind_fac1 = np.append(ind_fac1, facet.index())
    ind_fac2 = []
    for facet in facets2:
        ind_fac2 = np.append(ind_fac2, facet.index())

    # intersect gives index
    index = np.intersect1d(ind_fac1, ind_fac2)

    return Facet(mesh, int(index[0]))
Ejemplo n.º 10
0
 def write_fenics_file(ofile, mesh, editor):
     
     dim = mesh.geometry().dim()
     for i in range(1, len(cell_map)+1):
         if dim == 2:
             editor.add_cell(i-1, cell_map[i][0]-1, cell_map[i][1]-1, cell_map[i][2]-1)
         else:
             editor.add_cell(i-1, cell_map[i][0]-1, cell_map[i][1]-1, cell_map[i][2]-1, cell_map[i][3]-1)
     
     mesh.order()
     # Set MeshValueCollections from info in  boundary_cell
     #mvc = mesh.domains().markers(dim-1)
     md = mesh.domains()
     for zone, cells in boundary_cells.iteritems():
         for cell, nds in cells.iteritems():
             dolfin_cell = Cell(mesh, cell-1)
             vertices_of_cell = dolfin_cell.entities(0)
             vertices_of_face = nds - 1
             for jj, ff in enumerate(facets(dolfin_cell)):
                 facet_vertices = ff.entities(0)
                 if all(map(lambda x: x in vertices_of_face, facet_vertices)):
                     local_index = jj
                     break
             #mvc.set_value(cell-1, local_index, zone)
             md.set_marker((ff.index(), zone), dim-1)
             
     ofile << mesh        
     from dolfin import plot
     plot(mesh, interactive=True)
     print 'Finished writing FEniCS mesh\n'
Ejemplo n.º 11
0
def hat_function_grad(vertex, cell):
    """Compute L^\infty-norm of gradient of hat function on 'cell'
    and value 1 in 'vertex'."""
    # TODO: fix using ghosted mesh
    not_working_in_parallel("function 'hat_function_grad'")

    assert vertex in vertices(cell), "vertex not in cell!"

    # Find adjacent facet
    f = [f for f in facets(cell) if not vertex in vertices(f)]
    assert len(f) == 1, "Something strange with adjacent cell!"
    f = f[0]

    # Get unit normal
    n = f.normal()
    n /= n.norm()

    # Pick some vertex on facet
    # FIXME: Is it correct index in parallel?
    facet_vertex_0 = Vertex(cell.mesh(), f.entities(0)[0])

    # Compute signed distance from vertex to facet plane
    d = (facet_vertex_0.point() - vertex.point()).dot(n)

    # Return norm of gradient
    assert d != 0.0, "Degenerate cell!"
    return 1.0/abs(d)
Ejemplo n.º 12
0
 def set_mesh(self, mesh, *, transform=None):
     mesh.init()
     self.mesh = mesh
     self.basedim = mesh.geometric_dimension()
     self.num_vertices = mesh.num_vertices()
     self.num_cells = mesh.num_cells()
     self.num_facets = mesh.num_facets()
     self.dimension_dict = {
         self.num_cells: self.basedim,
         self.num_facets: self.basedim - 1
     }
     if transform is None:
         self.file.create_dataset('vertices',
                                  (self.num_vertices, self.basedim),
                                  data=mesh.coordinates(),
                                  compression=self.compression)
     else:
         self.file.create_dataset('vertices',
                                  (self.num_vertices, self.basedim),
                                  data=transform(mesh.coordinates()),
                                  compression=self.compression)
     self.file.create_dataset('cells', (self.num_cells, self.basedim + 1),
                              data=numpy.array(mesh.cells(),
                                               dtype=numpy.uintp),
                              compression=self.compression)
     self.file.create_dataset(
         'facets', (self.num_facets, self.basedim),
         data=numpy.array(
             [facet.entities(0) for facet in dolfin.facets(mesh)],
             dtype=numpy.uintp),
         compression=self.compression)
Ejemplo n.º 13
0
def get_vertex_patch(vid, mesh, layers=1):
    # find patch cells
    patch_cid = []
    for l in range(layers):
        if l == 0:
            patch_cid = Vertex(mesh,vid).entities(2).tolist()
        else:
            new_cid = []
            for cid in patch_cid:
                for cid in Cell(mesh,cid).entities(2).tolist():
                    if cid not in patch_cid:
                        new_cid.append(cid)
            patch_cid = patch_cid + new_cid

    # determine all facets
    FF_inner = FacetFunction('size_t', mesh)
    inner_facets = [Cell(mesh,cid).entities(1).tolist() for cid in patch_cid]
    inner_facets = set(iter.chain(*inner_facets))
    for fid in inner_facets:
        FF_inner[int(fid)] = 1

    # determine boundary facets
    FF_boundary = FacetFunction('size_t', mesh)
    for cid in patch_cid:
        c = Cell(mesh,cid)
        for f in facets(c):
            flist = f.entities(2).tolist()
            for fcid in flist:
                if fcid not in patch_cid or len(flist)==1:
                    FF_boundary[f.index()] = 1
                    FF_inner[f.index()] = 2 if len(flist)==2 else 3 # mark patch boundary facet (3 for outer Dirichlet boundary)
                    break
    return patch_cid, FF_inner, FF_boundary
Ejemplo n.º 14
0
    def calculate_normal(self, domains, interior, exterior):
        """calculate normal pointing towards the exterior domain at the 
        middle of each facet. Return the normal and its position """

        self.normal = np.zeros((self.Nfacets, 2))
        self.midpoints = np.zeros((self.Nfacets, 2))
        self.facet_lengths = np.zeros(self.Nfacets)
        counter = 0

        for facet in facets(domains.mesh()):
            cells = facet.entities(2)
            if facet.exterior() == False:
                domain1 = domains.array()[cells[0]]
                domain2 = domains.array()[cells[1]]
                if (sorted([domain1, domain2]) == sorted([interior,
                                                          exterior])):
                    self.facet_lengths[counter] = facet_length(facet)
                    if domain1 == interior:
                        self.normal[counter, 0] = facet.normal().x()
                        self.normal[counter, 1] = facet.normal().y()
                        self.midpoints[counter, 0] = facet.midpoint().x()
                        self.midpoints[counter, 1] = facet.midpoint().y()

                    elif domain1 == exterior:
                        self.normal[counter, 0] = -facet.normal().x()
                        self.normal[counter, 1] = -facet.normal().y()
                        self.midpoints[counter, 0] = facet.midpoint().x()
                        self.midpoints[counter, 1] = facet.midpoint().y()

                    counter += 1

        return (self.normal, self.midpoints)
Ejemplo n.º 15
0
    def compute_parent_facet_indices(submesh, mesh):
        dim = mesh.topology().dim()
        facet_dim = dim - 1
        submesh.init(facet_dim)
        mesh.init(facet_dim)

        # Make sure we have vertex-facet connectivity for parent mesh
        mesh.init(0, facet_dim)

        parent_vertex_indices = submesh.data().array("parent_vertex_indices",
                                                     0)
        # Create the fact map
        parent_facet_indices = np.full(submesh.num_facets(), -1)

        # Iterate over the edges and figure out their parent number
        for local_facet in df.facets(submesh):

            # Get parent indices for edge vertices
            vs = local_facet.entities(0)
            Vs = [df.Vertex(mesh, parent_vertex_indices[int(v)]) for v in vs]

            # Get outgoing facets from the two parent vertices
            facets = [set(V.entities(facet_dim)) for V in Vs]

            # Check intersection
            common_facets = facets[0]
            for f in facets[1:]:
                common_facets = common_facets.intersection(f)
            assert len(common_facets) == 1
            parent_facet_index = list(common_facets)[0]

            # Set value
            parent_facet_indices[local_facet.index()] = parent_facet_index
        return parent_facet_indices
Ejemplo n.º 16
0
def fun(mesh2d, nselects):
    '''A random curve from the edges'''
    import networkx as nx
    import random

    facet_f = df.MeshFunction('size_t', mesh2d, 1, 0)
    mesh2d.init(1, 0)
    # Init the graph
    G = nx.Graph()

    edge_indices = {
        tuple(sorted(facet.entities(0).tolist())): f_index
        for f_index, facet in enumerate(df.facets(mesh2d))
    }
    G.add_edges_from(iter(edge_indices.keys()))

    vertices = list(range(mesh2d.num_vertices()))
    for _ in range(nselects):
        v0, v1 = random.sample(vertices, 2)
        if v0 == v1: continue

        # THe path is a shortest path between 2 random vertices
        path = nx.shortest_path(G, source=v0, target=v1)
        for v0, v1 in zip(path[:-1], path[1:]):
            edge = (v0, v1) if v0 < v1 else (v1, v0)
            facet_f[edge_indices[edge]] = 1

    return facet_f
Ejemplo n.º 17
0
def fun(mesh2d, nselects):
    '''A random curve from the edges'''
    import networkx as nx
    import random

    facet_f = df.MeshFunction('size_t', mesh2d, 1, 0)    
    mesh2d.init(1, 0)
    # Init the graph
    G = nx.Graph()

    edge_indices = {tuple(sorted(facet.entities(0).tolist())): f_index
                    for f_index, facet in enumerate(df.facets(mesh2d))}
    G.add_edges_from(edge_indices.iterkeys())

    vertices = range(mesh2d.num_vertices())
    for _ in range(nselects):
        v0, v1 = random.sample(vertices, 2)
        if v0 == v1: continue

        # THe path is a shortest path between 2 random vertices
        path = nx.shortest_path(G, source=v0, target=v1)
        for v0, v1 in zip(path[:-1], path[1:]):
            edge = (v0, v1) if v0 < v1 else (v1, v0)
            facet_f[edge_indices[edge]] = 1

    return facet_f
Ejemplo n.º 18
0
def offsets_to_facetfunction(function, out_ff=None):
    '''
Parameters
----------
function : dolfin.Function
    Input DG0 function.

Returns
-------
ff : dolfin.MeshFunction
    Facet function: equal to 1 if facet separates two cells with
    different `function` values, and 0 otherwise.
'''
    space = function.function_space()
    mesh = space.mesh()
    D = mesh.geometry().dim()
    vec = function.vector()

    ff = out_ff
    if not ff:
        ff = dolfin.MeshFunction("int", mesh, D - 1, 0)

    ffv = ff.array()
    for facet in dolfin.facets(mesh):
        l = facet.entities(D)
        if len(l) == 2:
            a, b = l
            if vec[a] != vec[b]:
                ffv[facet.index()] = 1

    return ff
Ejemplo n.º 19
0
def boundaries(mesh):
    boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
    for f in facets(mesh):
        boundaries.array()[f.index()] = 0
        for v in vertices(f):
            boundaries.array()[f.index()] += v.global_index()
    return boundaries
Ejemplo n.º 20
0
def from_mesh(cls, mesh, initial_point, k):
  print 'Creating Mesh from dolfin.Mesh data.'

  # Make sure it is the right kind of mesh.
  print 'Initializing mesh attributes (edges, faces, etc.)'
  mesh.init()  # This will do nothing if already called.
  check_mesh_type(mesh)

  # Compute extra data not stored on the object.
  print 'Reading vertex list from the mesh object'
  vertex_list = list(dolfin.vertices(mesh))
  print 'Reading edge list from the mesh object'
  edge_list = list(dolfin.edges(mesh))
  print 'Reading facets list from the mesh object'
  # Use facets since they have facet.exterior() set.
  facets_list = list(dolfin.facets(mesh))
  # Get values specific to motion on the mesh.
  print 'Reading cell list from the mesh object'
  cell_list = list(dolfin.cells(mesh))
  initial_face_index = get_face(dolfin.Point(*initial_point),
                                mesh, cell_list)

  print 'Parsing exterior faces and creating Face objects'
  (all_vertices, triangles, face_local_bases, neighbor_faces,
   initial_face_index) = get_face_data(vertex_list, edge_list,
                                       facets_list, initial_face_index)

  return cls(k, initial_point, initial_face_index,
             all_vertices, triangles, face_local_bases, neighbor_faces)
Ejemplo n.º 21
0
    def write_fenics_file(ofile, mesh, editor):

        dim = mesh.geometry().dim()
        for i in range(1, len(cell_map) + 1):
            if dim == 2:
                editor.add_cell(i - 1, cell_map[i][0] - 1, cell_map[i][1] - 1,
                                cell_map[i][2] - 1)
            else:
                editor.add_cell(i - 1, cell_map[i][0] - 1, cell_map[i][1] - 1,
                                cell_map[i][2] - 1, cell_map[i][3] - 1)

        mesh.order()
        # Set MeshValueCollections from info in  boundary_cell
        #mvc = mesh.domains().markers(dim-1)
        md = mesh.domains()
        for zone, cells in boundary_cells.iteritems():
            for cell, nds in cells.iteritems():
                dolfin_cell = Cell(mesh, cell - 1)
                vertices_of_cell = dolfin_cell.entities(0)
                vertices_of_face = nds - 1
                for jj, ff in enumerate(facets(dolfin_cell)):
                    facet_vertices = ff.entities(0)
                    if all(map(lambda x: x in vertices_of_face,
                               facet_vertices)):
                        local_index = jj
                        break
                #mvc.set_value(cell-1, local_index, zone)
                md.set_marker((ff.index(), zone), dim - 1)

        ofile << mesh
        from dolfin import plot
        plot(mesh, interactive=True)
        print 'Finished writing FEniCS mesh\n'
Ejemplo n.º 22
0
def precompute_facet_data(simulation):
    """
    Get facet normal and areas in an easy to use format
    """
    mesh = simulation.data['mesh']
    conFC = simulation.data['connectivity_FC']
    ndim = simulation.ndim
    cell_info = simulation.data['cell_info']

    # Get the facet areas from the cells
    areas = {}
    for cell in dolfin.cells(mesh, 'all'):
        # Get the connected facets
        facet_idxs = cell.entities(ndim - 1)

        # Loop over connected facets and get the area
        for i, fidx in enumerate(facet_idxs):
            a = cell.facet_area(i)
            if fidx in areas:
                assert a == areas[fidx]
            else:
                areas[fidx] = a

    # Loop over facets and gather the required information
    facet_info = [None] * mesh.num_facets()
    for facet in dolfin.facets(mesh, 'all'):
        fidx = facet.index()

        mp = facet.midpoint()
        if ndim == 2:
            midpoint = numpy.array([mp.x(), mp.y()], float)
        else:
            midpoint = numpy.array([mp.x(), mp.y(), mp.z()], float)

        # Find one cell connected to this facet. There can be one or two
        # connected cells, we only need the first one
        connected_cells = conFC(fidx)
        icell0 = connected_cells[0]
        on_boundary = len(connected_cells) == 1

        # Midpoint of local cell 0
        cell0_mp = cell_info[icell0].midpoint

        # Vector from local cell midpoint to face midpoint
        vec0 = midpoint - cell0_mp

        # Find a normal pointing out from cell 0
        normalpt = facet.normal()
        if ndim == 2:
            normal = numpy.array([normalpt.x(), normalpt.y()], float)
        else:
            normal = numpy.array([normalpt.x(), normalpt.y(), normalpt.z()], float)
        if numpy.dot(vec0, normal) < 0:
            normal *= -1

        area = areas[fidx]
        facet_info[fidx] = FacetInfo(area, midpoint, normal, on_boundary)

    simulation.data['facet_info'] = facet_info
Ejemplo n.º 23
0
def get_dof_region_marks(simulation, V):
    """
    Given a function space, return a dictionary mapping dof number to a
    list of region number (indexed from 0, same as region list from the
    input file).

    Many dofs will not be included in the mapping since they are not
    inside a boundary region (not on a boundary facet). This property is
    used elsewhere to identify boundary dofs, in mark_cell_layers() and
    in SlopeLimiterBoundaryConditions
    """
    # This function only supports a small subset of function spaces
    family = V.ufl_element().family()
    assert family in ('Lagrange', 'Discontinuous Lagrange')

    # Get local indices for the facet dofs for each facet in the cell
    facet_dof_indices = get_facet_dof_indices(V)

    # Get dofs that share the same location (relevant for DG)
    same_loc_dofs = get_same_loc_dofs(V)

    # Loop over mesh and get dofs that are connected to boundary regions
    dm = V.dofmap()
    facet_marks = [int(m) for m in simulation.data['boundary_marker'].array()]
    mesh = simulation.data['mesh']
    dof_region_marks = {}
    for cell in dolfin.cells(mesh, 'all'):
        dofs = dm.cell_dofs(cell.index())

        for ifacet, facet in enumerate(dolfin.facets(cell)):
            # Get facet region marker
            mark = facet_marks[facet.index()] - 1

            # Skip non-boundary facets
            if mark == -1:
                continue

            facet_dofs = dofs[facet_dof_indices[ifacet]]
            for fdof in facet_dofs:
                dof_region_marks.setdefault(fdof, []).append(mark)

    # Treat all dofs in the same location in the same way
    for fdof, regions in list(dof_region_marks.items()):
        for dof2 in same_loc_dofs[fdof]:
            if dof2 not in dof_region_marks:
                dof_region_marks[dof2] = regions
                continue
            for mark in regions:
                if mark not in dof_region_marks[dof2]:
                    dof_region_marks[dof2].append(mark)

    # Order must be the same on all ranks independent of iteration order
    # of the dof_region_marks dictionary in the above loop
    for marks in dof_region_marks.values():
        marks.sort()

    return dof_region_marks
Ejemplo n.º 24
0
def get_boundary_surface(simulation, field, value):
    """
    Find the boundary surface consisting of facets with
    scalar field values greater than the given iso value
    """
    assert simulation.ndim == 2

    mesh = simulation.data['mesh']
    all_values = field.compute_vertex_values()

    connectivity_FC = simulation.data['connectivity_FC']

    # Find the crossing points where the contour crosses a facet
    connections = {}
    for facet in dolfin.facets(mesh):
        fid = facet.index()

        # Skip facets that are not on the boundary
        connected_cells = connectivity_FC(fid)
        if not len(connected_cells) == 1:
            continue

        # Get connected vertices and the field values there
        vertex_coords = []
        vertex_values = []
        for vertex in dolfin.vertices(facet):
            pt = vertex.point()
            vertex_coords.append((pt.x(), pt.y(), pt.z()))
            vertex_values.append(all_values[vertex.index()])
        assert len(vertex_coords) == 2

        # Check if all values are above the iso value
        if vertex_values[0] < value or vertex_values[1] < value:
            continue

        connections.setdefault(vertex_coords[0], []).append(vertex_coords[1])
        connections.setdefault(vertex_coords[1], []).append(vertex_coords[0])

    # Map coord to coord, just to be able to use the generic functionality in
    # contour_lines_from_endpoints which works on facet_id <-> coord mappings
    available_coords = {vc: vc for vc in connections}

    # Make continous contour lines
    # Find end points of contour lines and start with these
    end_points = [
        vc for vc, neighbours in connections.items() if len(neighbours) < 2
    ]
    contours_from_endpoints = contour_lines_from_endpoints(
        end_points, available_coords, connections)

    # Include crossing points without neighbours or joined circles without end points
    other_points = available_coords.keys()
    contours_from_singles_and_loops = contour_lines_from_endpoints(
        other_points, available_coords, connections)

    assert len(available_coords) == 0
    return contours_from_endpoints + contours_from_singles_and_loops
Ejemplo n.º 25
0
def test_normal():
    "Test that the normal() method is wrapped"
    mesh = UnitSquareMesh(4, 4)
    for facet in facets(mesh):
        n = facet.normal()
        nx, ny, nz = n.x(), n.y(), n.z()
        assert isinstance(nx, float)
        assert isinstance(ny, float)
        assert isinstance(nz, float)
Ejemplo n.º 26
0
    def extract_coupling_boundary_vertices1(self, function_space):
        """Extracts verticies which lay on the boundary. Currently handles 2D
        case properly, 3D is circumvented.

        :raise Exception: if no correct coupling interface is defined
        :return: stack of verticies
        """
        n = 0
        local_dofs = []
        vertices_x = []
        vertices_y = []
        if self._dimensions == 3:
            vertices_z = []
        con = []

        if not issubclass(type(self._coupling_subdomain), SubDomain):
            raise Exception("no correct coupling interface defined!")

        mesh = function_space.mesh()
        v2d = vertex_to_dof_map(function_space)
        value_size = function_space.ufl_element().value_size()
        for f in facets(mesh):
            interface = True
            #if f.exterior():
            for v in vertices(f):
                if self._dimensions == 2:
                    if not self._coupling_subdomain.inside(
                        [v.x(0), v.x(1)], True):
                        interface = False
                elif self._dimensions == 3:
                    if not self._coupling_subdomain.inside(
                        [v.x(0), v.x(1), v.x(2)], True):
                        interface = False
            #else:
            #    interface=False
            if interface:
                for v in vertices(f):
                    for ii in range(value_size):
                        local_dof = v2d[value_size * v.index() + ii]
                        if ii == 0:
                            con.append(local_dof)
                        if local_dof not in local_dofs:
                            local_dofs.append(local_dof)
                            if ii == 0:
                                n += 1
                                vertices_x.append(v.x(0))
                                vertices_y.append(v.x(1))
                                if self._dimensions == 3:
                                    vertices_z.append(v.x(2))

        if self._dimensions == 2:
            return np.column_stack([vertices_x,
                                    vertices_y]), n, local_dofs, con
        elif self._dimensions == 3:
            return np.column_stack([vertices_x, vertices_y,
                                    vertices_z]), n, local_dofs, con
Ejemplo n.º 27
0
def mark_facets(mesh, ffun):
    """
    Mark mesh according to facet function
    """
    for facet in df.facets(mesh):

        if ffun[facet] == 2 ** 64 - 1:
            ffun[facet] = 0

        mesh.domains().set_marker((facet.index(), ffun[facet]), 2)
Ejemplo n.º 28
0
def refine_perimeter(mesh):
    """Refine largest boundary triangles."""
    mesh.init(1, 2)
    perimeter = [c for c in cells(mesh)
                 if any([f.exterior() for f in facets(c)])]
    marker = CellFunction('bool', mesh, False)
    max_size = max([c.diameter() for c in perimeter])
    for c in perimeter:
        marker[c] = c.diameter() > 0.75 * max_size
    return refine(mesh, marker)
def boundary_normal(mesh, facet_markers, bndry_id):
    """
    Extracts the normal vector of the boundary marked by the boundary id
    by checking that
        1. the facet normal vectors are co-linear
        2. the vector connecting two face midpoints is tangential to both
           normal vectors.
    Returns a tuple of float representing the normal.
    """
    assert isinstance(mesh, dlfn.Mesh)
    assert isinstance(facet_markers, dlfn.cpp.mesh.MeshFunctionSizet)
    assert isinstance(bndry_id, int)

    tol = 1.0e3 * dlfn.DOLFIN_EPS
    normal_vectors = []
    midpoints = []
    for f in dlfn.facets(mesh):
        if f.exterior():
            if facet_markers[f] == bndry_id:
                current_normal = f.normal()
                current_midpoint = f.midpoint()
                for normal, midpoint in zip(normal_vectors, midpoints):
                    # check that normal vectors point in the same direction
                    assert current_normal.dot(normal) > 0.0
                    # check that normal vector are parallel
                    if abs(current_normal.dot(normal) -
                           1.0) > tol:  # pragma: no cover
                        raise ValueError(
                            "Boundary facets do not share common normal.")
                    # compute a tangential vector as connection vector of two
                    # midpoints
                    midpoint_connection = midpoint - current_midpoint
                    # check that tangential vector is orthogonal to both normal
                    #  vectors
                    if abs(midpoint_connection.dot(
                            normal)) > tol:  # pragma: no cover
                        raise ValueError(
                            "Midpoint connection vector is not tangential to boundary facets."
                        )
                    if abs(midpoint_connection.dot(
                            current_normal)) > tol:  # pragma: no cover
                        raise ValueError(
                            "Midpoint connection vector is not tangential to boundary facets."
                        )
                normal_vectors.append(current_normal)
                midpoints.append(current_midpoint)

    assert len(normal_vectors) > 0, "Boundary id is not marked in MeshFunction"
    assert len(midpoints) == len(normal_vectors)

    dim = mesh.topology().dim()
    normal = normal_vectors[0]

    return tuple(normal[d] for d in range(dim))
Ejemplo n.º 30
0
def refine_perimeter(mesh):
    """Refine largest boundary triangles."""
    mesh.init(1, 2)
    perimeter = [
        c for c in cells(mesh) if any([f.exterior() for f in facets(c)])
    ]
    marker = CellFunction('bool', mesh, False)
    max_size = max([c.diameter() for c in perimeter])
    for c in perimeter:
        marker[c] = c.diameter() > 0.75 * max_size
    return refine(mesh, marker)
 def _check_boundary_conditions(self, bcs):
     from boundary_conditions import VelocityBCType, TemperatureBCType
     # input check: boundary conditions
     assert isinstance(bcs, dict)
     assert bcs.has_key("temperature")
     assert bcs.has_key("velocity")
     # check if structure of dictionary is correct
     ids_bc = set()
     for key, bc in bcs.iteritems():
         if key is "velocity":
             bc_types = VelocityBCType
             none_type = VelocityBCType.no_slip
         elif key is "temperature":
             bc_types = TemperatureBCType
             none_type = None
         else:
             raise ValueError()
         const_type = bc_types.constant
         assert isinstance(bc, tuple)
         assert len(bc) > 0
         # check sub boundary conditions
         for i in range(len(bc)):
             assert isinstance(bc[i], tuple)
             assert len(bc[i]) == 3
             # check if type of bc is correct
             assert bc[i][0] in bc_types
             # check if type of facet_id is correct
             assert isinstance(bc[i][1], int) and bc[i][1] > 0
             ids_bc.add(bc[i][1])
             # check if value type of bc is correct
             if none_type is VelocityBCType.no_slip:
                 assert bc[i][2] is None
             elif bc[i][2] is const_type:
                 if key is "velocity":
                     assert isinstance(bc[i][2], (list, tuple))
                     assert len(bc[i][2]) == self._space_dim
                     assert all(isinstance(x, float) for x in bc[i][2])
                 elif key is "temperature":
                     assert isinstance(bc[i][2], float)
             else:
                 isinstance(bc[i][2], dlfn.Expression)
     # check if facet_ids of bcs occur in markers
     ids_bc = tuple(ids_bc)
     ids_bc_found = [
         False,
     ] * len(ids_bc)
     for facet in dlfn.facets(self._mesh):
         if facet.exterior():
             if self._facet_markers[facet] in ids_bc:
                 i = ids_bc.index(self._facet_markers[facet])
                 ids_bc_found[i] = True
                 if all(ids_bc_found):
                     break
Ejemplo n.º 32
0
    def _plot_edges(self, ax, mesh, edge_color, bdr_edge_color):
        'Compute inner and boundary edges of the mesh and plot them.'
        # Create edges
        tdim = mesh.topology().dim()
        mesh.init(1)
        bdr_edges = set([])

        # Compute boundary edges for inter-process boundaries
        if self.mpi_size > 1:
            # Facet cell connectivity, 2d = edge->cell, 3d = facet->cell
            mesh.init(tdim-1, tdim)
            # In 2d bdr edge has different number of local and global cells
            if tdim == 2:
                bdr_edges =\
                    set([f.index() for f in facets(mesh)
                         if
                         f.num_entities(tdim) != f.num_global_entities(tdim)])
            # In 3d bdr edge belongs to facet who has different number of local
            # and global cells
            else:
                # Face -> edge connectivity
                mesh.init(tdim-1, 1)
                bdr_edges =\
                    set(map(int, sum([f.entities(1).tolist()
                                      for f in facets(mesh)
                                      if
                                      f.num_entities(tdim) !=
                                      f.num_global_entities(tdim)],
                                     [])))

        # Plot inner_edges
        inner_edges = set(range(mesh.size(1))) - bdr_edges
        x_min_max =\
            self._plot_edges_from_list(ax, mesh, inner_edges, edge_color)

        # Plot boundary edges
        if bdr_edges:
            self._plot_edges_from_list(ax, mesh, bdr_edges, bdr_edge_color)

        return x_min_max
Ejemplo n.º 33
0
    def _plot_edges(self, ax, mesh, edge_color, bdr_edge_color):
        'Compute inner and boundary edges of the mesh and plot them.'
        # Create edges
        tdim = mesh.topology().dim()
        mesh.init(1)
        bdr_edges = set([])

        # Compute boundary edges for inter-process boundaries
        if self.mpi_size > 1:
            # Facet cell connectivity, 2d = edge->cell, 3d = facet->cell
            mesh.init(tdim - 1, tdim)
            # In 2d bdr edge has different number of local and global cells
            if tdim == 2:
                bdr_edges =\
                    set([f.index() for f in facets(mesh)
                         if
                         f.num_entities(tdim) != f.num_global_entities(tdim)])
            # In 3d bdr edge belongs to facet who has different number of local
            # and global cells
            else:
                # Face -> edge connectivity
                mesh.init(tdim - 1, 1)
                bdr_edges =\
                    set(map(int, sum([f.entities(1).tolist()
                                      for f in facets(mesh)
                                      if
                                      f.num_entities(tdim) !=
                                      f.num_global_entities(tdim)],
                                     [])))

        # Plot inner_edges
        inner_edges = set(range(mesh.size(1))) - bdr_edges
        x_min_max =\
            self._plot_edges_from_list(ax, mesh, inner_edges, edge_color)

        # Plot boundary edges
        if bdr_edges:
            self._plot_edges_from_list(ax, mesh, bdr_edges, bdr_edge_color)

        return x_min_max
def extract_all_boundary_markers(mesh, mesh_function):
    """
    Stores all boundary markers of the MeshFunction inside a set.
    """
    assert isinstance(mesh, dlfn.Mesh)
    assert isinstance(
        mesh_function,
        (dlfn.cpp.mesh.MeshFunctionSizet, dlfn.cpp.mesh.MeshFunctionInt))
    boundary_markers = set()
    for f in dlfn.facets(mesh):
        if f.exterior():
            boundary_markers.add(mesh_function[f])
    return boundary_markers
Ejemplo n.º 35
0
 def cell_to_cells_adjacency_via_facet(self):
     mesh = self.mesh
     D = mesh.topology().dim()
     mesh.init(D - 1, D)
     mesh.init(D, D)
     cell_neighbors = [[] for i in range(mesh.num_cells())]
     for facet in dolfin.facets(mesh):
         l = facet.entities(D)
         if len(l) == 2:
             a, b = l
             cell_neighbors[a].append(b)
             cell_neighbors[b].append(a)
     return cell_neighbors
Ejemplo n.º 36
0
def boundary_mesh_entities(mesh, dim='facet', type='exterior', order=True):
    '''iterator of facets or cells of BoundaryMesh

    slow stupid limited workaround version >_< '''
    if (dim, type, order) != ('facet', 'exterior', True):
        raise AssertionError()

    D = mesh.topology().dim()
    Facet = dolfin.Facet
    for f in dolfin.facets(mesh):
        if len(f.entities(D)) == 1:
            # only one adjacent cell, other side is nonexistence
            yield f
Ejemplo n.º 37
0
    def init_localizer(self, bnd):
        # self.facet_adjacents[cell_id][facet_number] is the id of the adjacent cell
        # self.facet_normals[cell_id][facet_number] is the normal vector to a facet
        # self.facet_mids[cell_id][facet_number] is the midpoint on a facet
        # facet_number is a number from 0 to t_dim
        # TBD: Now all facets are stored redundantly (for each cell)
        # Storage could be reduced, but would the performance hit be significant?

        self.mesh.init(self.t_dim-1, self.t_dim)
        self.facet_adjacents = []
        self.facet_normals = []
        self.facet_mids = []
        facets = list(df.facets(self.mesh))
        for cell in df.cells(self.mesh):
            facet_ids = cell.entities(self.t_dim-1)
            adjacents = []
            normals = []
            mids = []

            for facet_number, facet_id in enumerate(facet_ids):
                facet = facets[facet_id]

                adjacent = set(facet.entities(self.t_dim))-{cell.index()}
                adjacent = list(adjacent)
                if adjacent == []:
                    # Travelled out of bounds through the following boundary
                    # Minus indicates through boundary
                    adjacent = -int(bnd.array()[facet_id])

                else:
                    adjacent = int(adjacent[0])

                assert isinstance(adjacent,int)


                # take normal from cell rather than from facet to make sure it
                # is outwards-pointing
                normal = cell.normal(facet_number).array()[:self.g_dim]

                mid = facet.midpoint()
                mid = np.array([mid.x(), mid.y(), mid.z()])
                mid = mid[:self.t_dim]

                adjacents.append(adjacent)
                normals.append(normal)
                mids.append(mid)


            self.facet_adjacents.append(adjacents)
            self.facet_normals.append(normals)
            self.facet_mids.append(mids)
def get_data(resolution):
    mesh_full_filename = 'data/mesh_res_%d_full.xml' % resolution
    mesh_3d_full = dolfin.Mesh(mesh_full_filename)
    print 'Calling mesh.init() to compute faces / edges / etc.'
    print '=' * 60
    mesh_3d_full.init()

    print 'Reading facet, edge and vertex iterators into lists'
    print '=' * 60
    facets = list(dolfin.facets(mesh_3d_full))
    edges = list(dolfin.edges(mesh_3d_full))
    vertices = list(dolfin.vertices(mesh_3d_full))

    return mesh_3d_full, facets, edges, vertices
def get_data(resolution):
  mesh_full_filename = 'data/mesh_res_%d_full.xml' % resolution
  mesh_3d_full = dolfin.Mesh(mesh_full_filename)
  print 'Calling mesh.init() to compute faces / edges / etc.'
  print '=' * 60
  mesh_3d_full.init()

  print 'Reading facet, edge and vertex iterators into lists'
  print '=' * 60
  facets = list(dolfin.facets(mesh_3d_full))
  edges = list(dolfin.edges(mesh_3d_full))
  vertices = list(dolfin.vertices(mesh_3d_full))

  return mesh_3d_full, facets, edges, vertices
Ejemplo n.º 40
0
    def base_mean_position(self):
        """
        Return mean coordinates of the base
        (serial only?)
        """
        import numpy as np

        (facet_indices,) = np.where(self.ffun.array() == self.markers["BASE"][0])
        point_inidces = []
        for facet in dolfin.facets(self.mesh):
            if facet.index() in facet_indices:
                point_inidces.extend(facet.entities(0).tolist())

        return np.mean(self.mesh.coordinates()[point_inidces, :], 0)
Ejemplo n.º 41
0
def poincare_friedrichs_cutoff(o, p):
    if isinstance(o, Mesh):
        # TODO: easy fix - ghosted mesh + missing reduction
        not_working_in_parallel("PF cutoff on mesh")
        return max(poincare_friedrichs_cutoff(v, p) for v in vertices(o))

    if isinstance(o, Vertex):
        # TODO: fix using ghosted mesh
        not_working_in_parallel("PF cutoff on patch")
        hat_fun_grad = max(hat_function_grad(o, c) for c in cells(o))
        if any(f.exterior() for f in facets(o)):
            return 1.0 + friedrichs_const(o, p) * hat_fun_grad
        else:
            return 1.0 + poincare_const(o, p) * hat_fun_grad

    raise NotImplementedError
Ejemplo n.º 42
0
def get_face(point, mesh, cell_list):
  face_intersection = dolfin.cpp.mesh.intersect(mesh, point)
  # Require a unique intersection. This is not actually necessary as some
  # points may lie on an edge / vertex or may not be on the mesh at all.
  if face_intersection.intersected_cells().size != 1:
    raise ValueError('Point does not intersect mesh in a unique cell.')
  cell_index = face_intersection.intersected_cells()[0]

  matched_cell = cell_list[cell_index]
  exterior_facets = [facet for facet in dolfin.facets(matched_cell)
                     if facet.exterior()]
  if len(exterior_facets) != 1:
    print 'exterior_facets:', exterior_facets
    raise ValueError('Number of facets on cell marked exterior != 1.')

  return exterior_facets[0].index()
def findAdjacentCellInd(cell, mesh):
    adj_cells = []
    D = mesh.topology().dim()
    # Build connectivity between facets and cells
    mesh.init(D - 1, D)
    # loop over edges
    for facet in facets(cell):
        # find all cells with edge facet
        # print facet.entities(D)
        adj_cells = np.append(adj_cells, facet.entities(D))

    # delete doubles and the cell itself
    adj_cells = np.unique(adj_cells)
    adj_cells = adj_cells[adj_cells != cell.index()]

    return adj_cells
def computeEdgeCRDofArray(V, mesh, B=None):
    # dof map, dim_V = 2 * num_E
    num_E = mesh.num_facets()
    dofmap = V.dofmap()
    edgeCRDofArray = np.zeros((num_E, 2))

    # loop over cells and fill array
    for k, cell in enumerate(cells(mesh)):
        # list of dof-indices for edges of the cell
        dofs = dofmap.cell_dofs(cell.index())
        for i, facet in enumerate(facets(cell)):
            # print 'cell: %3g  ||  i: %3g   || facet: %3g || dof[i]: %3g' \
            #     % (cell.index(), i, facet.index(), dofs[i])
            # corresponding DoFs (2 basisfct per edge)
            edgeCRDofArray[facet.index()] = [dofs[i], dofs[i+3]]
            # edgeCRDofArray[facet.index()] = [dofs[i], dofs[i]+1]
            # every interior edge visited twice but EGAL!

    return edgeCRDofArray
Ejemplo n.º 45
0
def write_fenics_file(dim, ofilename):
    ofile  = File(ofilename + '.xml')
    mesh = Mesh()
    editor = MeshEditor()
    editor.open(mesh, dim, dim)
    editor.init_vertices(nodes.shape[1])
    editor.init_cells(len(cell_map))    
    for i in range(nodes.shape[1]):
        if dim == 2:
            editor.add_vertex(i, nodes[0, i], nodes[1, i])
        else:
            editor.add_vertex(i, nodes[0, i], nodes[1, i], nodes[2, i])
            
    for i in range(1, len(cell_map)+1):
        if dim == 2:
            editor.add_cell(i-1, cell_map[i][0]-1, cell_map[i][1]-1, cell_map[i][2]-1)
        else:
            editor.add_cell(i-1, cell_map[i][0]-1, cell_map[i][1]-1, cell_map[i][2]-1, cell_map[i][3]-1)
    
    mesh.order()
    mvc = mesh.domains().markers(dim-1)
    for zone, cells in boundary_cells.iteritems():
        for cell, nds in cells.iteritems():
            dolfin_cell = Cell(mesh, cell-1)
            nodes_of_cell = dolfin_cell.entities(0)
            #print cell
            #print nodes_of_cell
            nodes_of_face = nds - 1
            #print nodes_of_face
            for jj, ff in enumerate(facets(dolfin_cell)):
                facet_nodes = ff.entities(0)
                #print facet_nodes
                if all(map(lambda x: x in nodes_of_face, facet_nodes)):
                    local_index = jj
                    break
            mvc.set_value(cell-1, local_index, zone)
        
    ofile << mesh        
    from dolfin import plot
    plot(mesh, interactive=True)
    print 'Finished writing FEniCS mesh\n'
def main():
  resolution = 96  # 32 * 3
  mesh_full_filename = 'data/mesh_res_%d_full.xml' % resolution
  mesh_3d_full = dolfin.Mesh(mesh_full_filename)
  print 'Calling mesh.init() to compute faces / edges / etc.'
  print '=' * 60
  mesh_3d_full.init()

  coords = mesh_3d_full.coordinates()
  top_coords = np.nonzero(
      coords[:, 2] >= full_dendrite_mesh.TOP_CONE_TOP_Z - 0.001)[0]
  top_coords_set = set(top_coords)

  num_faces = mesh_3d_full.num_faces()
  num_facets = mesh_3d_full.num_facets()
  if num_faces != num_facets:
    raise ValueError('Expected tetrahedral mesh.')

  # Use facets instead of faces (though identical) because the
  # facet objects have .exterior() set.
  faces_as_facets = dolfin.facets(mesh_3d_full)
  exterior_face_indices = []
  vertical_normal_faces = []
  all_top_coords_faces = []
  face_count = 0

  print 'Looping through faces to find faces on tops of synapses'
  print '=' * 60
  for face in faces_as_facets:
    face_count += 1
    if face_count % 20000 == 0:
      print face_count, '/', num_faces

    # Only use exterior facets / faces.
    if not face.exterior():
      continue
    else:
      exterior_face_indices.append(face.index())

    # The vertical normal is (0, 0, 1) and we check the angle between
    # the normal and this vector v . (0, 0, 1) = v_z (dot product).
    theta = np.arccos(face.normal().z())
    if np.allclose(theta, 0):
      vertical_normal_faces.append(face)

    # If every single index is one of the "top coordinate" indices.
    if set(face.entities(0)) <= top_coords_set:
      all_top_coords_faces.append(face)

  # First save the exterior face indices.
  # NOTE: We are 100% sure indices are computed the same upon reloading data
  #       from XML file. This is relevant for face indices, since they are
  #       not stored in the XML file. See
  #           http://fenicsproject.org/qa/3233
  #       for details.
  exterior_face_filename = 'data/exterior_faces_res_%d_full.npz' % resolution
  print '=' * 60
  print 'Saving to file:', exterior_face_filename
  print '%d exterior faces out of %d total faces.' % (
      len(exterior_face_indices), num_faces)
  print '=' * 60
  np.savez(exterior_face_filename, np.array(exterior_face_indices))

  if vertical_normal_faces != all_top_coords_faces:
    raise ValueError('Top face classifications disagree.')

  # Indices for the faces will be the same if data loaded again. See above.
  face_index_matrix = np.vstack(
      [face.entities(0) for face in vertical_normal_faces])

  faces_full_filename = 'data/faces_top_res_%d_full.npz' % resolution
  print '=' * 60
  print 'Saving to file:', faces_full_filename
  print '=' * 60
  np.savez(faces_full_filename, face_index_matrix)

  # Save the indices of the facets on the top.
  top_indices_filename = 'data/faces_top_indices_res_%d_full.npz' % resolution
  print '=' * 60
  print 'Saving to file:', top_indices_filename
  print '=' * 60
  top_indices = [facet.index() for facet in vertical_normal_faces]
  np.savez(top_indices_filename, np.array(top_indices))
Ejemplo n.º 47
0
innerinds = np.setdiff1d(range(V.dim()), bcinds)
bcinds = np.setdiff1d(range(V.dim()), innerinds)

# vector of -1
vvec = np.zeros(V.dim()) - 1
# set inner nodes to 1
vvec[innerinds] = 1
# assign to function
v = dolfin.Function(V)
v.vector().set_local(vvec)

# Evaluate CR at midpoints
mesh.init(1, 2)
midpoints = np.array([np.array([facet.midpoint().x(), facet.midpoint().y()])
                      for facet in dolfin.facets(mesh) if facet.exterior()])
U = np.zeros(len(midpoints))
V = np.zeros_like(U)
for i, mp in enumerate(midpoints):
    U[i], V[i] = v(mp)

import matplotlib.tri as tri
import matplotlib.pyplot as plt

# Data for mesh
mesh_coordinates = mesh.coordinates().reshape((-1, 2))
triangles = np.asarray([cell.entities(0) for cell in dolfin.cells(mesh)])
triangulation = tri.Triangulation(mesh_coordinates[:, 0],
                                  mesh_coordinates[:, 1],
                                  triangles)
Ejemplo n.º 48
0
def mortar_meshes(subdomains, markers, ifacet_iter=None, strict=True, tol=1E-14):
    '''
    Let subdomains a cell function. We assume that domains (cells) marked 
    with the given markers are adjecent and an interface can be defined 
    between these domains which is a continuous curve. Then for each 
    domain we create a (sub)mesh and a single interface mesh which holds 
    a connectivity map of its cells to facets of the submeshes. The submeshes 
    are returned as a list. The connectivity map is 
    of the form submesh.id -> facets. The marking function f of the EmbeddedMesh
    that is the interface is colored such that f[color] is the interface 
    of meshes (submeshes[m] for m color_map[color]).
    '''
    assert len(markers) > 1
    # Need a cell function
    mesh = subdomains.mesh()
    tdim = mesh.topology().dim()
    assert subdomains.dim() == tdim

    markers = list(markers)
    # For each facet we want to know which 2 cells share it
    tagged_iface = defaultdict(dict)

    if ifacet_iter is None:
        mesh.init(tdim-1)
        ifacet_iter = df.facets(mesh)
    
    mesh.init(tdim-1, tdim)
    for facet in ifacet_iter:
        cells = map(int, facet.entities(tdim))

        if len(cells) > 1:
            c0, c1 = cells
            tag0, tag1 = subdomains[c0], subdomains[c1]
            if tag0 != tag1 and tag0 in markers and tag1 in markers:
                # A key of sorted tags
                if tag0 < tag1:
                    key = (tag0, tag1)
                    # The cells connected to facet order to match to tags
                    value = (c0, c1)
                else:
                    key = (tag1, tag0)
                    value = (c1, c0)
                # A facet to 2 cells map for the facets of tagged pair
                tagged_iface[key][facet.index()] = value

    # order -> tagged keys
    color_to_tag_map = tagged_iface.keys()
    # Set to color which won't be encounred
    interface = df.MeshFunction('size_t', mesh, tdim-1, len(color_to_tag_map))
    values = interface.array()

    # Mark facets corresponding to tagged pair by a color
    for color, tags in enumerate(color_to_tag_map):
        values[tagged_iface[tags].keys()] = color

    # Finally create an interface mesh for all the colors
    interface_mesh = EmbeddedMesh(interface, range(len(color_to_tag_map)))

    # Try to recogninze the meshes which violates assumptions by counting
    assert not strict or is_continuous(interface_mesh)
    
    # And subdomain mesh for each marker
    subdomain_meshes = {tag: EmbeddedMesh(subdomains, tag) for tag in markers}

    # Alloc the entity maps for the embedded mesh
    interface_map = {subdomain_meshes[tag].id(): [None]*interface_mesh.num_cells()
                     for tag in markers}
    
    # THe maps are filled by the following idea. Using marking function
    # of interface mesh one cat get cells of that color and useing entity
    # map for (original) mesh map the cells to mesh facet. A color also
    # corresponds to a pair of tags which identifies the two meshes which
    # share the facet - facet connected to 2 cells one for each mesh. The
    # final step is to lean to map submesh cells to mesh cells

    # local submesh <- global of parent mesh
    sub_mesh_map = lambda tag: dict(
        (mesh_c, submesh_c)
        for submesh_c, mesh_c in
        enumerate(subdomain_meshes[tag].parent_entity_map[mesh.id()][tdim])
    )

    # Thec cell-cell connectivity of each submesh
    c2c = {tag: sub_mesh_map(tag) for tag in markers}
    # A connectivity of interface mesh cells to facets of global mesh
    c2f = interface_mesh.parent_entity_map[mesh.id()][tdim-1]

    for color, tags in enumerate(color_to_tag_map):
        # Precompute for the 2 tags
        submeshes = [subdomain_meshes[tag] for tag in tags]
        
        for cell in df.SubsetIterator(interface_mesh.marking_function, color):
            cell_index = cell.index()
            # The corresponding global cell facet
            facet = c2f[cell_index]
            # The two cells in global mesh numbering
            global_cells = tagged_iface[tags][facet]
            # Let's find the facet in submesh
            for tag, gc, submesh in zip(tags, global_cells, submeshes):
                # The map uses local cell
                local_cell = c2c[tag][gc]
                mesh_id = submesh.id()
                
                found = False
                for submesh_facet in df.facets(df.Cell(submesh, local_cell)):
                    found = df.near(cell.midpoint().distance(submesh_facet.midpoint()), 0, tol)
                    if found:
                        interface_map[mesh_id][cell_index] = submesh_facet.index()
                        break

    # Collapse to list; I want list indexing
    subdomain_meshes = np.array([subdomain_meshes[m] for m in markers]) 
    color_map = [map(markers.index, tags) for tags in color_to_tag_map]

    # Parent in the sense that the colored piece of interface
    # could have been created from mesh
    interface_mesh.parent_entity_map.update(
        dict((k, {tdim-1: v}) for k, v in interface_map.items())
    )

    return subdomain_meshes, interface_mesh, color_map
Ejemplo n.º 49
0
Archivo: test.py Proyecto: alogg/dolfin
    def test_convert_triangle(self): # Disabled because it fails, see FIXME below
        # test no. 1
        from dolfin import Mesh, MPI
        if MPI.num_processes() != 1:
            return
        fname = os.path.join("data", "triangle")
        dfname = fname+".xml"
        
        # Read triangle file and convert to a dolfin xml mesh file
        meshconvert.triangle2xml(fname, dfname)

        # Read in dolfin mesh and check number of cells and vertices
        mesh = Mesh(dfname)
        self.assertEqual(mesh.num_vertices(), 96)
        self.assertEqual(mesh.num_cells(), 159)

        # Clean up
        os.unlink(dfname)


        # test no. 2
        from dolfin import MPI, Mesh, MeshFunction, \
                           edges, Edge, faces, Face, \
                           SubsetIterator, facets, CellFunction
        if MPI.num_processes() != 1:
            return
        fname = os.path.join("data", "test_Triangle_3")
        dfname = fname+".xml"
        dfname0 = fname+".attr0.xml"

        # Read triangle file and convert to a dolfin xml mesh file
        meshconvert.triangle2xml(fname, dfname)

        # Read in dolfin mesh and check number of cells and vertices
        mesh = Mesh(dfname)
        mesh.init()
        mfun = MeshFunction('double', mesh, dfname0)
        self.assertEqual(mesh.num_vertices(), 58)
        self.assertEqual(mesh.num_cells(), 58)

        # Create a size_t CellFunction and assign the values based on the
        # converted Meshfunction
        cf = CellFunction("size_t", mesh)
        cf.array()[mfun.array()==10.0] = 0
        cf.array()[mfun.array()==-10.0] = 1

        # Meassure total area of cells with 1 and 2 marker
        add = lambda x, y : x+y
        area0 = reduce(add, (Face(mesh, cell.index()).area() \
                             for cell in SubsetIterator(cf, 0)), 0.0)
        area1 = reduce(add, (Face(mesh, cell.index()).area() \
                             for cell in SubsetIterator(cf, 1)), 0.0)
        total_area = reduce(add, (face.area() for face in faces(mesh)), 0.0)

        # Check that all cells in the two domains are either above or below y=0
        self.assertTrue(all(cell.midpoint().y()<0 for cell in SubsetIterator(cf, 0)))
        self.assertTrue(all(cell.midpoint().y()>0 for cell in SubsetIterator(cf, 1)))
        
        # Check that the areas add up
        self.assertAlmostEqual(area0+area1, total_area)
        
        # Measure the edge length of the two edge domains
        edge_markers = mesh.domains().facet_domains()
        self.assertTrue(edge_markers is not None)
        length0 = reduce(add, (Edge(mesh, e.index()).length() \
                            for e in SubsetIterator(edge_markers, 0)), 0.0)
        length1 = reduce(add, (Edge(mesh, e.index()).length() \
                            for e in SubsetIterator(edge_markers, 1)), 0.0)
        
        # Total length of all edges and total length of boundary edges
        total_length = reduce(add, (e.length() for e in edges(mesh)), 0.0)
        boundary_length = reduce(add, (Edge(mesh, f.index()).length() \
                          for f in facets(mesh) if f.exterior()), 0.0)
        
        # Check that the edges add up
        self.assertAlmostEqual(length0+length1, total_length)
        self.assertAlmostEqual(length1, boundary_length)

        # Clean up
        os.unlink(dfname)
        os.unlink(dfname0)