def refine_maxh(self, maxh, uniform=False): """Refine mesh of FEM basis such that maxh of mesh is smaller than given value.""" if maxh <= 0 or self.mesh.hmax() < maxh: return self, self.project_onto, self.project_onto, 0 ufl = self._fefs.ufl_element() mesh = self.mesh num_cells_refined = 0 if uniform: while mesh.hmax() > maxh: num_cells_refined += mesh.num_cells() mesh = refine(mesh) # NOTE: this global refine results in a red-refinement as opposed to bisection in the adaptive case else: while mesh.hmax() > maxh: cell_markers = CellFunction("bool", mesh) cell_markers.set_all(False) for c in cells(mesh): if c.diameter() > maxh: cell_markers[c.index()] = True num_cells_refined += 1 mesh = refine(mesh, cell_markers) if self._fefs.num_sub_spaces() > 1: new_fefs = VectorFunctionSpace(mesh, ufl.family(), ufl.degree()) else: new_fefs = FunctionSpace(mesh, ufl.family(), ufl.degree()) new_basis = FEniCSBasis(new_fefs) prolongate = new_basis.project_onto restrict = self.project_onto return new_basis, prolongate, restrict, num_cells_refined
def generate_meshes(N = 5, iterations = 3, refinements = 0.5): mesh1 = UnitSquare(N,N) mesh2 = UnitSquare(N,N) for ref in range(iterations): print "refinement ", ref+1 info(mesh1) info(mesh2) cf1 = CellFunction("bool", mesh1) cf2 = CellFunction("bool", mesh2) cf1.set_all(False) cf2.set_all(False) m1 = round(cf1.size()*refinements) m2 = round(cf2.size()*refinements) mi1 = randint(0,cf1.size(),m1) mi2 = randint(0,cf2.size(),m2) for i in mi1: cf1[i] = True for i in mi2: cf2[i] = True # newmesh1 = adapt(mesh1, cf1) newmesh1 = refine(mesh1, cf1) # newmesh2 = adapt(mesh2, cf2) newmesh2 = refine(mesh2, cf2) mesh1 = newmesh1 mesh2 = newmesh2 return [(0.,0.),(1.,0.),(1.,1.),(0.,1.)], mesh1, mesh2
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 setupMeshes(cls, mesh, N, num_refine=0, randref=(1.0, 1.0)): """Create a set of N meshes based on provided mesh. Parameters num_refine>=0 and randref specify refinement adjustments. num_refine specifies the number of refinements per mesh, randref[0] specifies the probability that a given mesh is refined, and randref[1] specifies the probability that an element of the mesh is refined (if it is refined at all). """ assert num_refine >= 0 assert 0 < randref[0] <= 1.0 assert 0 < randref[1] <= 1.0 # create set of (refined) meshes meshes = list(); for _ in range(N): m = Mesh(mesh) for _ in range(num_refine): if randref[0] == 1.0 and randref[1] == 1.0: m = refine(m) elif random() <= randref[0]: cell_markers = CellFunction("bool", m) cell_markers.set_all(False) cell_ids = range(m.num_cells()) shuffle(cell_ids) num_ref_cells = int(ceil(m.num_cells() * randref[1])) for cell_id in cell_ids[0:num_ref_cells]: cell_markers[cell_id] = True m = refine(m, cell_markers) meshes.append(m) return meshes
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 mesh_generator(n): mesh = RectangleMesh(1.0, 0.0, 2.0, 1.0, n, n, 'left/right') domains = CellFunction('uint', mesh) domains.set_all(0) dx = Measure('dx')[domains] boundaries = FacetFunction('uint', mesh) boundaries.set_all(0) ds = Measure('ds')[boundaries] return mesh, dx, ds
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 = FacetFunction('size_t', mesh) 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 test1(): # setup meshes P = 0.3 ref1 = 4 ref2 = 14 mesh1 = UnitSquare(2, 2) mesh2 = UnitSquare(2, 2) # refinement loops for level in range(ref1): mesh1 = refine(mesh1) for level in range(ref2): # mark and refine markers = CellFunction("bool", mesh2) markers.set_all(False) # randomly refine mesh for i in range(mesh2.num_cells()): if random() <= P: markers[i] = True mesh2 = refine(mesh2, markers) # create joint meshes mesh1j, parents1 = create_joint_mesh([mesh2], mesh1) mesh2j, parents2 = create_joint_mesh([mesh1], mesh2) # evaluate errors joint meshes ex1 = Expression("sin(2*A*x[0])*sin(2*A*x[1])", A=10) V1 = FunctionSpace(mesh1, "CG", 1) V2 = FunctionSpace(mesh2, "CG", 1) V1j = FunctionSpace(mesh1j, "CG", 1) V2j = FunctionSpace(mesh2j, "CG", 1) f1 = interpolate(ex1, V1) f2 = interpolate(ex1, V2) # interpolate on respective joint meshes f1j = interpolate(f1, V1j) f2j = interpolate(f2, V2j) f1j1 = interpolate(f1j, V1) f2j2 = interpolate(f2j, V2) # evaluate error with regard to original mesh e1 = Function(V1) e2 = Function(V2) e1.vector()[:] = f1.vector() - f1j1.vector() e2.vector()[:] = f2.vector() - f2j2.vector() print "error on V1:", norm(e1, "L2") print "error on V2:", norm(e2, "L2") plot(f1j, title="f1j") plot(f2j, title="f2j") plot(mesh1, title="mesh1") plot(mesh2, title="mesh2") plot(mesh1j, title="joint mesh from mesh1") plot(mesh2j, title="joint mesh from mesh2", interactive=True)
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_boundary_layers(mesh, s, d, x0, x1): from dolfin import CellFunction, cells, refine, DOLFIN_EPS h = mesh.hmax() cell_markers = CellFunction('bool', mesh, mesh.topology().dim()) cell_markers.set_all(False) for cell in cells(mesh): x = cell.midpoint() for i, d_ in enumerate(d): if x[d_] > (x1[i]-s*h-DOLFIN_EPS) or x[d_] < (s*h + x0[i] + DOLFIN_EPS): cell_markers[cell] = True return refine(mesh, cell_markers)
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(self, cell_ids=None): """Refine mesh of basis uniformly or wrt cells, returns (new_basis,prolongate,restrict).""" mesh = self._fefs.mesh() cell_markers = CellFunction("bool", mesh) if cell_ids is None: cell_markers.set_all(True) else: cell_markers.set_all(False) for cid in cell_ids: cell_markers[cid] = True new_mesh = refine(mesh, cell_markers) # if isinstance(self._fefs, VectorFunctionSpace): if self._fefs.num_sub_spaces() > 1: new_fs = VectorFunctionSpace(new_mesh, self._fefs.ufl_element().family(), self._fefs.ufl_element().degree()) else: new_fs = FunctionSpace(new_mesh, self._fefs.ufl_element().family(), self._fefs.ufl_element().degree()) new_basis = FEniCSBasis(new_fs) prolongate = new_basis.project_onto restrict = self.project_onto return new_basis, prolongate, restrict
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 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 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 _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 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)
#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 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)
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 create_joint_mesh(meshes, destmesh=None, additional_refine=0): if destmesh is None: # start with finest mesh to avoid (most) refinements # hmin = [m.hmin() for m in meshes] # mind = hmin.index(min(hmin)) numcells = [m.num_cells() for m in meshes] mind = numcells.index(max(numcells)) destmesh = meshes.pop(mind) try: # test for old FEniCS version < 1.2 destmesh.closest_cell(Point(0,0)) bbt = None except: # FEniCS > 1.2 bbt = destmesh.bounding_box_tree() # setup parent cells parents = {} for c in cells(destmesh): parents[c.index()] = [c.index()] PM = [] # refinement loop for destmesh for m in meshes: # loop until all cells of destmesh are finer than the respective cells in the set of meshes while True: cf = CellFunction("bool", destmesh) cf.set_all(False) rc = 0 # counter for number of marked cells # get cell sizes of current mesh h = [c.diameter() for c in cells(destmesh)] # check all cells with destination sizes and mark for refinement when destination mesh is coarser (=larger) for c in cells(m): p = c.midpoint() if bbt is not None: # FEniCS > 1.2 cid = bbt.compute_closest_entity(p)[0] else: # FEniCS < 1.2 cid = destmesh.closest_cell(p) if h[cid] > c.diameter(): cf[cid] = True rc += 1 # carry out refinement if any cells are marked if rc: # refine marked cells newmesh = refine(destmesh, cf) # determine parent cell association map pc = newmesh.data().array("parent_cell", newmesh.topology().dim()) pmap = defaultdict(list) for i, cid in enumerate(pc): pmap[cid].append(i) PM.append(pmap) # set refined mesh as current mesh destmesh = newmesh else: break # carry out additional uniform refinements for _ in range(additional_refine): # refine uniformly newmesh = refine(destmesh) # determine parent cell association map pc = newmesh.data().array("parent_cell", newmesh.topology().dim()) pmap = defaultdict(list) for i, cid in enumerate(pc): pmap[cid].append(i) PM.append(pmap) # set refined mesh as current mesh destmesh = newmesh # determine association to parent cells for level in range(len(PM)): for parentid, childids in parents.iteritems(): newchildids = [] for cid in childids: for cid in PM[level][cid]: newchildids.append(cid) parents[parentid] = newchildids return destmesh, parents