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 get(self): """Built-in polygonal mesh.""" params = self.pad(self.values) if params[1]: vertices = convex_hull(params[0]) else: vertices = params[0] vertices = [Point(*p) for p in vertices] size = params[2] try: # may fail if not counterclockwise vertices poly = Polygon(vertices) except: poly = Polygon(vertices[::-1]) return generate_mesh(poly, size)
def build_fin(loc, l, d): """ Build a fin as a domain to be meshed Input: loc - location of outer most corner coordinates [x, y] l - length of fin d - thickness of fin Output: fin - fin domain """ # define the fin as a polygon angle = np.radians(45) # vertices, proceeding counter-clockwise pts = np.zeros((2, 6)) # leave pts[:, 0] alone pts[:, 1] = [l * np.cos(angle), l * np.sin(angle)] pts[:, 2] = [(l + d) * np.cos(angle), (l - d) * np.sin(angle)] pts[:, 3] = [d / np.cos(angle), 0] pts[0, 4] = pts[0, 2] # flip point along x-axis pts[1, 4] = -pts[1, 2] pts[0, 5] = pts[0, 1] pts[1, 5] = -pts[1, 1] # shift over to loc # convert to mshr Points points = [] for j in range(6): points.append(Point(pts[:, -j] + loc)) # build polygon poly = Polygon(points) return poly
def get(self): """ Generate polygon from top and bottom curves. """ radius, N = self.pad(self.values) radius = evaluate(radius)[0] points = [ Point(*(radius(theta) * np.array([cos(theta), sin(theta)]))) for theta in np.linspace(0, 2 * np.pi, N + 2) ] if abs(radius(0) - radius(2 * np.pi)) < 1E-4: points.pop() try: # may fail if not counterclockwise vertices poly = Polygon(points) except: poly = Polygon(points[::-1]) return generate_mesh(poly, 1)
def get(self): """ Generate polygon from top and bottom curves. """ m, M, top, bottom, var, N = self.pad(self.values) top = evaluate(top)[0] bottom = evaluate(bottom)[0] if var == 'x': points = [Point(x, top(x)) for x in np.linspace(m, M, N + 2)] else: points = [Point(top(x), x) for x in np.linspace(m, M, N + 2)] if abs(top(M) - bottom(M)) < 1E-4: points.pop() if var == 'x': points += [Point(x, bottom(x)) for x in np.linspace(M, m, N + 2)] else: points += [Point(bottom(x), x) for x in np.linspace(M, m, N + 2)] if abs(top(m) - bottom(m)) < 1E-4: points.pop() try: # may fail if not counterclockwise vertices poly = Polygon(points) except: poly = Polygon(points[::-1]) return generate_mesh(poly, 1)
def coupled_ridge_waveguides(w_wg1, w_wg2, w_gap, w_wing1, w_wing2, h_total, h_mem): # manually define all points domain_vertices = [] x = 0.0 y = 0.0 domain_vertices.append(Point(x, y)) x = 0.0 y = h_mem domain_vertices.append(Point(x, y)) x += w_wing1 y = h_mem domain_vertices.append(Point(x, y)) x = x y = h_total domain_vertices.append(Point(x, y)) x += w_wg1 y = h_total domain_vertices.append(Point(x, y)) x = x y = h_mem domain_vertices.append(Point(x, y)) x += w_gap y = h_mem domain_vertices.append(Point(x, y)) x = x y = h_total domain_vertices.append(Point(x, y)) x += w_wg2 y = h_total domain_vertices.append(Point(x, y)) x = x y = h_mem domain_vertices.append(Point(x, y)) x += w_wing2 y = h_mem domain_vertices.append(Point(x, y)) x = x y = 0.0 domain_vertices.append(Point(x, y)) domain_vertices.reverse() # need counter clockwise order domain = Polygon(domain_vertices) return domain
############################################################################################################# ### Test 1: Hexagon ############################################################################################################# for N in range(4, 21): x = empty((N, )) y = empty((N, )) for n in range(N): x[n] = cos(2. * pi * n / N) y[n] = sin(2. * pi * n / N) interior_angles = 180. * (N - 2) / N if interior_angles > 90: interior_angles = 180 - interior_angles mesh = generate_mesh(Polygon([Point(xx, yy) for xx, yy in zip(x, y)]), N) markers1 = detect_colinearity(mesh, interior_angles - 1) markers2 = detect_colinearity(mesh, interior_angles + 1) # number of tags should be equal to the number of sides of the polygon plus the interior tag if len(unique(markers1.array())) != N + 1: raise RuntimeError( 'Test failed: number of tags assigned by colinearity_detection is wrong' ) # number of tags should be equal to the number of sides of the polygon divided by 2 plus the interior tag # this is because colinearity is checked with respect to the first untagged facet found if len(unique(markers2.array())) != int(N / 2) + 1: raise RuntimeError(
def cylinder(dim, radii, height, n_refinements=0): """ Creates the mesh of a cylinder using the mshr module. """ assert isinstance(dim, int) assert dim == 2 or dim == 3 assert isinstance(radii, (list, tuple)) and len(radii) == 2 rt, rb = radii assert isinstance(rb, float) and rb > 0. assert isinstance(rt, float) and rt > 0. assert isinstance(height, float) and height > 0. assert isinstance(n_refinements, int) and n_refinements >= 0 # mesh generation if dim == 2: bottom = dlfn.Point(0., 0.) top = dlfn.Point(0., height) elif dim == 3: bottom = dlfn.Point(0., 0., 0.) top = dlfn.Point(0., 0., height) if dim == 2: domain = Polygon([ dlfn.Point(-rb / 2., 0.), bottom, dlfn.Point(rb / 2., 0.), dlfn.Point(rt / 2., height), top, dlfn.Point(-rt / 2., height) ]) mesh = generate_mesh(domain, 10) elif dim == 3: domain = Cylinder(top, bottom, rt, rb, segments=100) mesh = generate_mesh(domain, 32) # 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) # calculate radius depending on the x[3] coordinate def radius(z): return rb + z * (rt - rb) / height # mark boundaries BoundaryMarkers = CylinderBoundaryMarkers gamma_side = CylinderBoundary(mesh=mesh, radius=radius) gamma_side.mark(facet_marker, BoundaryMarkers.side.value) if dim == 2: gamma_top = dlfn.CompiledSubDomain("near(x[1], height) && on_boundary", height=height) gamma_top.mark(facet_marker, BoundaryMarkers.top.value) gamma_bottom = dlfn.CompiledSubDomain("near(x[1], 0.0) && on_boundary") gamma_bottom.mark(facet_marker, BoundaryMarkers.bottom.value) elif dim == 3: gamma_top = dlfn.CompiledSubDomain("near(x[2], height) && on_boundary", height=height) gamma_top.mark(facet_marker, BoundaryMarkers.top.value) gamma_bottom = dlfn.CompiledSubDomain("near(x[2], 0.0) && on_boundary") gamma_bottom.mark(facet_marker, BoundaryMarkers.bottom.value) return mesh, facet_marker
def Regular(n, size=50): """Build mesh for a regular polygon with n sides.""" points = [(np.cos(2 * np.pi * i / n), np.sin(2 * np.pi * i / n)) for i in range(n)] polygon = Polygon([Point(*p) for p in points]) return generate_mesh(polygon, size)