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
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
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)
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
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
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)
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
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
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
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
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)
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
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)
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
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
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
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)
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
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)
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
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
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
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
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())
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)
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)
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
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
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
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
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
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)
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 ))
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
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
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
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
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
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
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
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
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
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)
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
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]
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