def create(mesh, domain_ids, invert=False): """ Creates a wrapped mesh from a super mesh for a given collection of domain IDs. *Arguments* mesh (:class:`dolfin.Mesh`) The mesh. domain_ids (:class:`[int]`) List of domain IDs invert (:class:`bool`) Invert list of domain IDs *Returns* :class:`WrappedMesh` The wrapped mesh """ if invert or isinstance(domain_ids, list) or isinstance( domain_ids, tuple): if isinstance(domain_ids, int): domain_ids = (domain_ids, ) subdomains = MeshFunction('size_t', mesh, 3, mesh.domains()) combined_subdomains = CellFunction("size_t", mesh, 0) for domain_id in domain_ids: combined_subdomains.array()[subdomains.array() == domain_id] = 1 submesh = SubMesh(mesh, combined_subdomains, 0 if invert else 1) else: submesh = SubMesh(mesh, domain_ids) submesh.__class__ = WrappedMesh submesh._init(mesh) return submesh
def array_to_meshfunction(x, mesh): "Convert array x to cell function on Omega" f = CellFunction("double", mesh) if not f.size() == x.size: raise RuntimeError, "Size of vector does not match number of cells." for i in range(x.size): f[i] = x[i] return f
def test_store_mesh(casedir): pp = PostProcessor(dict(casedir=casedir)) from dolfin import (UnitSquareMesh, CellFunction, FacetFunction, AutoSubDomain, Mesh, HDF5File, assemble, Expression, ds, dx) # Store mesh mesh = UnitSquareMesh(6, 6) celldomains = CellFunction("size_t", mesh) celldomains.set_all(0) AutoSubDomain(lambda x: x[0] < 0.5).mark(celldomains, 1) facetdomains = FacetFunction("size_t", mesh) AutoSubDomain(lambda x, on_boundary: x[0] < 0.5 and on_boundary).mark( facetdomains, 1) pp.store_mesh(mesh, celldomains, facetdomains) # Read mesh back mesh2 = Mesh() f = HDF5File(mpi_comm_world(), os.path.join(pp.get_casedir(), "mesh.hdf5"), 'r') f.read(mesh2, "Mesh", False) celldomains2 = CellFunction("size_t", mesh2) f.read(celldomains2, "CellDomains") facetdomains2 = FacetFunction("size_t", mesh2) f.read(facetdomains2, "FacetDomains") e = Expression("1+x[1]", degree=1) dx1 = dx(1, domain=mesh, subdomain_data=celldomains) dx2 = dx(1, domain=mesh2, subdomain_data=celldomains2) C1 = assemble(e * dx1) C2 = assemble(e * dx2) assert abs(C1 - C2) < 1e-10 ds1 = ds(1, domain=mesh, subdomain_data=facetdomains) ds2 = ds(1, domain=mesh2, subdomain_data=facetdomains2) F1 = assemble(e * ds1) F2 = assemble(e * ds2) assert abs(F1 - F2) < 1e-10
def refine_cylinder(mesh): 'Refine mesh by cutting cells around the cylinder.' h = mesh.hmin() center = Point(c_x, c_y) cell_f = CellFunction('bool', mesh, False) for cell in cells(mesh): if cell.midpoint().distance(center) < r + h: cell_f[cell] = True mesh = refine(mesh, cell_f) return mesh
def refine_perimeter(mesh): """Refine largest boundary triangles.""" mesh.init(1, 2) perimeter = [ c for c in cells(mesh) if any([f.exterior() for f in facets(c)]) ] marker = CellFunction('bool', mesh, False) max_size = max([c.diameter() for c in perimeter]) for c in perimeter: marker[c] = c.diameter() > 0.75 * max_size return refine(mesh, marker)
def square_with_obstacle(): # Create classes for defining parts of the boundaries and the interior # of the domain class Left(SubDomain): def inside(self, x, on_boundary): return near(x[0], 0.0) class Right(SubDomain): def inside(self, x, on_boundary): return near(x[0], 1.0) class Bottom(SubDomain): def inside(self, x, on_boundary): return near(x[1], 0.0) class Top(SubDomain): def inside(self, x, on_boundary): return near(x[1], 1.0) class Obstacle(SubDomain): def inside(self, x, on_boundary): return between(x[1], (0.5, 0.7)) and between(x[0], (0.2, 1.0)) # Initialize sub-domain instances left = Left() top = Top() right = Right() bottom = Bottom() obstacle = Obstacle() # Define mesh mesh = UnitSquareMesh(100, 100, "crossed") # Initialize mesh function for interior domains domains = CellFunction("size_t", mesh) domains.set_all(0) obstacle.mark(domains, 1) # Initialize mesh function for boundary domains boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundaries.set_all(0) left.mark(boundaries, 1) top.mark(boundaries, 2) right.mark(boundaries, 3) bottom.mark(boundaries, 4) boundary_indices = {"left": 1, "top": 2, "right": 3, "bottom": 4} f = Constant(0.0) theta0 = Constant(293.0) return mesh, f, boundaries, boundary_indices, theta0
def refine_mesh(mesh, size, edge=False): """ Refine mesh to at least given size, using one of two methods. """ dim = mesh.topology().dim() if not edge: # FEniCS 1.5 and 1.6 have a bug which prevents uniform refinement while mesh.size(dim) < size: mesh = refine(mesh) else: # Refine based on MeshFunction while mesh.size(dim) < size: print refine(mesh).size(dim) full = CellFunction("bool", mesh, True) print refine(mesh, full).size(dim) mesh = refine(mesh, full) return mesh
def as_pvd(h5_file): '''Store facet and cell function for pvd''' root, ext = os.path.splitext(h5_file) mesh = Mesh() hdf = HDF5File(mesh.mpi_comm(), h5_file, 'r') hdf.read(mesh, '/mesh', False) facet_markers = FacetFunction('size_t', mesh) hdf.read(facet_markers, '/facet_markers') cell_markers = CellFunction('size_t', mesh) hdf.read(cell_markers, '/cell_markers') File(root + 'facets' + '.pvd') << facet_markers File(root + 'volumes' + '.pvd') << cell_markers return True
def refine_mesh_upto(mesh, size, edge=False): """ Refine mesh to at most given size, using one of two methods. """ dim = mesh.topology().dim() if mesh.size(dim) > size: return mesh if not edge: while True: # FEniCS 1.5 and 1.6 have a bug which prevents uniform refinement mesh2 = refine(mesh) if mesh2.size(dim) > size: return mesh mesh = mesh2 else: # Refine based on MeshFunction while True: all = CellFunction("bool", mesh, True) mesh2 = refine(mesh, all) if mesh2.size(dim) > size: return mesh mesh = mesh2
def test_ale(self): print "" print "Testing ALE::move(Mesh& mesh0, const Mesh& mesh1)" # Create some mesh mesh = UnitSquareMesh(4, 5) # Make some cell function # FIXME: Initialization by array indexing is probably # not a good way for parallel test cellfunc = CellFunction('size_t', mesh) cellfunc.array()[0:4] = 0 cellfunc.array()[4:] = 1 # Create submeshes - this does not work in parallel submesh0 = SubMesh(mesh, cellfunc, 0) submesh1 = SubMesh(mesh, cellfunc, 1) # Move submesh0 disp = Constant(("0.1", "-0.1")) submesh0.move(disp) # Move and smooth submesh1 accordignly submesh1.move(submesh0) # Move mesh accordingly parent_vertex_indices_0 = \ submesh0.data().array('parent_vertex_indices', 0) parent_vertex_indices_1 = \ submesh1.data().array('parent_vertex_indices', 0) mesh.coordinates()[parent_vertex_indices_0[:]] = \ submesh0.coordinates()[:] mesh.coordinates()[parent_vertex_indices_1[:]] = \ submesh1.coordinates()[:] # If test passes here then it is probably working # Check for cell quality for sure magic_number = 0.28 rmin = MeshQuality.radius_ratio_min_max(mesh)[0] self.assertTrue(rmin > magic_number)
def adaptive(self, mesh, eigv, eigf): """Refine mesh based on residual errors.""" fraction = 0.1 C = FunctionSpace(mesh, "DG", 0) # constants on triangles w = TestFunction(C) h = CellSize(mesh) n = FacetNormal(mesh) marker = CellFunction("bool", mesh) print len(marker) indicators = np.zeros(len(marker)) for e, u in zip(eigv, eigf): errform = avg(h) * jump(grad(u), n) ** 2 * avg(w) * dS \ + h * (inner(grad(u), n) - Constant(e) * u) ** 2 * w * ds if self.degree > 1: errform += h**2 * div(grad(u))**2 * w * dx indicators[:] += assemble(errform).array() # errors for each cell print "Residual error: ", sqrt(sum(indicators) / len(eigv)) cutoff = sorted(indicators, reverse=True)[int(len(indicators) * fraction) - 1] marker.array()[:] = indicators > cutoff # mark worst errors mesh = refine(mesh, marker) return mesh
#for mesh in [UnitSquareMesh(8,8)]: for mesh in [UnitSquareMesh(8, 8), UnitCubeMesh(6, 6, 6)]: #print mesh.num_cells() #exit() # from dolfin import BoundaryMesh #mesh = BoundaryMesh(mesh, "exterior") #mf = MeshFunction("size_t", mesh, mesh.ufl_cell().topological_dimension()) #mf.set_all(0) #class Left(SubDomain): # def inside(self, x, on_boundary): # return x[0] < 0.4 #Left().mark(mf, 1) cell_domains = CellFunction("size_t", mesh) cell_domains.set_all(0) subdomains = AutoSubDomain(lambda x: x[0] < 0.5) subdomains.mark(cell_domains, 1) if MPI.size(mpi_comm_world()) == 1: submesh = SubMesh(mesh, cell_domains, 1) else: submesh = create_submesh(mesh, cell_domains, 1) #MPI.barrier(mpi_comm_world()) #continue V = FunctionSpace(submesh, "CG", 2) expr = Expression("x[0]*x[1]*x[1]+4*x[2]", degree=2) u = project(expr, V)
def test_convert_triangle( self): # Disabled because it fails, see FIXME below # test no. 1 from dolfin import Mesh, MPI, mpi_comm_world # MPI_COMM_WORLD wrapper if MPI.size(mpi_comm_world()) != 1: return fname = os.path.join("data", "triangle") dfname = fname + ".xml" # Read triangle file and convert to a dolfin xml mesh file meshconvert.triangle2xml(fname, dfname) # Read in dolfin mesh and check number of cells and vertices mesh = Mesh(dfname) self.assertEqual(mesh.num_vertices(), 96) self.assertEqual(mesh.num_cells(), 159) # Clean up os.unlink(dfname) # test no. 2 from dolfin import MPI, Mesh, MeshFunction, \ edges, Edge, faces, Face, \ SubsetIterator, facets, CellFunction, mpi_comm_world if MPI.size(mpi_comm_world()) != 1: return fname = os.path.join("data", "test_Triangle_3") dfname = fname + ".xml" dfname0 = fname + ".attr0.xml" # Read triangle file and convert to a dolfin xml mesh file meshconvert.triangle2xml(fname, dfname) # Read in dolfin mesh and check number of cells and vertices mesh = Mesh(dfname) mesh.init() mfun = MeshFunction('double', mesh, dfname0) self.assertEqual(mesh.num_vertices(), 58) self.assertEqual(mesh.num_cells(), 58) # Create a size_t CellFunction and assign the values based on the # converted Meshfunction cf = CellFunction("size_t", mesh) cf.array()[mfun.array() == 10.0] = 0 cf.array()[mfun.array() == -10.0] = 1 # Meassure total area of cells with 1 and 2 marker add = lambda x, y: x + y area0 = reduce(add, (Face(mesh, cell.index()).area() \ for cell in SubsetIterator(cf, 0)), 0.0) area1 = reduce(add, (Face(mesh, cell.index()).area() \ for cell in SubsetIterator(cf, 1)), 0.0) total_area = reduce(add, (face.area() for face in faces(mesh)), 0.0) # Check that all cells in the two domains are either above or below y=0 self.assertTrue( all(cell.midpoint().y() < 0 for cell in SubsetIterator(cf, 0))) self.assertTrue( all(cell.midpoint().y() > 0 for cell in SubsetIterator(cf, 1))) # Check that the areas add up self.assertAlmostEqual(area0 + area1, total_area) # Measure the edge length of the two edge domains #edge_markers = mesh.domains().facet_domains() edge_markers = mesh.domains().markers(mesh.topology().dim() - 1) self.assertTrue(edge_markers is not None) #length0 = reduce(add, (Edge(mesh, e.index()).length() \ # for e in SubsetIterator(edge_markers, 0)), 0.0) length0, length1 = 0.0, 0.0 for item in edge_markers.items(): if item[1] == 0: e = Edge(mesh, int(item[0])) length0 += Edge(mesh, int(item[0])).length() elif item[1] == 1: length1 += Edge(mesh, int(item[0])).length() # Total length of all edges and total length of boundary edges total_length = reduce(add, (e.length() for e in edges(mesh)), 0.0) boundary_length = reduce(add, (Edge(mesh, f.index()).length() \ for f in facets(mesh) if f.exterior()), 0.0) # Check that the edges add up self.assertAlmostEqual(length0 + length1, total_length) self.assertAlmostEqual(length1, boundary_length) # Clean up os.unlink(dfname) os.unlink(dfname0)
def construct_sleeve_geometry( t_wall=None, t_gap=None, t_sleeve=None, L_wall=None, L_sleeve=None, refinement_parameter=16, ): # # Define the domain as a polygon mesh = Mesh() domain = Polygon([ dolfin.Point(0.0, 0.0), dolfin.Point(L_wall, 0.0), dolfin.Point(L_wall, t_wall), dolfin.Point((L_wall - L_sleeve), t_wall), dolfin.Point((L_wall - L_sleeve), (t_wall + t_gap)), dolfin.Point(L_wall, (t_wall + t_gap)), dolfin.Point(L_wall, (t_sleeve + t_wall + t_gap)), dolfin.Point((L_wall - L_sleeve), (t_sleeve + t_wall + t_gap)), dolfin.Point((L_wall - L_sleeve - t_sleeve - t_gap), t_wall), dolfin.Point(0.0, t_wall), ], ) # # Define weld region weld_subdomain = Polygon([ dolfin.Point((L_wall - L_sleeve - t_sleeve - t_gap), t_wall), dolfin.Point((L_wall - L_sleeve), t_wall), dolfin.Point((L_wall - L_sleeve), (t_wall + t_sleeve + t_gap)), ]) domain.set_subdomain(1, weld_subdomain) # # Mesh mesh = generate_mesh(domain, refinement_parameter) # # Refine in the weld cell_markers = CellFunction("bool", mesh) cell_markers.set_all(False) c = is_in_weld_region( t_wall=t_wall, t_gap=t_gap, t_sleeve=t_sleeve, L_wall=L_wall, L_sleeve=L_sleeve, ) class MyDomain(SubDomain): def inside(self, x, on_boundary): return c(x) my_domain = MyDomain() my_domain.mark(cell_markers, True) mesh = refine(mesh, cell_markers) # # Define the upper and lower boundaries class Upper(SubDomain): def inside(self, x, on_boundary): # # Define relevant points xb1 = (L_wall - L_sleeve - t_sleeve - t_gap) xb2 = (L_wall - L_sleeve) yb1 = t_wall yb2 = (t_wall + t_sleeve + t_gap) # # Define params for assessing if on a line between points dx_line = xb2 - xb1 dy_line = yb2 - yb1 dx = x[0] - xb1 dy = x[1] - yb1 zero = dx * dy_line - dx_line * dy # is_upper_region_one = x[0] <= xb1 and near(x[1], yb1) is_upper_region_two = x[0] >= xb1 and x[0] <= xb2 and near(zero, 0) is_upper_region_three = x[0] >= xb2 and near(x[1], yb2) # return is_upper_region_one or is_upper_region_two or is_upper_region_three class Lower(SubDomain): def inside(self, x, on_boundary): return near(x[1], 0) # # Set boundaries upper = Upper() lower = Lower() boundaries = FacetFunction("size_t", mesh) boundaries.set_all(0) upper.mark(boundaries, 1) lower.mark(boundaries, 2) # return (mesh, boundaries)