예제 #1
0
def poincare_const(o, p, d=1):
    # Vectorial Poincare, see [Blechta, Malek, Vohralik 2016]
    if d != 1 and p != 2.0:
        return d**abs(0.5-1.0/p) * poincare_const(o, p)

    if isinstance(o, Mesh):
        raise NotImplementedError("Poincare constant not implemented on mesh!")

    if isinstance(o, Cell):
        assert _is_simplex(o), "Poincare constant not " \
                "implemented on non-simplicial cells!"
        h = max(e.length() for e in edges(o))
        return h*_poincare_convex(p)

    if isinstance(o, CellType):
        assert _is_simplex(o), "Poincare constant not " \
                "implemented on non-simplicial cells!"
        return _poincare_convex(p)

    if isinstance(o, Vertex):
        # TODO: fix using ghosted mesh
        not_working_in_parallel("Poincare computation on patch")
        h = max(v0.point().distance(v1.point())
                for c0 in cells(o) for v0 in vertices(c0)
                for c1 in cells(o) for v1 in vertices(c1))
        # FIXME: Implement a check for convexity of the patch
        _warn_poincare_convex()
        return h*_poincare_convex(p)

    raise NotImplementedError
예제 #2
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
예제 #3
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)
예제 #4
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
예제 #5
0
def friedrichs_const(o, p):
    if isinstance(o, Vertex):
        # TODO: fix using ghosted mesh
        not_working_in_parallel("Friedrichs computation on patch")
        d = max(v0.point().distance(v1.point())
                for c0 in cells(o) for v0 in vertices(c0)
                for c1 in cells(o) for v1 in vertices(c1))
        # FIXME: Implement the check
        _warn_friedrichs_lines()
        return d

    raise NotImplementedError
예제 #6
0
    def __init__(self, mesh):

        try:
            from scipy import spatial

        except ImportError:
            logger.warning(
                (
                    "Scipy is not install. Residual in the unloading "
                    "algorithm cannot be computed. Please install "
                    'scipy "pip install scipy" if you want to compute '
                    "the residual"
                )
            )
            self.bbtree = None

        else:

            self.mesh = mesh
            d = self.mesh.topology().dim()
            local_points = [v.point() for v in dolfin.vertices(self.mesh)]
            coords = [(p.x(), p.y(), p.z()) for p in local_points]

            # FIXME
            coords = numpy_mpi.gather_broadcast(np.array(coords).flatten())
            coords.resize(int(len(coords) / d), d)

            self.bbtree = spatial.KDTree(coords)
예제 #7
0
    def _extract_coupling_boundary_edges(self, id_mapping):
        """Extracts edges of mesh which lie on the boundary.
        :return: two arrays of vertex IDs. Array 1 consists of first points of all edges
        and Array 2 consists of second points of all edges

        NOTE: Edge calculation is only relevant in 2D cases.
        """

        vertices = dict()

        for v1 in dolfin.vertices(self._mesh_fenics):
            if self._coupling_subdomain.inside(v1.point(), True):
                vertices[v1] = []

        for v1 in vertices.keys():
            for v2 in vertices.keys():
                if self._are_connected_by_edge(v1, v2):
                    vertices[v1] = v2
                    vertices[v2] = v1

        vertices1_ids = []
        vertices2_ids = []

        for v1, v2 in vertices.items():
            if v1 is not v2:
                vertices1_ids.append(id_mapping[v1.global_index()])
                vertices2_ids.append(id_mapping[v2.global_index()])

        vertices1_ids = np.array(vertices1_ids)
        vertices2_ids = np.array(vertices2_ids)

        return vertices1_ids, vertices2_ids
예제 #8
0
def test_pointsource_vector_fs(mesh, point):
    """Tests point source when given constructor PointSource(V, point,
    mag) with a vector for a vector function space that isn't placed
    at a node for 1D, 2D and 3D. Global points given to constructor
    from rank 0 processor.

    """

    rank = MPI.rank(mesh.mpi_comm())
    V = VectorFunctionSpace(mesh, "CG", 1)
    v = TestFunction(V)
    b = assemble(dot(Constant([0.0]*mesh.geometry().dim()), v)*dx)
    if rank == 0:
        ps = PointSource(V, point, 10.0)
    else:
        ps = PointSource(V, [])
    ps.apply(b)

    # Checks array sums to correct value
    b_sum = b.sum()
    assert round(b_sum - 10.0*V.num_sub_spaces()) == 0

    # Checks point source is added to correct part of the array
    v2d = vertex_to_dof_map(V)
    for v in vertices(mesh):
        if near(v.midpoint().distance(point), 0.0):
            for spc_idx in range(V.num_sub_spaces()):
                ind = v2d[v.index()*V.num_sub_spaces() + spc_idx]
                if ind < len(b.get_local()):
                    assert np.round(b.get_local()[ind] - 10.0) == 0
예제 #9
0
def test_pointsource_matrix_second_constructor(mesh, point):
    """Tests point source when given different constructor PointSource(V1,
    V2, point, mag) with a matrix and when placed at a node for 1D, 2D
    and 3D. Global points given to constructor from rank 0
    processor. Currently only implemented if V1=V2.

    """

    V1 = FunctionSpace(mesh, "CG", 1)
    V2 = FunctionSpace(mesh, "CG", 1)

    rank = MPI.rank(mesh.mpi_comm())
    u, v = TrialFunction(V1), TestFunction(V2)
    w = Function(V1)
    A = assemble(Constant(0.0)*u*v*dx)
    if rank == 0:
        ps = PointSource(V1, V2, point, 10.0)
    else:
        ps = PointSource(V1, V2, [])
    ps.apply(A)

    # Checks array sums to correct value
    a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array()))
    assert round(a_sum - 10.0) == 0

    # Checks point source is added to correct part of the array
    A.get_diagonal(w.vector())
    v2d = vertex_to_dof_map(V1)
    for v in vertices(mesh):
        if near(v.midpoint().distance(point), 0.0):
            ind = v2d[v.index()]
            if ind < len(A.array()):
                assert np.round(w.vector()[ind] - 10.0) == 0
예제 #10
0
    def create_3d_mesh(self, mesh):

        nv = mesh.num_vertices()
        nc = mesh.num_cells()
        h = self.thickness

        mesh3 = df.Mesh()
        editor = df.MeshEditor()
        editor.open(mesh3, 3, 3)
        editor.init_vertices(2 * nv)
        editor.init_cells(3 * nc)

        for v in df.vertices(mesh):
            i = v.index()
            p = v.point()
            editor.add_vertex(i, p.x(), p.y(), 0)
            editor.add_vertex(i + nv, p.x(), p.y(), h)

        gid = 0
        for c in df.cells(mesh):
            i, j, k = c.entities(0)
            editor.add_cell(gid, i, j, k, i + nv)
            gid = gid + 1
            editor.add_cell(gid, j, j + nv, k, i + nv)
            gid = gid + 1
            editor.add_cell(gid, k, k + nv, j + nv, i + nv)
            gid = gid + 1

        editor.close()
        return mesh3
예제 #11
0
 def shape(self, mesh, size=50):
     """Build mesh."""
     vf = np.vectorize(self.f)
     x = mesh.coordinates()[:, 0]
     y = mesh.coordinates()[:, 1]
     a = np.arctan2(y, x)
     x, y = [x * vf(a), y * vf(a)]
     mesh.coordinates()[:] = np.array([x, y]).transpose()
     boundary = BoundaryMesh(mesh, 'exterior')
     boundary.init()
     lst = [0]
     vs = list(vertices(boundary))
     while True:
         v = vs[lst[-1]]
         neighbors = set()
         for e in edges(v):
             neighbors.update(e.entities(0))
         neighbors.remove(v.index())
         neighbors = list(neighbors)
         k = 0
         if len(lst) > 1:
             if neighbors[0] == lst[-2]:
                 k = 1
         lst.append(neighbors[k])
         if lst[-1] == lst[0]:
             break
     lst = lst[:-1]
     points = boundary.coordinates()[lst]
     points = [Point(*p) for p in points]
     try:
         polygon = Polygon(points)
     except:
         polygon = Polygon(points[::-1])
     return generate_mesh(polygon, size)
예제 #12
0
def find_low(mesh, V, Ause):

    V2dm = V.dofmap()
    cq2 = MeshQuality.radius_ratios(mesh)
    cq = cq2.array()

    indices = np.where(cq < 0.1)[0]

    dof_set = []
    cell_set = []
    for i in indices:
        cell = Cell(mesh, i)
        for v in vertices(cell):
            for c in cells(v):
                cell_set += [c.index()]
                dof_set.extend(V2dm.cell_dofs(c.index()))

    bad_set = list(set(dof_set))
    bad_cells = list(set(cell_set))

    # print('BAD CELLS=', bad_cells)
    # print(len(bad_cells))
    # print('BAD DOFS=', bad_dofs)
    # print(len(bad_dofs))

    # check redundancy
    re_dofs = []
    for d1 in bad_set:
        for d2 in bad_set:
            if Ause[d1, d2] != 0:
                re_dofs.append(d2)

    bad_dofs = list(set(re_dofs))

    return bad_dofs
예제 #13
0
 def shape(self, mesh, size=50):
     """Build mesh."""
     vf = np.vectorize(self.f)
     x = mesh.coordinates()[:, 0]
     y = mesh.coordinates()[:, 1]
     a = np.arctan2(y, x)
     x, y = [x * vf(a), y * vf(a)]
     mesh.coordinates()[:] = np.array([x, y]).transpose()
     boundary = BoundaryMesh(mesh, 'exterior')
     boundary.init()
     lst = [0]
     vs = list(vertices(boundary))
     while True:
         v = vs[lst[-1]]
         neighbors = set()
         for e in edges(v):
             neighbors.update(e.entities(0))
         neighbors.remove(v.index())
         neighbors = list(neighbors)
         k = 0
         if len(lst) > 1:
             if neighbors[0] == lst[-2]:
                 k = 1
         lst.append(neighbors[k])
         if lst[-1] == lst[0]:
             break
     lst = lst[:-1]
     points = boundary.coordinates()[lst]
     points = [Point(*p) for p in points]
     try:
         polygon = Polygon(points)
     except:
         polygon = Polygon(points[::-1])
     return generate_mesh(polygon, size)
예제 #14
0
def test_pointsource_vector_fs(mesh, point):
    """Tests point source when given constructor PointSource(V, point,
    mag) with a vector for a vector function space that isn't placed
    at a node for 1D, 2D and 3D. Global points given to constructor
    from rank 0 processor.

    """

    rank = MPI.rank(mesh.mpi_comm())
    V = VectorFunctionSpace(mesh, "CG", 1)
    v = TestFunction(V)
    b = assemble(dot(Constant([0.0] * mesh.geometry().dim()), v) * dx)
    if rank == 0:
        ps = PointSource(V, point, 10.0)
    else:
        ps = PointSource(V, [])
    ps.apply(b)

    # Checks array sums to correct value
    b_sum = b.sum()
    assert round(b_sum - 10.0 * V.num_sub_spaces()) == 0

    # Checks point source is added to correct part of the array
    v2d = vertex_to_dof_map(V)
    for v in vertices(mesh):
        if near(v.midpoint().distance(point), 0.0):
            for spc_idx in range(V.num_sub_spaces()):
                ind = v2d[v.index() * V.num_sub_spaces() + spc_idx]
                if ind < len(b.get_local()):
                    assert np.round(b.get_local()[ind] - 10.0) == 0
예제 #15
0
def test_pointsource_matrix_second_constructor(mesh, point):
    """Tests point source when given different constructor PointSource(V1,
    V2, point, mag) with a matrix and when placed at a node for 1D, 2D
    and 3D. Global points given to constructor from rank 0
    processor. Currently only implemented if V1=V2.

    """

    V1 = FunctionSpace(mesh, "CG", 1)
    V2 = FunctionSpace(mesh, "CG", 1)

    rank = MPI.rank(mesh.mpi_comm())
    u, v = TrialFunction(V1), TestFunction(V2)
    w = Function(V1)
    A = assemble(Constant(0.0) * u * v * dx)
    if rank == 0:
        ps = PointSource(V1, V2, point, 10.0)
    else:
        ps = PointSource(V1, V2, [])
    ps.apply(A)

    # Checks array sums to correct value
    a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array()))
    assert round(a_sum - 10.0) == 0

    # Checks point source is added to correct part of the array
    A.get_diagonal(w.vector())
    v2d = vertex_to_dof_map(V1)
    for v in vertices(mesh):
        if near(v.midpoint().distance(point), 0.0):
            ind = v2d[v.index()]
            if ind < len(A.array()):
                assert np.round(w.vector()[ind] - 10.0) == 0
예제 #16
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
예제 #17
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)
예제 #18
0
    def _extract_coupling_boundary_vertices(self):
        """Extracts vertices which lie on the boundary.
        :return: stack of vertices
        """
        n = 0
        vertices_x = []
        vertices_y = []
        if self._dimensions == 3:
            vertices_z = []

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

        for v in dolfin.vertices(self._mesh_fenics):
            if self._coupling_subdomain.inside(v.point(), True):
                n += 1
                vertices_x.append(v.x(0))
                if self._dimensions == 2:
                    vertices_y.append(v.x(1))
                elif self._can_apply_2d_3d_coupling():
                    vertices_y.append(v.x(1))
                    vertices_z.append(0)
                else:
                    raise Exception("Dimensions do not match!")

        assert(n != 0), "No coupling boundary vertices detected"

        if self._dimensions == 2:
            return np.stack([vertices_x, vertices_y]), n
        elif self._dimensions == 3:
            return np.stack([vertices_x, vertices_y, vertices_z]), n
예제 #19
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)
예제 #20
0
    def test_contains(self):

        values = [1,2,3]

        t = IonTag('foo',3,'int', self.mesh)

        for v in vertices(self.mesh):
            # testing setter
            t[v] = values

        v = MeshEntity(self.mesh,0,1)

        # testing getter
        self.assertTrue((t[v] == values).all())

        #---------------------------------------------------------------------------------------
        # Delete a tag entry (for an entity)
        #---------------------------------------------------------------------------------------

        # choose an entity to delete
        entity_tuple = (v.dim(),v.index())

        # check that tag has the entity, v, in it
        self.assertTrue(t.__contains__(entity_tuple))

        del t._entity_values[entity_tuple]

        # check that the tag no longer has the entity, v, in it
        self.assertFalse(t.__contains__(entity_tuple))
    def generate(self, N):
        """
        Generate a random set of N points per cell.

        Parameters
        ----------
        N: int
            Number of points per cell.
        Returns
        -------
        np.ndarray
            Coordinate array of points.
        """

        # TODO - number of points per cell could be random too, with a minimum
        # value, and should be related to the cell volume.
        points_inside = []

        for c in cells(self.mesh):
            pts = [v.point().array() for v in vertices(c)]

            for i in range(N):
                x = self._random_bary(len(pts))
                points_inside.append(sum([a * b for (a, b) in zip(x, pts)]))

        points_inside = np.array(points_inside)

        if self.mesh.geometry().dim() == 2:
            points_inside = points_inside[:, :2]

        return points_inside
예제 #22
0
    def extract_coupling_boundary_vertices(self):
        """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
        vertices_x = []
        vertices_y = []
        if self._dimensions == 3:
            vertices_z = []

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

        for v in dolfin.vertices(self._mesh_fenics):
            if self._coupling_subdomain.inside(v.point(), True):
                n += 1
                vertices_x.append(v.x(0))
                vertices_y.append(v.x(1))
                if self._dimensions == 3:
                    # todo this has to be fixed for "proper" 3D coupling. Currently this is a workaround for the coupling of 2D fenics with pseudo 3D openfoam
                    vertices_z.append(0)

        if self._dimensions == 2:
            return np.stack([vertices_x, vertices_y]), n
        elif self._dimensions == 3:
            return np.stack([vertices_x, vertices_y, vertices_z]), n
예제 #23
0
    def get_vertices(self):
        facet_iter = df.SubsetIterator(self.boundaries, self.id)
        vertices = np.empty((self.num_facets * self.g_dim, self.g_dim))
        for i, facet in enumerate(facet_iter):
            for j, v in enumerate(df.vertices(facet)):
                vertices[i * self.g_dim +
                         j, :] = v.point().array()[:self.g_dim]

        return vertices
예제 #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
예제 #25
0
    def test_len(self):

        # Initial step: Feed in values to the vertices in the mesh
        t = IonTag('foo',1,'int', self.mesh)

        for x,v in enumerate(vertices(self.mesh)):
            t[v] = (x,)

        # test len
        self.assertEqual(len(t), self.mesh.num_vertices())
예제 #26
0
    def __init__(self, mesh):
        self.mesh = mesh
        d = self.mesh.topology().dim()
        self.bbtree = df.BoundingBoxTree()
        local_points = [v.point() for v in df.vertices(self.mesh)]
        coords = [(p.x(), p.y(), p.z()) for p in local_points]

        coords = numpy_mpi.gather_broadcast(np.array(coords).flatten())
        coords.resize(len(coords) / d, d)
        glob_points = [df.Point(p) for p in coords]
        self.bbtree.build(glob_points, 3)
예제 #27
0
    def test_len(self):

        t = IonTag('foo',3,'int', self.mesh)

        # we create a tag entry for every vertex of the mesh
        for v in vertices(self.mesh):
            # testing setter
            t[v] = [1,2,3]

        # we check that the number of tag entries is the same as the number we created
        self.assertEqual(len(t), self.mesh.num_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
    def __init__(self, mesh, cell_id, particle):
        # Initialize parent -- create Cell with id on mesh
        df.Cell.__init__(self, mesh, cell_id)
        # Make an empty list of particles that I carry
        self.particles = []
        self += particle
        # Make the cell aware of its neighbors; neighbor cells are cells
        # connected to this one by vertices
        tdim = mesh.topology().dim()

        neighbors = sum((vertex.entities(tdim).tolist() for vertex in df.vertices(self)), [])
        neighbors = set(neighbors) - set([cell_id])   # Remove self
        self.neighbors = map(lambda neighbor_index: df.Cell(mesh, neighbor_index),
                             neighbors)
예제 #30
0
    def __init__(self, mesh, cell_id, particle):
        # Initialize parent -- create Cell with id on mesh
        df.Cell.__init__(self, mesh, cell_id)
        # Make an empty list of particles that I carry
        self.particles = []
        self += particle
        # Make the cell aware of its neighbors; neighbor cells are cells
        # connected to this one by vertices
        tdim = mesh.topology().dim()

        neighbors = sum((vertex.entities(tdim).tolist() for vertex in df.vertices(self)), [])
        neighbors = set(neighbors) - set([cell_id])   # Remove self
        self.neighbors = map(lambda neighbor_index: df.Cell(mesh, neighbor_index),
                             neighbors)
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_surface_points(marker):
    coordinates = []
    idxs = []
    # Loop over the facets
    for facet in df.facets(geometry.mesh):
        # If the facet markers matched that of ENDO
        if geometry.ffun[facet] == marker:
            # Loop over the vertices of that facets
            for vertex in df.vertices(facet):
                idxs.append(vertex.global_index())
                # coordinates.append(tuple(vertex.midpoint().array()))
    # Remove duplicates
    idxs = np.array(list(set(idxs)))
    coordinates = geometry.mesh.coordinates()[idxs]
    return coordinates, idxs
예제 #33
0
 def convert_mesh_to_grid(self, mesh):
     grid = vtkUnstructuredGrid()
     points = vtkPoints()
     cell_array = vtkCellArray()
     for v in vertices(mesh):
         vp = v.point()
         points.InsertNextPoint(vp.x(), vp.y(), vp.z())
     for c in cells(mesh):
         t = vtkTetra()
         for i, v in enumerate(c.entities(0)):
             t.GetPointIds().SetId(i, v)
         cell_array.InsertNextCell(t)
     grid.SetPoints(points)
     grid.SetCells(VTK_TETRA, cell_array)
     return grid
예제 #34
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
예제 #35
0
def mesh(Lx=1., Ly=1., grid_spacing=1. / 16, refine_depth=3, **namespace):
    m = df.RectangleMesh(df.Point(0., 0.), df.Point(Lx, Ly),
                         int(Lx / grid_spacing), int(Ly / grid_spacing))
    # x = m.coordinates()[:]

    # beta = 0.0
    # x[:, 1] = beta*x[:, 1] + (1.-beta)*Ly*(
    #     np.arctan(1.0*np.pi*((x[:, 1]-Ly)/Ly))/np.arctan(np.pi) + 1.)

    for level in range(1, refine_depth + 1):
        cell_markers = df.MeshFunction("bool", m, m.topology().dim())
        cell_markers.set_all(False)
        for cell in df.cells(m):
            y_mean = np.mean([node.x(1) for node in df.vertices(cell)])
            if y_mean < 1. / 2**level:
                cell_markers[cell] = True
        m = df.refine(m, cell_markers)

    return m
예제 #36
0
    def _extract_coupling_boundary_edges(self):
        """Extracts edges of mesh which lie on the boundary.
        :return: two arrays of vertex IDs. Array 1 consists of first points of all edges
        and Array 2 consists of second points of all edges

        NOTE: Edge calculation is only relevant in 2D cases.
        """

        n = 0
        vertices = dict()

        for v1 in dolfin.vertices(self._mesh_fenics):
            if self._coupling_subdomain.inside(v1.point(), True):
                vertices[v1] = []
                n += 1

        for v1 in vertices.keys():
            for v2 in vertices.keys():
                if self._are_connected_by_edge(v1, v2):
                    vertices[v1] = v2
                    vertices[v2] = v1

        vertices_1 = []
        vertices_2 = []

        for v1, v2 in vertices.items():
            vertices_1.append(v1.x(0))
            vertices_1.append(v1.x(1))
            vertices_2.append(v2.x(0))
            vertices_2.append(v2.x(1))

        vertices_1 = np.array(vertices_1)
        vertices_2 = np.array(vertices_2)
        vertices1_ids = np.zeros(n)
        vertices2_ids = np.zeros(n)

        self._interface.get_mesh_vertex_ids_from_positions(
            self._mesh_id, n, vertices_1, vertices1_ids)
        self._interface.get_mesh_vertex_ids_from_positions(
            self._mesh_id, n, vertices_2, vertices2_ids)

        return vertices1_ids, vertices2_ids
예제 #37
0
    def __init__(self, mesh, bnd):
        self.mesh = mesh

        # Allocate a list of particles for each cell
        for cell in df.cells(self.mesh):
            self.append(list())

        # Create a list of sets of neighbors for each cell
        self.t_dim = self.mesh.topology().dim()
        self.g_dim = self.mesh.geometry().dim()

        self.mesh.init(0, self.t_dim)
        self.tree = self.mesh.bounding_box_tree()
        self.neighbors = list()
        for cell in df.cells(self.mesh):
            neigh = sum([vertex.entities(self.t_dim).tolist() for vertex in df.vertices(cell)], [])
            neigh = set(neigh) - set([cell.index()])
            self.neighbors.append(neigh)

        self.init_localizer(bnd)
예제 #38
0
    def test_iter(self):
        # test the iterator and verify that the correct type is passed back

        #------------------------------------------------------------
        # Initial step: Feed in values to the vertices in the mesh
        #------------------------------------------------------------

        t = IonTag('foo',1,'int', self.mesh)

        for x,v in enumerate(vertices(self.mesh)):
            t[v] = (x,)

        #------------------------------------------------------------
        # Test the iteration over the tags
        #------------------------------------------------------------

        for key, item in t.iteritems():
            self.assertEqual(t[ key ], item  )
            self.assertTrue(isinstance(key, MeshEntity))
            self.assertTrue(isinstance(item[0], int ))
예제 #39
0
def voronoi_volume_approx(V, inv=True, raw=True):
    """
    Returns the approximated volume for every Voronoi cell centered at
    the a DOF as a FEniCS function. V is the function space for the function
    to be returned (must be CG1). Works for
    1D, 2D and 3D, with and without periodic boundaries and objects.

    The approximated volume of a Voronoi cell centered at a vertex is the
    sum of the neighboring cells divided by the number of geometric dimensions
    plus one. This approximation is better the closer to equilateral the cells
    are, a feature which is desirable in a FEM mesh anyhow.

    Curiously, the result of this function happens to be exact not only for
    completely equilateral cells, but also for entirely periodic simple
    meshes as created using simple_mesh(). For non-periodic simple meshes it
    becomes inaccurate on the boundary nodes. The total volume of all cells is
    always correct.
    """
    assert V.ufl_element().family() == 'Lagrange'
    assert V.ufl_element().degree() == 1

    n_dofs = V.dim()
    dof_indices = df.vertex_to_dof_map(V)
    volumes = np.zeros(n_dofs)

    # These loops inherently deal with periodic boundaries
    for i, v in enumerate(df.vertices(V.mesh())):
        for c in df.cells(v):
            volumes[dof_indices[i]] += c.volume()

    volumes /= (V.mesh().geometry().dim() + 1)

    if inv:
        volumes = volumes**(-1)

    if raw:
        return volumes
    else:
        dv = df.Function(V)
        dv.vector()[:] = volumes
        return dv
예제 #40
0
def dolfinFindClosestPoint(mesh, coords):
    """
    Given some point and a mesh, returns the coordinates of the nearest vertex
    """
    p = d.Point(coords)
    L = list(d.vertices(mesh))
    distToVerts = [np.linalg.norm(p.array() - x.midpoint().array()) for x in L]
    minDist = min(distToVerts)
    minIdx = distToVerts.index(minDist) # returns the local index (wrt the cell) of the closest point

    closestPoint = L[minIdx].midpoint().array()

    if size > 1:
        min_dist_global, min_idx = comm.allreduce((minDist,rank), op=pyMPI.MINLOC)

        if rank == min_idx:
            comm.Send(closestPoint, dest=root)

        if rank == root:
            comm.Recv(closestPoint, min_idx)
            print("CPU with rank %d has the closest point to %s: %s. The distance is %s" % (min_idx, coords, closestPoint, min_dist_global))
            return closestPoint, min_dist_global
    else:
        return closestPoint, minDist
예제 #41
0
def patch_volume(V, inv=True, raw=True):
    """
    Returns an array containing the volumes (or their reciprocal values) of each 
    patch M_j, where M_j is the set of all the cells sharing vertex x_j. 
    """
    assert V.ufl_element().family() == 'Lagrange'
    assert V.ufl_element().degree() == 1

    n_dofs = V.dim()
    dof_indices = df.vertex_to_dof_map(V)
    volumes = np.zeros(n_dofs)

    for i, v in enumerate(df.vertices(V.mesh())):
        for c in df.cells(v):
            volumes[dof_indices[i]] += c.volume()
    if inv:
        volumes = volumes**(-1)

    if raw:
        return volumes
    else:
        dv = df.Function(V)
        dv.vector()[:] = volumes
        return dv
예제 #42
0
def create_3d_mesh(mesh, h=1):
    assert mesh.topology().dim() == 2
    for cell in df.cells(mesh):
        print cell
        print cell.entities(0)
        print cell.get_vertex_coordinates()

    nv = mesh.num_vertices()
    nc = mesh.num_cells()

    mesh3 = df.Mesh()
    editor = df.MeshEditor()
    editor.open(mesh3, 3, 3)
    editor.init_vertices(2 * nv)
    editor.init_cells(3 * nc)

    for v in df.vertices(mesh):
        i = v.global_index()
        p = v.point()
        editor.add_vertex(i, p.x(), p.y(), 0)
        editor.add_vertex(i + nv, p.x(), p.y(), h)

    gid = 0
    for c in df.cells(mesh):
        #gid = c.global_index()
        i, j, k = c.entities(0)
        print i, j, k
        editor.add_cell(gid, i, j, k, i + nv)
        gid = gid + 1
        editor.add_cell(gid, j, j + nv, k, i + nv)
        gid = gid + 1
        editor.add_cell(gid, k, k + nv, j + nv, i + nv)
        gid = gid + 1

    editor.close()
    return mesh3
예제 #43
0
def get_iso_surfaces(simulation, field, value):
    """
    Slow fallback version that uses vertex values only
    """
    assert simulation.ndim == 2
    mesh = simulation.data['mesh']
    all_values = field.compute_vertex_values()

    # We will collect the cells containing the iso surface
    cells_with_surface = numpy.zeros(mesh.num_cells(), bool)
    connectivity_FC = simulation.data['connectivity_FC']

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

        # 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 for iso surface crossing
        b1, b2 = vertex_values[0] < value, vertex_values[1] < value
        if (b1 and b2) or not (b1 or b2):
            # Facet not crossed by contour
            continue

        # Find the location where the contour line crosses the facet
        v1, v2 = vertex_values
        fac = (v1 - value) / (v1 - v2)
        x = (1 - fac) * vertex_coords[0][0] + fac * vertex_coords[1][0]
        y = (1 - fac) * vertex_coords[0][1] + fac * vertex_coords[1][1]
        z = (1 - fac) * vertex_coords[0][2] + fac * vertex_coords[1][2]
        crossing_points[fid] = (x, y, z)

        # Find the cells connected to this facet
        for cid in connectivity_FC(fid):
            cells_with_surface[cid] = True

    # Get facet-facet connectivity via cells
    conFC = simulation.data['connectivity_FC']
    conCF = simulation.data['connectivity_CF']

    # Find facet to facet connections
    connections = {}
    for facet_id in crossing_points:
        connections[facet_id] = []
        for cell_id in conFC(facet_id):
            for facet_neighbour_id in conCF(cell_id):
                if (facet_neighbour_id != facet_id
                        and facet_neighbour_id in crossing_points):
                    connections[facet_id].append(facet_neighbour_id)

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

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

    assert len(crossing_points) == 0
    return contours_from_endpoints + contours_from_singles_and_loops, cells_with_surface
예제 #44
0
def extract_boundary_mesh(mesh, surface_facet, marker, variable_list=[]):
    """
  This function iterates through the cells and vertces of the mesh in order
  to find the boundaries

  Args:

    :mesh:          The dolfin mesh for which to find the boundaries
    :marker:        Cell marker to determine the surface facets
    :variable_list: A list of variables corrisponding to the mesh
 
  Returns:
  
    :rtype: FEniCS boundary mesh containing information on the surface of the
            mesh and a list of surface variables derived from the variable_list 
            parameter.

  """
    from dolfin import vertices

    D = mesh.topology().dim()
    surface_mesh = BoundaryMesh(mesh, 'exterior')
    surface_mesh.clear()

    editor = MeshEditor()
    editor.open(surface_mesh,
                mesh.type().type2string(mesh.type().facet_type()), D - 1,
                D - 1)

    mesh.init(D - 1, D)

    #exterior = mesh.parallel_data().exterior_facet()

    num_vertices = mesh.num_vertices()

    boundary_vertices = (pl.ones(num_vertices) * num_vertices).astype(int)
    num_boundary_vertices = 0
    num_boundary_cells = 0

    #surface_facet = mesh.domains().facet_domains(mesh)
    boundary_facet = MeshFunctionBool(mesh, D - 1, False)
    for f in facets(mesh):
        if surface_facet[f] == marker and f.exterior():
            boundary_facet[f] = True
            #    if boundary_facet[f]:
            for v in vertices(f):
                v_index = v.index()
                if boundary_vertices[v_index] == num_vertices:
                    boundary_vertices[v_index] = num_boundary_vertices
                    num_boundary_vertices += 1
            num_boundary_cells += 1

    editor.init_vertices(num_boundary_vertices)
    editor.init_cells(num_boundary_cells)

    vertex_map = surface_mesh.entity_map(0)
    if num_boundary_vertices > 0:
        vertex_map.init(surface_mesh, 0, num_boundary_vertices)

    cell_map = surface_mesh.entity_map(D - 1)
    if num_boundary_cells > 0:
        cell_map.init(surface_mesh, D - 1, num_boundary_cells)

    for v in vertices(mesh):
        vertex_index = boundary_vertices[v.index()]
        if vertex_index != mesh.num_vertices():
            if vertex_map.size() > 0:
                vertex_map[vertex_index] = v.index()
            editor.add_vertex(vertex_index, v.point())

    cell = pl.zeros(surface_mesh.type().num_vertices(
        surface_mesh.topology().dim()),
                    dtype=pl.uintp)
    current_cell = 0
    for f in facets(mesh):
        if boundary_facet[f]:
            vertices = f.entities(0)
            for ii in range(cell.size):
                cell[ii] = boundary_vertices[vertices[ii]]
            if cell_map.size() > 0:
                cell_map[current_cell] = f.index()
            editor.add_cell(current_cell, cell)
            current_cell += 1

    surface_mesh.order()
    Q = FunctionSpace(surface_mesh, "CG", 1)
    surface_variable_list = []

    for ii in range(len(variable_list)):
        surface_variable_list.append(Function(Q))

    v2d_surf = vertex_to_dof_map(Q)
    print vertex_map.array()
    v2d_3d = vertex_to_dof_map(variable_list[0].function_space())

    for ii, index in enumerate(vertex_map.array()):
        for jj, variable in enumerate(variable_list):
            surface_variable_list[jj].vector()[
                v2d_surf[ii]] = variable_list[jj].vector()[v2d_3d[index]]

    return surface_mesh, surface_variable_list
예제 #45
0
    def get_edge_errors(self):
        """
    Calculates the error estimates of the expression projected into the mesh.
    
    :rtype: Dolfin edge function containing the edge errors of the mesh

    """
        mesh = self.mesh
        coord = mesh.coordinates()

        V = FunctionSpace(mesh, "CG", 1)
        Hxx = TrialFunction(V)
        Hxy = TrialFunction(V)
        Hyy = TrialFunction(V)
        phi = TestFunction(V)

        edge_errors = EdgeFunction('double', mesh)

        U = project(self.U_ex, V)
        a_xx = Hxx * phi * dx
        L_xx = -U.dx(0) * phi.dx(0) * dx

        a_xy = Hxy * phi * dx
        L_xy = -U.dx(0) * phi.dx(1) * dx

        a_yy = Hyy * phi * dx
        L_yy = -U.dx(1) * phi.dx(1) * dx

        Hxx = Function(V)
        Hxy = Function(V)
        Hyy = Function(V)

        Mxx = Function(V)
        Mxy = Function(V)
        Myy = Function(V)

        solve(a_xx == L_xx, Hxx)
        solve(a_xy == L_xy, Hxy)
        solve(a_yy == L_yy, Hyy)
        e_list = []

        for v in vertices(mesh):
            idx = v.index()
            pt = v.point()
            x = pt.x()
            y = pt.y()

            a = Hxx(x, y)
            b = Hxy(x, y)
            d = Hyy(x, y)

            H_local = ([[a, b], [b, d]])

            l, ve = pl.eig(H_local)
            M = pl.dot(pl.dot(ve, abs(pl.diag(l))), ve.T)

            Mxx.vector()[idx] = M[0, 0]
            Mxy.vector()[idx] = M[1, 0]
            Myy.vector()[idx] = M[1, 1]

        e_list = []
        for e in edges(mesh):
            I, J = e.entities(0)
            x_I = coord[I, :]
            x_J = coord[J, :]
            M_I = pl.array([[Mxx.vector()[I], Mxy.vector()[I]],
                            [Mxy.vector()[I], Myy.vector()[I]]])
            M_J = pl.array([[Mxx.vector()[J], Mxy.vector()[J]],
                            [Mxy.vector()[J], Myy.vector()[J]]])
            M = (M_I + M_J) / 2.
            dX = x_I - x_J
            error = pl.dot(pl.dot(dX, M), dX.T)

            e_list.append(error)
            edge_errors[e] = error

        return edge_errors
예제 #46
0
    def _evaluateLocalEstimator(cls, mu, w, coeff_field, pde, f, quadrature_degree, epsilon=1e-5):
        """Evaluation of patch local equilibrated estimator."""

        # prepare numerical flux and f
        sigma_mu, f_mu = evaluate_numerical_flux(w, mu, coeff_field, f)

        # ###################
        # ## MIXED PROBLEM ##
        # ###################

        # get setup data for mixed problem
        V = w[mu]._fefunc.function_space()
        mesh = V.mesh()
        mesh.init()
        degree = element_degree(w[mu]._fefunc)

        # data for nodal bases
        V_dm = V.dofmap()
        V_dofs = dict([(i, V_dm.cell_dofs(i)) for i in range(mesh.num_cells())])
        V1 = FunctionSpace(mesh, 'CG', 1)   # V1 is to define nodal base functions
        phi_z = Function(V1)
        phi_coeffs = np.ndarray(V1.dim())
        vertex_dof_map = V1.dofmap().vertex_to_dof_map(mesh)
        # vertex_dof_map = vertex_to_dof_map(V1)
        dof_list = vertex_dof_map.tolist()
        # DG0 localisation
        DG0 = FunctionSpace(mesh, 'DG', 0)
        DG0_dofs = dict([(c.index(),DG0.dofmap().cell_dofs(c.index())[0]) for c in cells(mesh)])
        dg0 = TestFunction(DG0)
        # characteristic function of patch
        xi_z = Function(DG0)
        xi_coeffs = np.ndarray(DG0.dim())
        # mesh data
        h = CellSize(mesh)
        n = FacetNormal(mesh)
        cf = CellFunction('size_t', mesh)
        # setup error estimator vector
        eq_est = np.zeros(DG0.dim())

        # setup global equilibrated flux vector
        DG = VectorFunctionSpace(mesh, "DG", degree)
        DG_dofmap = DG.dofmap()

        # define form functions
        tau = TrialFunction(DG)
        v = TestFunction(DG)

        # define global tau
        tau_global = Function(DG)
        tau_global.vector()[:] = 0.0

        # iterate vertices
        for vertex in vertices(mesh):
            # get patch cell indices
            vid = vertex.index()
            patch_cid, FF_inner, FF_boundary = get_vertex_patch(vid, mesh, layers=1)

            # set nodal base function
            phi_coeffs[:] = 0
            phi_coeffs[dof_list.index(vid)] = 1
            phi_z.vector()[:] = phi_coeffs

            # set characteristic function and mark patch
            cf.set_all(0)
            xi_coeffs[:] = 0
            for cid in patch_cid:
                xi_coeffs[DG0_dofs[int(cid)]] = 1
                cf[int(cid)] = 1
            xi_z.vector()[:] = xi_coeffs

            # determine local dofs
            lDG_cell_dofs = dict([(cid, DG_dofmap.cell_dofs(cid)) for cid in patch_cid])
            lDG_dofs = [cd.tolist() for cd in lDG_cell_dofs.values()]
            lDG_dofs = list(iter.chain(*lDG_dofs))

            # print "\nlocal DG subspace has dimension", len(lDG_dofs), "degree", degree, "cells", len(patch_cid), patch_cid
            # print "local DG_cell_dofs", lDG_cell_dofs
            # print "local DG_dofs", lDG_dofs

            # create patch measures
            dx = Measure('dx')[cf]
            dS = Measure('dS')[FF_inner]

            # define forms
            alpha = Constant(1 / epsilon) / h
            a = inner(tau,v) * phi_z * dx(1) + alpha * div(tau) * div(v) * dx(1) + avg(alpha) * jump(tau,n) * jump(v,n) * dS(1)\
                + avg(alpha) * jump(xi_z * tau,n) * jump(v,n) * dS(2)
            L = -alpha * (div(sigma_mu) + f) * div(v) * phi_z * dx(1)\
                - avg(alpha) * jump(sigma_mu,n) * jump(v,n) * avg(phi_z)*dS(1)

    #        print "L2 f + div(sigma)", assemble((f + div(sigma)) * (f + div(sigma)) * dx(0))

            # assemble forms
            lhs = assemble(a, form_compiler_parameters={'quadrature_degree': quadrature_degree})
            rhs = assemble(L, form_compiler_parameters={'quadrature_degree': quadrature_degree})

            # convert DOLFIN representation to scipy sparse arrays
            rows, cols, values = lhs.data()
            lhsA = sps.csr_matrix((values, cols, rows)).tocoo()

            # slice sparse matrix and solve linear problem
            lhsA = coo_submatrix_pull(lhsA, lDG_dofs, lDG_dofs)
            lx = spsolve(lhsA, rhs.array()[lDG_dofs])
            # print ">>> local solution lx", type(lx), lx
            local_tau = Function(DG)
            local_tau.vector()[lDG_dofs] = lx
            # print "div(tau)", assemble(inner(div(local_tau),div(local_tau))*dx(1))

            # add up local fluxes
            tau_global.vector()[lDG_dofs] += lx

        # evaluate estimator
        # maybe TODO: re-define measure dx
        eq_est = assemble( inner(tau_global, tau_global) * dg0 * (dx(0)+dx(1)),\
                           form_compiler_parameters={'quadrature_degree': quadrature_degree})

        # reorder according to cell ids
        eq_est = eq_est[DG0_dofs.values()].array()
        global_est = np.sqrt(np.sum(eq_est))
        # eq_est_global = assemble( inner(tau_global, tau_global) * (dx(0)+dx(1)), form_compiler_parameters={'quadrature_degree': quadrature_degree} )
        # global_est2 = np.sqrt(np.sum(eq_est_global))
        return global_est, FlatVector(np.sqrt(eq_est))#, tau_global
예제 #47
0
파일: helper.py 프로젝트: mauro3/VarGlaS
  def get_edge_errors(self):
    """
    Calculates the error estimates of the expression projected into the mesh.
    
    :rtype: Dolfin edge function containing the edge errors of the mesh
    """
    mesh  = self.mesh
    coord = mesh.coordinates()
    
    V     = FunctionSpace(mesh, "CG", 1)
    Hxx   = TrialFunction(V)
    Hxy   = TrialFunction(V)
    Hyy   = TrialFunction(V)
    phi   = TestFunction(V)
    
    edge_errors = EdgeFunction('double', mesh)

    U    = project(self.U_ex, V)
    a_xx = Hxx * phi * dx
    L_xx = - U.dx(0) * phi.dx(0) * dx

    a_xy = Hxy * phi * dx
    L_xy = - U.dx(0) * phi.dx(1) * dx

    a_yy = Hyy * phi * dx
    L_yy = - U.dx(1) * phi.dx(1) * dx       

    Hxx  = Function(V)
    Hxy  = Function(V)
    Hyy  = Function(V)
         
    Mxx  = Function(V)
    Mxy  = Function(V)
    Myy  = Function(V)
  
    solve(a_xx == L_xx, Hxx)
    solve(a_xy == L_xy, Hxy)
    solve(a_yy == L_yy, Hyy)
    e_list = []

    for v in vertices(mesh):
      idx = v.index()
      pt  = v.point()
      x   = pt.x()
      y   = pt.y()
          
      a   = Hxx(x, y)
      b   = Hxy(x, y)
      d   = Hyy(x, y)

      H_local = ([[a,b], [b,d]])

      l, ve   = p.eig(H_local)
      M       = p.dot(p.dot(ve, abs(p.diag(l))), ve.T)       

      Mxx.vector()[idx] = M[0,0]
      Mxy.vector()[idx] = M[1,0]
      Myy.vector()[idx] = M[1,1]

    e_list = []
    for e in edges(mesh):
      I, J  = e.entities(0)
      x_I   = coord[I,:]
      x_J   = coord[J,:]
      M_I   = p.array([[Mxx.vector()[I], Mxy.vector()[I]],
                       [Mxy.vector()[I], Myy.vector()[I]]]) 
      M_J   = p.array([[Mxx.vector()[J], Mxy.vector()[J]],
                       [Mxy.vector()[J], Myy.vector()[J]]])
      M     = (M_I + M_J)/2.
      dX    = x_I - x_J
      error = p.dot(p.dot(dX, M), dX.T)
      
      e_list.append(error)
      edge_errors[e] = error
    
    return edge_errors
예제 #48
0
    def test_get_set_del(self):
        #Test the getter, setter and delete method

        values = [1,2,3]

        t = IonTag('foo',3,'int', self.mesh)

        for v in vertices(self.mesh):
            # test the setter
            t[v] = values

        # choose an entity in the mesh
        v = MeshEntity(self.mesh,0,1)

        # test the getter
        self.assertTrue((t[v] == values).all())

        #---------------------------------------------------------------------------------------
        # Check delete of a tag entry (for an entity)
        #---------------------------------------------------------------------------------------

        # choose an entity to delete
        entity_tuple = (v.dim(),v.index())

        # check that tag has the entity, v, in it
        self.assertTrue(t._entity_values.has_key(entity_tuple))

        # delete a tag entry for an entity
        del t[entity_tuple]

        # check that the tag no longer has the entity, v, in it
        self.assertFalse(t._entity_values.has_key(entity_tuple))

        #---------------------------------------------------------------------------------------
        # Add less number of values than the size defined in the tag object
        #---------------------------------------------------------------------------------------

        values = [1]
        t = IonTag('foo',3,'int', self.mesh)
        v = MeshEntity(self.mesh,0,1)

        #@todo check to see why self.assertRaises is not working for unittest:

#        with self.assertRaises(ValueError):
#            t[v] = values

        try:
            t[v] = values
        except ValueError:
            pass
        else:
            raise AssertionError('A Value Error should have been raised!')

        #---------------------------------------------------------------------------------------
        # Add more number of values that the size defined in the tag object
        #---------------------------------------------------------------------------------------

        values = [1,2,3,4]
        size = 2
        t = IonTag('foo',size,'int', self.mesh)
        v = MeshEntity(self.mesh,0,1)

        t[v] = values

        for key, value in t.iteritems():
            self.assertEqual(len(value), size)
예제 #49
0
파일: helper.py 프로젝트: mauro3/VarGlaS
def extract_boundary_mesh(mesh,surface_facet,marker,variable_list = []):
  """
  This function iterates through the cells and vertces of the mesh in order
  to find the boundaries

  :param mesh: The dolfin mesh for which to find the boundaries
  :param int marker: Cell marker to determine the surface facets
  :param variable_list: A list of variables corrisponding to the mesh
  :rtype: Dolfin boundary mesh containing information on the surface of the
     mesh and a list of surface variables derived from the variable_list 
     parameter
  """
  from dolfin import vertices

  D = mesh.topology().dim()
  surface_mesh = BoundaryMesh(mesh,'exterior')
  surface_mesh.clear()
 
  editor = MeshEditor()
  editor.open(surface_mesh,mesh.type().type2string(mesh.type().facet_type()), D-1,D-1)

  mesh.init(D-1,D)

  #exterior = mesh.parallel_data().exterior_facet()

  num_vertices = mesh.num_vertices()

  boundary_vertices = (p.ones(num_vertices)*num_vertices).astype(int)
  num_boundary_vertices = 0
  num_boundary_cells = 0

  #surface_facet = mesh.domains().facet_domains(mesh)
  boundary_facet = MeshFunctionBool(mesh,D-1,False)
  for f in facets(mesh):
    if surface_facet[f] == marker and f.exterior():
      boundary_facet[f] = True
#    if boundary_facet[f]:
      for v in vertices(f):
        v_index = v.index()
        if boundary_vertices[v_index] == num_vertices:
          boundary_vertices[v_index] = num_boundary_vertices
          num_boundary_vertices += 1
      num_boundary_cells += 1 

  editor.init_vertices(num_boundary_vertices)
  editor.init_cells(num_boundary_cells)

  vertex_map = surface_mesh.entity_map(0)
  if num_boundary_vertices > 0:
    vertex_map.init(surface_mesh, 0, num_boundary_vertices)

  cell_map = surface_mesh.entity_map(D-1)
  if num_boundary_cells > 0:
    cell_map.init(surface_mesh, D-1, num_boundary_cells)

  for v in vertices(mesh):
    vertex_index = boundary_vertices[v.index()]
    if vertex_index != mesh.num_vertices():
      if vertex_map.size() > 0:
        vertex_map[vertex_index] = v.index()
      editor.add_vertex(vertex_index,v.point())

  cell = p.zeros(surface_mesh.type().num_vertices(surface_mesh.topology().dim()),dtype = p.uintp)
  current_cell = 0
  for f in facets(mesh):
    if boundary_facet[f]:
      vertices = f.entities(0)
      for ii in range(cell.size):
        cell[ii] = boundary_vertices[vertices[ii]]
      if cell_map.size()>0:
        cell_map[current_cell] = f.index()
      editor.add_cell(current_cell,cell)
      current_cell += 1

  surface_mesh.order()
  Q = FunctionSpace(surface_mesh,"CG",1)
  surface_variable_list = []

  for ii in range(len(variable_list)):
    surface_variable_list.append(Function(Q))

  v2d_surf = vertex_to_dof_map(Q)
  print vertex_map.array()
  v2d_3d = vertex_to_dof_map(variable_list[0].function_space())

  for ii,index in enumerate(vertex_map.array()):
    for jj,variable in enumerate(variable_list):
      surface_variable_list[jj].vector()[v2d_surf[ii]] = variable_list[jj].vector()[v2d_3d[index]]

  return surface_mesh,surface_variable_list
예제 #50
0
editor.init_vertices(6)
editor.init_cells(2)

vertex_0 = Vertex(mesh, 0)
vertex_1 = Vertex(mesh, 1)
vertex_2 = Vertex(mesh, 2)
vertex_3 = Vertex(mesh, 3)

vertex_4 = Vertex(mesh, 4)
vertex_5 = Vertex(mesh, 5)

editor.add_cell(0, 1, 2, 3)
editor.add_cell(1, 0, 2, 3)

editor.close()


t = IonTag("foo", 3, "int", mesh)

for v in vertices(mesh):
    t[v] = [1, 2, 3]

for c in cells(mesh):
    t[c] = [4, 5, 6, 7]


v = MeshEntity(mesh, 0, 1)

print t[v]
예제 #51
0
파일: helper.py 프로젝트: mauro3/VarGlaS
  def weighted_smoothing(self, edge_errors, omega=0.1):
    """
    Smooths the points contained within the mesh
    
    :param edge_errors : Dolfin edge function containing the calculated
                         edge errors of the mesh
    :param omega       : Weighting factor used to refine the mesh
    """
    mesh  = self.mesh
    coord = mesh.coordinates()

    adjacent_points = {}
    mesh.init(1,2)
    
    #Create copies of the x coordinates
    new_x          = p.copy(coord[:,0])
    new_y          = p.copy(coord[:,1])
    exterior_point = {}

    for v in vertices(mesh):
      adjacent_points[v.index()] = set()

    for e in facets(mesh):
      vert = e.entities(0)
      ext  = e.exterior()
      for ii in (0,1):
        adjacent_points[vert[ii]].add((vert[ii-1], edge_errors[e]))
        adjacent_points[vert[ii-1]].add((vert[ii], edge_errors[e]))
      exterior_point[vert[0]] = ext
      exterior_point[vert[1]] = ext

    for item in adjacent_points.iteritems():
      index, data = item
      x       = coord[index,0]
      y       = coord[index,1]
      x_sum   = 0.0
      y_sum   = 0.0
      wgt_sum = 0.0
      kbar    = 0.0

      for entry in list(data):
        x_p   = coord[entry[0],0]
        y_p   = coord[entry[0],1]
        error = entry[1]
        kbar += 1./len(list(data)) * error/p.sqrt( (x-x_p)**2 + (y-y_p)**2 ) 
      kbar = 0.0 

      for entry in list(data):
        x_p      = coord[entry[0],0]
        y_p      = coord[entry[0],1]
        error    = entry[1]
        k_ij     = error/p.sqrt( (x-x_p)**2 + (y-y_p)**2 )
        x_sum   += (k_ij-kbar) * (x_p-x)
        y_sum   += (k_ij-kbar) * (y_p-y)
        wgt_sum += k_ij
        
      if not exterior_point[index]:
        new_x[index] = x + omega * x_sum / wgt_sum
        new_y[index] = y + omega * y_sum / wgt_sum

    return new_x, new_y