Esempio n. 1
0
def facet_info_and_dofmap(V):
    """
    Return three lists

      1) A list which maps facet index to dof
      2) A list which maps facet index to facet area
      2) A list which maps facet index to facet midpoint
    """
    mesh = V.mesh()
    dofmap = V.dofmap()

    ndim = V.ufl_cell().topological_dimension()

    # Loop through cells and get dofs for each cell
    facet_dofs = [None] * mesh.num_facets()
    facet_area = [None] * mesh.num_facets()
    facet_midp = [None] * mesh.num_facets()
    for cell in dolfin.cells(mesh):
        dofs = dofmap.cell_dofs(cell.index())
        facet_idxs = cell.entities(ndim - 1)

        # Only works for functions with one dof on each facet
        assert len(dofs) == len(facet_idxs)

        # Loop through connected facets and store dofs for each facet
        for i, fidx in enumerate(facet_idxs):
            facet_dofs[fidx] = dofs[i]
            facet_area[fidx] = cell.facet_area(i)
            mp = dolfin.Facet(mesh, fidx).midpoint()
            facet_midp[fidx] = (mp.x(), mp.y())

    return facet_dofs, facet_area, facet_midp
Esempio n. 2
0
 def get_normal(self, mesh):
     facet_iter = df.SubsetIterator(self.boundaries, self.id)
     normal = np.empty((self.num_facets, self.g_dim))
     for i, facet in enumerate(facet_iter):
         fs = df.Facet(mesh, facet.index())
         normal[i, :] = -1 * \
             np.array([fs.normal()[j] for j in range(self.g_dim)])
     return normal
Esempio n. 3
0
def _transferFacetMeshFun(fun, subfun, zero):
    # get meshes
    mesh = fun.mesh()
    submesh = subfun.mesh()
    # cell mapping
    parent_cell_indices = submesh.data().array("parent_cell_indices",
                                               3).astype(np.int)
    parent_vert_indices = submesh.data().array("parent_vertex_indices",
                                               0).astype(np.int)
    # space dimension
    dim = fun.mesh().geometry().dim()
    # initialize facets
    submesh.init(dim - 1, dim)
    # loop over cell on parent mesh
    for parent_cell in dlfn.cells(mesh):
        parent_cell_id = parent_cell.index()
        # loop over facet of parent cell
        for parent_facet_id in parent_cell.entities(dim - 1).astype(np.int):
            if fun[parent_facet_id] != zero:
                # get parent vertices
                parent_facet = dlfn.Facet(mesh, parent_facet_id)
                parent_facet_vert_ids = parent_facet.entities(0)
                # find matching cell in sub mesh (invert mapping)
                cell_id = np.where(parent_cell_indices == parent_cell_id)[0]
                if cell_id.size > 0:
                    assert cell_id.size == 1
                    cell = dlfn.Cell(submesh, cell_id[0])
                    # loop over child facet
                    for facet_id in cell.entities(dim - 1):
                        facet = dlfn.Facet(submesh, facet_id)
                        facet_match = True
                        for vert_id in facet.entities(0):
                            if parent_vert_indices[
                                    vert_id] not in parent_facet_vert_ids:
                                facet_match = False
                                break
                        if facet_match == True:
                            subfun.set_value(facet_id, fun[parent_facet_id])
                            break
Esempio n. 4
0
def surface_normal(tag, facet_f, point):
    '''Normal of taged surface which points away from the point'''
    # NOTE: as this is a constant it will only work for a flat surface
    mesh = facet_f.mesh()
    tdim = facet_f.dim()
    assert tdim == mesh.topology().dim() - 1
    assert mesh.geometry().dim() == 3

    point = df.Point(*point)
    facets, = np.where(facet_f.array() == tag)
    facets = iter(facets)

    first = df.Facet(mesh, next(facets))
    n = first.normal()
    # Is this a flat surface
    assert all(
        abs(abs(df.Facet(mesh, f).normal().dot(n)) - 1) < 1E-10
        for f in facets)

    mid = first.midpoint()

    return n.array() if n.dot(mid - point) > 0 else -1 * n.array()
Esempio n. 5
0
def boring(mesh_2d, inner_size):
    '''
    A mesh2d is assumed to be be a cube [-inner_size, inner_size]^2.
    The curve is mostly a collection of boundary edges.
    '''
    facet_f = df.MeshFunction('size_t', mesh_2d, 1, 0)
    mesh_2d.init(2, 1)

    # Mesh for the curve is tricky as we need to find the line in the faces
    def union(domains, A=inner_size, tol=1E-10):
        def body(domains):
            if isinstance(domains, str):
                if domains:
                    return '( %s )' % domains
                else:
                    return ''
            else:
                return ' || '.join(map(body, domains))

        return df.CompiledSubDomain(body(domains), A=A, tol=tol)

    lines = {
        4:
        union('near(x[1], A, tol) && near(x[2], A, tol)'),
        3:
        union('near(x[2], -x[0], tol)'),
        2:
        union('near(x[2], x[1], tol)'),
        1:
        union([
            'near(x[0], -A, tol) && near(x[2], -A, tol)',
            'near(x[1], A, tol) && near(x[0], -A, tol)',
            'near(x[1], -A, tol) && near(x[0], -A, tol)'
        ])
    }

    for tag, line in lines.items():
        # Get candidates
        facets = set(
            sum((cell.entities(1).tolist()
                 for cell in df.SubsetIterator(mesh_2d.marking_function, tag)),
                []))
        for facet in facets:
            if line.inside(df.Facet(mesh_2d, facet).midpoint().array(), True):
                facet_f[int(facet)] = 1

    return facet_f
Esempio n. 6
0
    def get_basis(self, mesh, vertices):
        facet_iter = df.SubsetIterator(self.boundaries, self.id)
        basis = np.empty((self.num_facets * self.g_dim, self.g_dim))
        for i, facet in enumerate(facet_iter):
            fs = df.Facet(mesh, facet.index())

            basis[i * self.g_dim, :] = vertices[i*self.g_dim, :] -\
                                       vertices[i*self.g_dim+1, :]
            basis[i * self.g_dim, :] /= np.linalg.norm(basis[i *
                                                             self.g_dim, :])
            basis[self.g_dim*(i+1)-1, :] = -1 * \
                np.array([fs.normal()[j] for j in range(self.g_dim)])
            if (self.g_dim == 3):
                basis[i*self.g_dim + 1, :] = \
                    np.cross(basis[self.g_dim*(i+1)-1, :],
                             basis[i*self.g_dim, :])
        return basis
Esempio n. 7
0
        emesh = df.BoundaryMesh(mesh, 'exterior')

        time = df.Timer('map')
        time.start()
        mapping = build_embedding_map(emesh, mesh, tol=1E-14)
        dt = time.stop()

        mesh_x = mesh.coordinates()
        emesh_x = emesh.coordinates()

        assert max(
            np.linalg.norm(ex - mesh_x[to])
            for ex, to in zip(emesh_x, mapping[0])) < 1E-14

        assert max(
            df.Facet(mesh, entity).midpoint().distance(
                df.Cell(emesh, cell).midpoint())
            for cell, entity in enumerate(mapping[1])) < 1E-14

        if n0 is not None:
            rate = np.log(dt / dt0) / np.log(float(n) / n0)
        else:
            rate = np.nan
        print n, dt, rate
        n0, dt0 = n, dt

    # Check creation
    mesh = df.UnitCubeMesh(10, 10, 10)

    f = df.MeshFunction('size_t', mesh, mesh.topology().dim() - 1, 0)
    chi = df.CompiledSubDomain('near(x[i], 0.5)', i=0)
    for i in range(3):
Esempio n. 8
0
    def pbc_facet_function(part_vectors,
                           mesh,
                           facet_function,
                           per_choice: dict,
                           dim=2,
                           tol=GEO_TOLERANCE):
        """[summary]

        Parameters
        ----------
        part_vectors : np.array
        mesh : Mesh
        facet_function : MeshFunction
        per_choice : dict
            key can be : 'X', 'Y'
            values : tuple (value of facetfunction for master, value for slave)
            Ex : {'X' : (3,5)}
        tol : float, optional

        Returns
        -------
        PeriodicDomain
        """

        # ! Not tested yet
        basis = list()
        for i in range(np.size(part_vectors, 1)):
            basis.append(fe.as_vector(part_vectors[:, i]))
        per_values = [val for couple in per_choice for val in couple]
        coordinates = dict()
        mesh.init(1,
                  0)  # Compute connectivity between given pair of dimensions.
        for val in per_values:
            points_for_val = list()
            facet_idces = facet_function.where_equal(val)
            for i in facet_idces:
                vertices_idces = fe.Facet(mesh, i).entities(0)
                for j in vertices_idces:
                    coord = fe.Vertex(mesh, j).point().array()
                    points_for_val.append(coord)
            coordinates[val] = points_for_val
        master_tests, slave_tests, per_vectors = list(), list(), list()
        for key, (master_idx, slave_idx) in per_choice.items():

            def master_test(x):
                return any(
                    np.allclose(x, pt, atol=tol)
                    for pt in coordinates[master_idx])

            def slave_test(x):
                return any(
                    np.allclose(x, pt, atol=tol)
                    for pt in coordinates[slave_idx])

            master_tests.append(master_test)
            slave_tests.append(slave_test)
            if key.lower() == "x":
                per_vectors.append(basis[0])
            elif key.lower() == "y":
                per_vectors.append(basis[1])

        return PeriodicDomain(per_vectors, master_tests, slave_tests, dim, tol)