def markBoundaries(self, mesh): self.boundaries = dolfin.MeshFunction("size_t", mesh, mesh.topology().dim() - 1) self.boundaries.set_all(0) self.subdomains['left'].mark(self.boundaries, 1) self.subdomains['top'].mark(self.boundaries, 2) self.subdomains['right'].mark(self.boundaries, 3) self.subdomains['bottom'].mark(self.boundaries, 4) self.subdomains['front'].mark(self.boundaries, 5) self.subdomains['back'].mark(self.boundaries, 6) #mark each electrode by its position in the list, plus an offset for electrode in self.electrodes: electrode.mark(self.boundaries, 7 + self.electrodes.index(electrode))
def integration_measure_over_expression(mesh, expr, threshold): mf = dolfin.MeshFunction('size_t', mesh, mesh.geometric_dimension()) dx_subdomains = dolfin.dx(subdomain_data=mf, domain=mesh) V_DG = dolfin.FunctionSpace(mesh, 'DG', 0) mf.array()[:] = np.array( dolfin.project(expr, V_DG).vector().get_local() > threshold, np.uint) dx_interior = dx_subdomains(1) dx_exterior = dx_subdomains(0) return dx_interior, dx_exterior
def generate_mesh(self): mesh = self.user_just_generate_mesh() cf = dolfin.MeshFunction('size_t', mesh, mesh.topology().dim(), 0) self.mesh = mesh self.cf = cf # initialize facets-cells mapping D = self.dim mesh.init(D - 1, D) d = self.user_tag_cells(cf) self.cell_regions = d['tag_to_cell_values']
def init_submeshes(self): self.oversampled_submeshes = [] self.patch_submeshes = [] self.patch_vertex_parent_maps = [] self.patch_cell_parent_maps = [] for marker in self.markers: patch_submesh = dolfin.SubMesh(self.mesh, marker, 2) self.patch_submeshes.append(patch_submesh) patch_vertex_parent_map = patch_submesh.data().array("parent_vertex_indices", 0) self.patch_vertex_parent_maps.append(patch_vertex_parent_map) patch_cell_parent_map = patch_submesh.data().array("parent_cell_indices", self.basedim) self.patch_cell_parent_maps.append(patch_cell_parent_map) oversampled_marker = dolfin.MeshFunction('size_t', self.mesh, self.basedim, 0) oversampled_marker.array()[numpy.where(marker.array() > 0)] = 1 self.oversampled_submeshes.append(dolfin.SubMesh(self.mesh, oversampled_marker, 1))
def test_two_line(): mesh = df.UnitCubeMesh(8, 8, 8) f = df.MeshFunction('size_t', mesh, 1, 0) df.CompiledSubDomain('near(x[0], x[1]) && near(x[1], x[2])').mark(f, 1) # One more line df.CompiledSubDomain('near(x[0], x[1]) && near(1., x[2])').mark(f, 1) d = curve_distance(f, nlayers=10, outside_val=-1) # See if we got the distance right A, B, C = np.array([0., 0, 0]), np.array([1, 1., 1]), np.array([0., 0, 1.]) dofs_x = d.function_space().tabulate_dof_coordinates().reshape((-1, 3)) for xi in dofs_x: assert abs(d(xi) - min((distance(A, B, xi), distance(C, B, xi)))) < 1E-13
def simple_domain(size=15): """Construct a simple meshfunction representing domains. Simple is defined as 0 defined on the left half (x < 0.5) and 1 on the right side (x > 0.5) :param size: Resolution of the mesh :return: Domain function """ mesh = df.UnitSquareMesh(size, size) domain = df.MeshFunction("size_t", mesh, 2) # make MeshFunction with right = 1 and left = 0 for c in df.cells(mesh): if c.midpoint()[0] > 0.5: domain[c] = 1 return domain
def test_plot_facetfunction(dim, wireframe): mesh = get_mesh(3) ffun = df.MeshFunction("size_t", mesh, 2) ffun.set_all(0) fixed = df.CompiledSubDomain("near(x[0], 0) && on_boundary") free = df.CompiledSubDomain("near(x[0], 1) && on_boundary") fixed_marker = 1 fixed.mark(ffun, fixed_marker) # Mark the second subdomain with value 2 free_marker = 2 free.mark(ffun, free_marker) plot(ffun, show=False)
def boring(mesh_2d, inner_size): ''' A mesh2d is assumed to be be a cube [-inner_size, inner_size]^2. The curve is mostly a collection of boundary edges. ''' facet_f = df.MeshFunction('size_t', mesh_2d, 1, 0) mesh_2d.init(2, 1) # Mesh for the curve is tricky as we need to find the line in the faces def union(domains, A=inner_size, tol=1E-10): def body(domains): if isinstance(domains, str): if domains: return '( %s )' % domains else: return '' else: return ' || '.join(map(body, domains)) return df.CompiledSubDomain(body(domains), A=A, tol=tol) lines = { 4: union('near(x[1], A, tol) && near(x[2], A, tol)'), 3: union('near(x[2], -x[0], tol)'), 2: union('near(x[2], x[1], tol)'), 1: union([ 'near(x[0], -A, tol) && near(x[2], -A, tol)', 'near(x[1], A, tol) && near(x[0], -A, tol)', 'near(x[1], -A, tol) && near(x[0], -A, tol)' ]) } for tag, line in lines.items(): # Get candidates facets = set( sum((cell.entities(1).tolist() for cell in df.SubsetIterator(mesh_2d.marking_function, tag)), [])) for facet in facets: if line.inside(df.Facet(mesh_2d, facet).midpoint().array(), True): facet_f[int(facet)] = 1 return facet_f
def tensor_components(mesh): ''' c00 c01 c02 c11 c12 c22 ''' c00 = d.MeshFunction("double", mesh, 3) c01 = d.MeshFunction("double", mesh, 3) c02 = d.MeshFunction("double", mesh, 3) c11 = d.MeshFunction("double", mesh, 3) c12 = d.MeshFunction("double", mesh, 3) c22 = d.MeshFunction("double", mesh, 3) return c00, c01, c02, c11, c12, c22
def mark_boundaries(simulation): """ Mark the boundaries of the mesh with different numbers to be able to apply different boundary conditions to different regions """ simulation.log.info('Creating boundary regions') # Create a function to mark the external facets mesh = simulation.data['mesh'] marker = dolfin.MeshFunction("size_t", mesh, mesh.topology().dim() - 1) mesh_facet_regions = simulation.data['mesh_facet_regions'] # Create boundary regions and let them mark the part of the # boundary that they belong to. They also create boundary # condition objects that are later used in the eq. solvers boundary = [] for index, _ in enumerate(simulation.input.get_value('boundary_conditions', [], 'list(dict)')): part = BoundaryRegion(simulation, marker, index, mesh_facet_regions) boundary.append(part) simulation.data['boundary'] = boundary simulation.data['boundary_marker'] = marker simulation.data['boundary_by_name'] = {b.name: b for b in boundary} # Create a boundary measure that is aware of the marked regions mesh = simulation.data['mesh'] ds = dolfin.Measure('ds', domain=mesh, subdomain_data=marker) simulation.data['ds'] = ds # Show region sizes one = dolfin.Constant(1) for region in boundary: length = dolfin.assemble(one * ds(region.mark_id, domain=mesh)) pf = simulation.log.info if length > 0.0 else simulation.log.warning pf(' Boundary region %s has size %f' % (region.name, length)) length0 = dolfin.assemble(one * ds(0, domain=mesh)) pf = simulation.log.info if length0 == 0.0 else simulation.log.warning pf(' Boundary region UNMARKED has size %f' % length0) # Optionally plot boundary regions to file if simulation.input.get_value('output/plot_bcs', False, 'bool'): prefix = simulation.input.get_value('output/prefix', '', 'string') pfile = prefix + '_boundary_regions.xdmf' simulation.log.info(' Plotting boundary regions to ' 'XDMF file %r' % pfile) with dolfin.XDMFFile(mesh.mpi_comm(), pfile) as xdmf: xdmf.write(marker)
def generate_subdomain_restriction(mesh, subdomains, subdomains_ids): D = mesh.topology().dim() # Initialize empty restriction restriction = mp.MeshRestriction(mesh, None) for d in range(D + 1): mesh_function_d = df.MeshFunction("bool", mesh, d) mesh_function_d.set_all(False) restriction.append(mesh_function_d) # Mark restriction mesh functions based on subdomain id for c in df.cells(mesh): for subdomain_id in subdomains_ids: if subdomains[c] == subdomain_id: restriction[D][c] = True for d in range(D): for e in df.entities(c, d): restriction[d][e] = True return restriction
def spherical_shell(dim, radii, n_refinements=0): """ Creates the mesh of a spherical shell using the mshr module. """ assert isinstance(dim, int) assert dim == 2 or dim == 3 assert isinstance(radii, (list, tuple)) and len(radii) == 2 ri, ro = radii assert isinstance(ri, float) and ri > 0. assert isinstance(ro, float) and ro > 0. assert ri < ro assert isinstance(n_refinements, int) and n_refinements >= 0 # mesh generation if dim == 2: center = dlfn.Point(0., 0.) elif dim == 3: center = dlfn.Point(0., 0., 0.) if dim == 2: domain = Circle(center, ro)\ - Circle(center, ri) mesh = generate_mesh(domain, 75) elif dim == 3: domain = Sphere(center, ro) \ - Sphere(center, ri) mesh = generate_mesh(domain, 15) # mesh refinement for i in range(n_refinements): mesh = dlfn.refine(mesh) # MeshFunction for boundaries ids facet_marker = dlfn.MeshFunction("size_t", mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) # mark boundaries BoundaryMarkers = SphericalAnnulusBoundaryMarkers gamma_inner = CircularBoundary(mesh=mesh, radius=ri) gamma_inner.mark(facet_marker, BoundaryMarkers.interior_boundary.value) gamma_outer = CircularBoundary(mesh=mesh, radius=ro) gamma_outer.mark(facet_marker, BoundaryMarkers.exterior_boundary.value) return mesh, facet_marker
def _gen_ds(self): mesh = self.mesh R_laser = self.R_laser Z = self.Z top_laser_boundary = dolfin.CompiledSubDomain( 'near(x[1], top_side) && x[0] < R_laser && on_boundary', top_side=Z, R_laser=R_laser, ) top_nonlaser_boundary = dolfin.CompiledSubDomain( 'near(x[1], top_side) && x[0]>= R_laser && on_boundary', top_side=Z, R_laser=R_laser, ) bottom_boundary = dolfin.CompiledSubDomain( 'near(x[1], bottom_side) && on_boundary', bottom_side=0, ) symmetry_ax_boundary = dolfin.CompiledSubDomain( 'near(x[0], right_side) && on_boundary', right_side=0, ) # whole top boundary with no separation top_boundary = dolfin.CompiledSubDomain( 'near(x[1], top_side) && on_boundary', top_side=Z) symmetry_ax_boundary = dolfin.CompiledSubDomain( 'near(x[0], right_side) && on_boundary', right_side=0) boundary_markers = dolfin.MeshFunction('size_t', mesh, mesh.topology().dim() - 1) symmetry_ax_boundary.mark(boundary_markers, 0) top_laser_boundary.mark(boundary_markers, 1) top_nonlaser_boundary.mark(boundary_markers, 2) # side_boun.mark(boundary_markers, 3) bottom_boundary.mark(boundary_markers, 4) ds = dolfin.Measure('ds', domain=mesh, subdomain_data=boundary_markers) return ds
def refine_mesh(mesh): """" To refine selected parts of the mesh. """ for r in [2.5]: #[20, 15, 10, 8]: print("Refining ...") cell_markers = df.MeshFunction("bool", mesh, dim=mesh.topology().dim() - 1) cell_markers.set_all(False) for cell in df.cells(mesh): # p = np.sum(np.array(cell.midpoint()[:])**2) if np.abs(cell.midpoint()[2]) < r: cell_markers[cell] = True mesh = df.refine(mesh, cell_markers) print(mesh.num_cells()) mesh.smooth() return mesh
def unitcube_geometry(): N = 2 mesh = dolfin.UnitCubeMesh(N, N, N) V_f = QuadratureSpace(mesh, 4) l0 = dolfin.interpolate(dolfin.Expression(("1.0", "0.0", "0.0"), degree=1), V_f) r0 = dolfin.interpolate(dolfin.Expression(("0.0", "1.0", "0.0"), degree=1), V_f) c0 = dolfin.interpolate(dolfin.Expression(("0.0", "0.0", "1.0"), degree=1), V_f) crl_basis = CRLBasis(l0=l0, r0=r0, c0=c0) cfun = strain_markers_3d(mesh, 2) ffun = dolfin.MeshFunction("size_t", mesh, 2) ffun.set_all(0) fixed.mark(ffun, fixed_marker) free.mark(ffun, free_marker) marker_functions = MarkerFunctions(ffun=ffun, cfun=cfun) fixed_marker_ = Marker(name='fixed', value=fixed_marker, dimension=2) free_marker_ = Marker(name='free', value=free_marker, dimension=2) markers = (fixed_marker_, free_marker_) # Fibers f0 = dolfin.interpolate(dolfin.Expression(("1.0", "0.0", "0.0"), degree=1), V_f) s0 = dolfin.interpolate(dolfin.Expression(("0.0", "1.0", "0.0"), degree=1), V_f) n0 = dolfin.interpolate(dolfin.Expression(("0.0", "0.0", "1.0"), degree=1), V_f) microstructure = Microstructure(f0=f0, s0=s0, n0=n0) geometry = Geometry(mesh=mesh, markers=markers, marker_functions=marker_functions, microstructure=microstructure, crl_basis=crl_basis) return geometry
def domain_relationship(self, A, B): # FIXME: this is seriously stupid and inefficient, but it works dom = A + B dom.set_subdomain(1, dom) dom.set_subdomain(2, A - B) dom.set_subdomain(3, B - A) mesh = mshr.generate_mesh(dom, 1) cf = dolfin.MeshFunction("size_t", mesh, mesh.geometry().dim(), mesh.domains()) # cell values (subdomains) that actually show up cvs = frozenset(cf.array()) return _domain_relationship_table[cvs]
def load_mesh_function(self, name: str) -> dolfin.MeshFunction: """Lead and return a mesh function. There are two options, 'CellDomains' or 'FacetDomains'. Both are stored in 'mesh.hdf5'. Arguments: name: Either 'CellDomains' or 'FacetDomains'. """ msg = "Meshfunctions are stored as 'CellDomains' or 'FacetDomains'." assert name in ("CellDomains", "FacetDomains"), msg filename = calsedir / Path("mesh.hdf5") # with dolfin.HDF5File(dolfin.mpi_comm_world(), filename, "r") as meshfile: with dolfin.HDF5File(mesh.mpi_comm(), filename, "r") as meshfile: mesh_function = dolfin.MeshFunction() meshfile.read(mesh, f"/{name}") return mesh_function
def relabel_bnd(bnd): """ Relabels MeshFunction bnd such that boundaries are marked 1, 2, 3, etc. instead of arbitrary numbers. The order is preserved, and by convention the first boundary is the exterior boundary. The objects start at 2. The background (not marked) is 0. """ new_bnd = bnd new_bnd = df.MeshFunction("size_t", bnd.mesh(), bnd.dim()) new_bnd.set_all(0) old_ids = np.array([int(tag) for tag in set(bnd.array())]) old_ids = np.sort(old_ids)[1:] for new_id, old_id in enumerate(old_ids, 1): new_bnd.array()[bnd.where_equal(old_id)] = int(new_id) num_objects = len(old_ids) - 1 return new_bnd, num_objects
def mesh1d(left, right, meshres): mesh = dolfin.IntervalMesh(meshres, left, right) # Construct of the facet markers: boundary = (dolfin.MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0), {}) #boundary[0].set_all(0) for f in dolfin.facets(mesh): if dolfin.near(f.midpoint()[0], left): boundary[0][f] = 1 # left boundary[1]['inner'] = 1 elif dolfin.near(f.midpoint()[0], right): boundary[0][f] = 2 # right boundary[1]['outer'] = 2 # Definition of measures and normal vector: n = dolfin.FacetNormal(mesh) dx = dolfin.Measure("dx", mesh) ds = dolfin.Measure("ds", subdomain_data=boundary[0]) return (mesh, boundary, n, dx, ds)
def __init__(self, region_material_properties, region_meshfunction, mesh): """Set up material property functions @param region_material_properties: A dict with key region_no, value MaterialProperties object for that region number @param region_meshfunction: A dolfin MeshFunction mapping elements to region numbers. If it is None, all elements are set to region 0 @param mesh: A dolfin Mesh object relating to region_meshfunction. The material functions will be defined on this mesh """ self.region_material_properties = region_material_properties # if the meshfunction is not defined then initialise to a zero mesh function if region_meshfunction is None: region_meshfunction = dolfin.MeshFunction('uint', mesh, mesh.topology().dim()) region_meshfunction.set_all(0) self.region_meshfunction = region_meshfunction self.mesh = mesh
def create_domain(level, diagonal="right"): N = 2**level * 11 mesh = df.UnitSquareMesh(N, N, diagonal) class Top(df.SubDomain): def inside(self, x, on_boundary): return on_boundary and df.near(x[1], 1.0) class Bottom(df.SubDomain): def inside(self, x, on_boundary): return on_boundary and df.near(x[1], 0.0) class Left(df.SubDomain): def inside(self, x, on_boundary): return on_boundary and df.near(x[0], 0.0) class Right(df.SubDomain): def inside(self, x, on_boundary): return on_boundary and df.near(x[0], 1.0) boundary_markers = df.MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundary_markers.set_all(0) Bottom().mark(boundary_markers, 1) Right().mark(boundary_markers, 2) Top().mark(boundary_markers, 3) Left().mark(boundary_markers, 4) class Pinpoint(df.SubDomain): def inside(self, x, on_boundary): return df.near(x[0], 0.0) and df.near(x[1], 1.0) class PeriodicBoundary(df.SubDomain): # Left boundary is "target domain" G def inside(self, x, on_boundary): return bool(on_boundary and (df.near(x[0], 0.0))) # Map right boundary (H) to left boundary (G) def map(self, x, y): y[0] = x[0] - 1.0 y[1] = x[1] return mesh, boundary_markers, Pinpoint(), PeriodicBoundary()
def read_attribute_group(self, key): try: group = self.file[key] first = group['0'] dim = self.dimension_dict[first.shape[0]] dtype = type_dict[first.dtype.kind] meshfunctions = [] ii = 0 key = f'{ii}' while key in group: dset = group[key] meshfunctions.append(dolfin.MeshFunction( dtype, self.mesh, dim)) meshfunctions[-1].set_values(dset[:]) ii += 1 key = f'{ii}' return meshfunctions except: raise Exception(f'Error reading attribute group: {key}')
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 demo_cellfunction(mesh): try: import dolfinplot as dfp except: raise IOError( "Misssing dolfinplot. git clone https://bitbucket.org/finsberg/dolfinplot.git" ) import dolfin as df cfun = df.MeshFunction("size_t", mesh, 3, mesh.domains()) V = df.FunctionSpace(mesh, "DG", 0) f = df.Function(V) f.vector()[:] = cfun.array() vtkfun = dfp.VTK_DolfinScalar(f) vtkfun.SetEdgeColor((0, 0, 0)) focal = (mesh.coordinates().T[0].max()) / 2.0 vtkfun.Render(view="side", dpi=300, size=(1200, 800), focal=focal) #vtkfun.Show() return vtkfun
def setUp(self): dl.parameters["ghost_mode"] = "shared_facet" ndim = 2 nx = 10 ny = 10 self.mesh = dl.UnitSquareMesh(nx, ny) self.rank = dl.MPI.rank(self.mesh.mpi_comm()) Vh2 = dl.FunctionSpace(self.mesh, 'Lagrange', 2) Vh1 = dl.FunctionSpace(self.mesh, 'Lagrange', 1) self.Vh = [Vh2, Vh1, Vh2] # Initialize Expressions f = dl.Constant(0.0) u_bdr = dl.Expression("x[1]", degree=1) u_bdr0 = dl.Constant(0.0) bc = dl.DirichletBC(self.Vh[STATE], u_bdr, u_boundary) bc0 = dl.DirichletBC(self.Vh[STATE], u_bdr0, u_boundary) def pde_varf(u, m, p): return dl.exp(m) * dl.inner( dl.nabla_grad(u), dl.nabla_grad(p)) * dl.dx - f * p * dl.dx self.pde = PDEVariationalProblem(self.Vh, pde_varf, bc, bc0, is_fwd_linear=True) GC = GammaCenter() marker = dl.MeshFunction("size_t", self.mesh, self.mesh.topology().dim() - 1) marker.set_all(0) GC.mark(marker, 1) dss = dl.Measure("dS", domain=self.mesh, subdomain_data=marker) n = dl.Constant((0., 1.)) #dl.FacetNormal(Vh[STATE].mesh()) def qoi_varf(u, m): return dl.avg(dl.exp(m) * dl.dot(dl.grad(u), n)) * dss(1) self.qoi = VariationalQoi(self.Vh, qoi_varf)
def complex_domain(size=15): """Construct a complex meshfunction representing domains. Simple is defined as 0 defined on the left half (x < 0.5) If on the right half the function is 1 if y < 0.5 and 2 if y > 0.5 :param size: Resolution of the mesh :return: Domain function """ mesh = df.UnitSquareMesh(size, size) domain = df.MeshFunction("size_t", mesh, 2) # make MeshFunction with left = 0 and right = 1 if lower and 2 if upper for c in df.cells(mesh): if c.midpoint()[0] > 0.5: if c.midpoint()[1] > 0.5: domain[c] = 2 else: domain[c] = 1 return domain
def meshhdf(name): mesh = dolfin.Mesh() hdf = dolfin.HDF5File(mesh.mpi_comm(), name + "_hdf.h5", "r") hdf.read(mesh, "/mesh", False) boundary = (dolfin.MeshFunction('size_t', mesh, mesh.topology().dim() - 1, 0), { 'inner': 1, 'outer': 2 }) hdf.read(boundary[0], "/boundary") hdf.close() n = dolfin.FacetNormal(mesh) dx = dolfin.Measure("dx", domain=mesh) ds = dolfin.Measure("ds", domain=mesh, subdomain_data=boundary[0]) return (mesh, boundary, n, dx, ds)
def load_mesh_function(mesh_function, mesh, mf_dim=None): """ Load the mesh function file specified by the user. The file may be xml, or HDF5 (assuming the current dolfin installation has the support). Parameters ---------- mesh_function : str Name of the file that contains the desired mesh function information. mesh : dolfin.cpp.mesh.Mesh The dolfin mesh object that corresponds to the mesh function. Returns ------- mesh_func : dolfin.cpp.mesh.MeshFunctionSizet This function returns a dolfin mesh function object. """ mesh_func_classes = (dlf.cpp.mesh.MeshFunctionSizet, dlf.cpp.mesh.MeshFunctionDouble, dlf.cpp.mesh.MeshFunctionBool, dlf.cpp.mesh.MeshFunctionInt) if isinstance(mesh_function, mesh_func_classes): return mesh_function if mesh_function[-3:] == '.h5': mesh_func = __load_mesh_function_hdf5(mesh_function, mesh, mf_dim=mf_dim) else: mesh_func = dlf.MeshFunction('size_t', mesh, mesh_function) return mesh_func
def generate_mesh_with_cicular_subdomain(resolution, radius, plot_mesh=False): cx1, cy1 = 0.5, 0.5 lx, ly = 1.0, 1.0 # Define 2D geometry domain = mshr.Rectangle(dl.Point(0.0, 0.0), dl.Point(lx, ly)) domain.set_subdomain(1, mshr.Circle(dl.Point(cx1, cy1), radius)) cx2, cy2 = cx1 - radius / np.sqrt(8), cy1 - radius / np.sqrt(8) domain.set_subdomain(2, mshr.Circle(dl.Point(cx2, cy2), radius / 2)) # Generate and plot mesh mesh2d = mshr.generate_mesh(domain, resolution) if plot_mesh: dl.plot(mesh2d, "2D mesh") class Circle1(dl.SubDomain): def inside(self, x, on_boundary): return pow(x[0] - cx1, 2) + pow(x[1] - cy1, 2) <= pow( radius, 2) class Circle2(dl.SubDomain): def inside(self, x, on_boundary): return pow(x[0] - cx2, 2) + pow(x[1] - cy2, 2) <= pow( radius / 2, 2) # Convert subdomains to mesh function for plotting mf = dl.MeshFunction("size_t", mesh2d, 2) mf.set_all(0) circle1 = Circle1() circle2 = Circle2() for c in dl.cells(mesh2d): if circle1.inside(c.midpoint(), True): mf[c.index()] = 1 if circle2.inside(c.midpoint(), True): mf[c.index()] = 2 dl.plot(mf, "Subdomains") # show must be called here or plot gets messed up # plt.show() return mesh2d
def generate_polygonal_mesh(resolution, ampothem, nedges, radius, plot_mesh=False): """ Sometimes segault is thrown when mshr.generate_mesh() is called. This is because resolution is to low to resolve smaller inner-most circle. """ import mshr vertices = get_vertices_of_polygon(ampothem, nedges) domain_vertices = [] for vertex in vertices.T: domain_vertices.append(dl.Point(vertex[0], vertex[1])) domain = mshr.Polygon(domain_vertices) cx1, cy1 = 0.0, 0.0 circle1 = mshr.Circle(dl.Point(cx1, cy1), radius) domain.set_subdomain(1, circle1) cx2, cy2 = cx1 - radius / np.sqrt(8), cy1 - radius / np.sqrt(8) circle2 = mshr.Circle(dl.Point(cx2, cy2), radius / 2) domain.set_subdomain(2, circle2) mesh = mshr.generate_mesh(domain, resolution) if plot_mesh: subdomains = dl.MeshFunction('size_t', mesh, mesh.topology().dim(), 2) subdomains.set_all(0) subdomain1 = dl.AutoSubDomain(lambda x: np.sqrt( (x[0] - cx1)**2 + (x[1] - cy1)**2) < radius + 1e-8) subdomain1.mark(subdomains, 1) subdomain2 = dl.AutoSubDomain(lambda x: np.sqrt( (x[0] - cx2)**2 + (x[1] - cy2)**2) < radius / 2 + 1e-8) subdomain2.mark(subdomains, 2) dl.plot(mesh) dl.plot(subdomains) plt.show() return mesh