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 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 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
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
def test_convert_triangle(self): # Disabled because it fails, see FIXME below # test no. 1 from dolfin import Mesh, MPI if MPI.num_processes() != 1: return fname = os.path.join("data", "triangle") dfname = fname+".xml" # Read triangle file and convert to a dolfin xml mesh file meshconvert.triangle2xml(fname, dfname) # Read in dolfin mesh and check number of cells and vertices mesh = Mesh(dfname) self.assertEqual(mesh.num_vertices(), 96) self.assertEqual(mesh.num_cells(), 159) # Clean up os.unlink(dfname) # test no. 2 from dolfin import MPI, Mesh, MeshFunction, \ edges, Edge, faces, Face, \ SubsetIterator, facets, CellFunction if MPI.num_processes() != 1: return fname = os.path.join("data", "test_Triangle_3") dfname = fname+".xml" dfname0 = fname+".attr0.xml" # Read triangle file and convert to a dolfin xml mesh file meshconvert.triangle2xml(fname, dfname) # Read in dolfin mesh and check number of cells and vertices mesh = Mesh(dfname) mesh.init() mfun = MeshFunction('double', mesh, dfname0) self.assertEqual(mesh.num_vertices(), 58) self.assertEqual(mesh.num_cells(), 58) # Create a size_t CellFunction and assign the values based on the # converted Meshfunction cf = CellFunction("size_t", mesh) cf.array()[mfun.array()==10.0] = 0 cf.array()[mfun.array()==-10.0] = 1 # Meassure total area of cells with 1 and 2 marker add = lambda x, y : x+y area0 = reduce(add, (Face(mesh, cell.index()).area() \ for cell in SubsetIterator(cf, 0)), 0.0) area1 = reduce(add, (Face(mesh, cell.index()).area() \ for cell in SubsetIterator(cf, 1)), 0.0) total_area = reduce(add, (face.area() for face in faces(mesh)), 0.0) # Check that all cells in the two domains are either above or below y=0 self.assertTrue(all(cell.midpoint().y()<0 for cell in SubsetIterator(cf, 0))) self.assertTrue(all(cell.midpoint().y()>0 for cell in SubsetIterator(cf, 1))) # Check that the areas add up self.assertAlmostEqual(area0+area1, total_area) # Measure the edge length of the two edge domains edge_markers = mesh.domains().facet_domains() self.assertTrue(edge_markers is not None) length0 = reduce(add, (Edge(mesh, e.index()).length() \ for e in SubsetIterator(edge_markers, 0)), 0.0) length1 = reduce(add, (Edge(mesh, e.index()).length() \ for e in SubsetIterator(edge_markers, 1)), 0.0) # Total length of all edges and total length of boundary edges total_length = reduce(add, (e.length() for e in edges(mesh)), 0.0) boundary_length = reduce(add, (Edge(mesh, f.index()).length() \ for f in facets(mesh) if f.exterior()), 0.0) # Check that the edges add up self.assertAlmostEqual(length0+length1, total_length) self.assertAlmostEqual(length1, boundary_length) # Clean up os.unlink(dfname) os.unlink(dfname0)
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)