def triangulate(self, options=None): if options is None: options = self._get_triangle_options() mesh_info = MeshInfo() mesh_info.set_points(self.vertices) if self.boundary is not None: segments = [] for b in self.boundary: segments += self.get_segments(b) mesh_info.set_facets(segments) if self.holes is not None: mesh_info.set_holes(self.holes) try: import locale except ImportError: use_locale = False else: use_locale = True prev_num_locale = locale.getlocale(locale.LC_NUMERIC) locale.setlocale(locale.LC_NUMERIC, "C") try: mesh = MeshInfo() internals.triangulate(options, mesh_info, mesh, MeshInfo(), None) finally: # restore previous locale if we've changed it if use_locale: locale.setlocale(locale.LC_NUMERIC, prev_num_locale) return mesh
def par_mesh(h, n): mesh_info = MeshInfo() # Set the vertices of the domain [0, 1]^2 mesh_info.set_points([ (0,0), (1,0), (1,1), (0,1)]) # Set the facets of the domain [0, 1]^2 mesh_info.set_facets([ [0,1], [1,2], [2,3], [3,0] ]) # Generate the tet mesh mesh = build(mesh_info, max_volume=(h)**2) node = np.array(mesh.points, dtype=np.float) cell = np.array(mesh.elements, dtype=np.int) tmesh = TriangleMesh(node, cell) # Partition the mesh cells into n parts if n > 1: edgecuts, parts = metis.part_mesh(tmesh, nparts=n, entity='node') else: NN = tmesh.number_of_nodes() parts = np.zeros(NN, dtype=np.int) tmesh.nodedata['partition'] = parts return tmesh
def domain(self, domaintype='meshpy'): if domaintype is 'meshpy': from meshpy.triangle import MeshInfo domain = MeshInfo() points = np.zeros((16, 2), dtype=np.float) points[0:4, :] = np.array([(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)], dtype=np.float) idx = np.arange(5, -1, -1) points[4:10, 0] = 0.25 + 0.1 * np.cos(idx * np.pi / 3) points[4:10, 1] = 0.75 + 0.1 * np.sin(idx * np.pi / 3) points[10:, 0] = 0.6 + 0.1 * np.cos(idx * np.pi / 3) points[10:, 1] = 0.4 + 0.1 * np.sin(idx * np.pi / 3) facets = np.zeros((16, 2), dtype=np.int) facets[0:4, :] = np.array([(0, 1), (1, 2), (2, 3), (3, 0)], dtype=np.int) facets[4:10, :] = np.array([(4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 4)], dtype=np.int) facets[10:, :] = np.array([(10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 10)], dtype=np.int) domain.set_points(points) domain.set_facets(facets) domain.set_holes([(0.25, 0.75), (0.6, 0.4)]) return domain
def generate_mesh(self, mesh_size=5): """Setup Mesh Object and Properties Go through generation Builder -> MeshInfo -> Mesh""" # TODO Look into section-properties on github? # TODO Are the values from meshpy.triangle accurate? mesh_info = MeshInfo() self.builder.set(mesh_info) self.mesh = build(mesh_info, max_volume=mesh_size) # Calculate Element Centroids # C = [(x1+x2+x3)/3 , (y1+y2+y3)/3] for i, e in enumerate(self.mesh.elements): p1 = self.mesh.points[e[0]] p2 = self.mesh.points[e[1]] p3 = self.mesh.points[e[2]] self.mesh_centroids[i] = ((p1[0] + p2[0] + p3[0]) / 3, (p1[1] + p2[1] + p3[1]) / 3) # Calculate Element Areas # A = abs(x1*y2 + x2*y3 + x3*y1 - y1*x2 - y2*x3 - y3*x1)/2 for i, e in enumerate(self.mesh.elements): p1 = self.mesh.points[e[0]] p2 = self.mesh.points[e[1]] p3 = self.mesh.points[e[2]] self.mesh_areas[i] = abs(p1[0] * p2[1] + p2[0] * p3[1] + p3[0] * p1[1] - p1[1] * p2[0] - p2[1] * p3[0] - p3[1] * p1[0]) / 2 # Assign material ids to elements # A bit verbose just to show calculations - might change later # this only accounts for circle assignments for primitive in self.ele_mat_primitive: r = primitive[0] prim_c = primitive[1] mat_id = primitive[2] for n, c in self.mesh_centroids.items(): if hypot(c[0] - prim_c[0], c[1] - prim_c[1]) < r: self.ele_mat[n] = mat_id
def triangle(box, h): from meshpy.triangle import MeshInfo, build mesh_info = MeshInfo() mesh_info.set_points([(box[0], box[2]), (box[1], box[2]), (box[1], box[3]), (box[0], box[3])]) mesh_info.set_facets([[0, 1], [1, 2], [2, 3], [3, 0]]) mesh = build(mesh_info, max_volume=h**2) point = np.array(mesh.points, dtype=np.float) cell = np.array(mesh.elements, dtype=np.int) return TriangleMesh(point, cell)
def domain(self, domaintype='meshpy'): if domaintype == 'meshpy': from meshpy.triangle import MeshInfo domain = MeshInfo() points = np.array([(0, 0), (48, 44), (48, 60), (0, 44)], dtype=np.float) facets = np.array([(0, 1), (1, 2), (2, 3), (3, 0)], dtype=np.int) domain.set_points(points) domain.set_facets(facets) return domain if domaintype == 'halfedge': return None
def make_mesh(max_volume): def round_trip_connect(seq): result = [] for i in range(len(seq)): result.append((i, (i+1)%len(seq))) return result shapes = read_shape() #from matplotlib.pyplot import plot,show #plot(shapes[0][:,0], shapes[0][:,1]) #show() from meshpy.geometry import GeometryBuilder, Marker builder = GeometryBuilder() for shape in shapes: from meshpy.geometry import make_box points = shape facets = round_trip_connect(range(len(points))) builder.add_geometry(points=points, facets=facets, facet_markers=Marker.FIRST_USER_MARKER) points, facets, facet_markers = make_box((-200, -600), (400, -300)) builder.add_geometry(points=points, facets=facets, facet_markers=facet_markers) def transform(pt): x, y = pt return -0.01*x, -0.01*y builder.apply_transform(transform) from meshpy.triangle import MeshInfo, build mi = MeshInfo() builder.set(mi) holes = [] for shape, sign, frac in zip(shapes, [1, 1, -1, 1, 1, 1], [0.5, 0, 0, 0, 0, 0]): avg = np.average(shape, axis=0) start_idx = int(frac*shape.shape[0]) start = shape[start_idx] holes.append(transform(start + sign*0.01*(avg-start))) mi.set_holes(holes) mesh = build(mi, allow_boundary_steiner=True, generate_faces=True, max_volume=max_volume) return mesh
def triangle_polygon_domain(points, facets, h, meshtype='tri'): from meshpy.triangle import MeshInfo, build mesh_info = MeshInfo() mesh_info.set_points(points) mesh_info.set_facets(facets) mesh = build(mesh_info, max_volume=h**2) node = np.array(mesh.points, dtype=np.float) cell = np.array(mesh.elements, dtype=np.int) if meshtype is 'tri': return TriangleMesh(node, cell) elif meshtype is 'polygon': mesh = TriangleMeshWithInfinityNode(TriangleMesh(node, cell)) pnode, pcell, pcellLocation = mesh.to_polygonmesh() return PolygonMesh(pnode, pcell, pcellLocation)
def triangle(box, h, meshtype='tri'): from meshpy.triangle import MeshInfo, build mesh_info = MeshInfo() mesh_info.set_points([(box[0], box[2]), (box[1], box[2]), (box[1], box[3]), (box[0], box[3])]) mesh_info.set_facets([[0,1], [1,2], [2,3], [3,0]]) mesh = build(mesh_info, max_volume=h**2) node = np.array(mesh.points, dtype=np.float) cell = np.array(mesh.elements, dtype=np.int) if meshtype is 'tri': return TriangleMesh(node, cell) elif meshtype is 'polygon': mesh = TriangleMeshWithInfinityNode(TriangleMesh(node, cell)) pnode, pcell, pcellLocation = mesh.to_polygonmesh() return PolygonMesh(pnode, pcell, pcellLocation)
def get_mesh_example(): area = rect((0.,0.),(1.,1.)) init = rect((0.1,0.1),(0.2,0.2)) goal1 = rect((0.8,0.8),(0.9,0.9)) goal2 = rect((0.2,0.8),(0.3,0.9)) env = area + goal1 + goal2 + init info = MeshInfo() info.set_points(env) info.set_facets(loop(0,4) + loop(4,8) + loop(8,12) + loop(12,16), facet_markers = [0]*4 + [1]*4 + [2]*4 + [3]*4) # Create 8 facets and apply markers 1-8 on them info.regions.resize(4) s = 0.05 info.regions[0] = [0.15, 0.15, 0, s] # Replace 0.1 by a smaller value to produce a finer mesh info.regions[1] = [0.25, 0.85, 1, s] # Fourth item specifies maximum area of triangles as a region attribute info.regions[2] = [0.85, 0.85, 2, s] # Replace 0.1 by a smaller value to produce a finer mesh info.regions[3] = [0.5, 0.5, 3, s] # Fourth item specifies maximum area of triangles as a region attribute mesh = build(info, volume_constraints=True, attributes=True, generate_faces=True, min_angle=20, mesh_order=1) return mesh
def make_mesh_triangle_trimesh(self, **params): """make_mesh_triangle_trimesh create mesh using trimesh.Trimesh """ c = params['c'] mesh_info = MeshInfo() # generate vertices and facets if params['obj'] == 'line': points, facets, faces = make_vertex_facets_line(params) elif params['obj'] == 'hexagon': points, facets, faces = make_vertex_facets_hexagon(params) elif params['obj'] == 'rect': points, facets, faces = make_vertex_facets_rect_trimesh(params) print('points = {0}\nfacets = {1}'.format(pformat(points), pformat(facets))) # mesh = trimesh.Trimesh(vertices=[[0, 0, 0], [0, 0, 1], [0, 1, 0]], # faces=[[0, 1, 2]]) face_attributes = { 'color': len(faces) * [0], 'state': [], 'freq': [], } print('face_attributes = {0}'.format(face_attributes)) mesh = trimesh.Trimesh(vertices=points, faces=faces) # print('mesh.edges = {0}'.format(mesh.edges)) # writing objects # mesh.write_vtk("trigrid.vtk") # f = open('trigrid.pkl', 'wb') # pickle.dump(mesh, f) # f.close() # joblib.dump(mesh, 'trigrid.pkl') # sys.exit() return mesh
def test_2d_gauss_theorem(actx_factory): """Verify Gauss's theorem explicitly on a mesh""" pytest.importorskip("meshpy") from meshpy.geometry import make_circle, GeometryBuilder from meshpy.triangle import MeshInfo, build geob = GeometryBuilder() geob.add_geometry(*make_circle(1)) mesh_info = MeshInfo() geob.set(mesh_info) mesh_info = build(mesh_info) from meshmode.mesh.io import from_meshpy from meshmode.mesh import BTAG_ALL mesh = from_meshpy(mesh_info, order=1) actx = actx_factory() dcoll = DiscretizationCollection(actx, mesh, order=2) volm_disc = dcoll.discr_from_dd(dof_desc.DD_VOLUME) x_volm = thaw(volm_disc.nodes(), actx) def f(x): return flat_obj_array( actx.np.sin(3 * x[0]) + actx.np.cos(3 * x[1]), actx.np.sin(2 * x[0]) + actx.np.cos(x[1])) f_volm = f(x_volm) int_1 = op.integral(dcoll, "vol", op.local_div(dcoll, f_volm)) prj_f = op.project(dcoll, "vol", BTAG_ALL, f_volm) normal = thaw(dcoll.normal(BTAG_ALL), actx) int_2 = op.integral(dcoll, BTAG_ALL, prj_f.dot(normal)) assert abs(int_1 - int_2) < 1e-13
def test_2d_gauss_theorem(actx_factory): """Verify Gauss's theorem explicitly on a mesh""" pytest.importorskip("meshpy") from meshpy.geometry import make_circle, GeometryBuilder from meshpy.triangle import MeshInfo, build geob = GeometryBuilder() geob.add_geometry(*make_circle(1)) mesh_info = MeshInfo() geob.set(mesh_info) mesh_info = build(mesh_info) from meshmode.mesh.io import from_meshpy mesh = from_meshpy(mesh_info, order=1) actx = actx_factory() discr = DGDiscretizationWithBoundaries(actx, mesh, order=2) def f(x): return flat_obj_array( sym.sin(3*x[0])+sym.cos(3*x[1]), sym.sin(2*x[0])+sym.cos(x[1])) gauss_err = bind(discr, sym.integral(( sym.nabla(2) * f(sym.nodes(2)) ).sum()) - # noqa: W504 sym.integral( sym.project("vol", sym.BTAG_ALL)(f(sym.nodes(2))) .dot(sym.normal(sym.BTAG_ALL, 2)), dd=sym.BTAG_ALL) )(actx) assert abs(gauss_err) < 1e-13
def make_mesh_triangle_meshpy(self, **params): """make_mesh_meshpy_triangle create mesh using meshpy.triangle.MeshInfo """ c = params['c'] mesh_info = MeshInfo() # generate vertices and facets if params['obj'] == 'line': points, facets, faces = make_vertex_facets_line(params) elif params['obj'] == 'hexagon': points, facets, faces = make_vertex_facets_hexagon(params) elif params['obj'] == 'rect': points, facets = make_vertex_facets_rect(params) print('points = {0}\nfacets = {1}'.format(pformat(points), pformat(facets))) # print('mesh_info.unit = {0}'.format(mesh_info.unit)) # copy points data into mesh mesh_info.set_points(points) # copy facets data into mesh mesh_info.set_facets(facets) # build the mesh mesh = build(mesh_info) # writing objects # mesh.write_vtk("trigrid.vtk") # f = open('trigrid.pkl', 'wb') # pickle.dump(mesh, f) # f.close() # joblib.dump(mesh, 'trigrid.pkl') # sys.exit() return mesh
def test_convergence_advec(ctx_factory, mesh_name, mesh_pars, op_type, flux_type, order, visualize=False): """Test whether 2D advection actually converges""" cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() for mesh_par in mesh_pars: if mesh_name == "segment": from meshmode.mesh.generation import generate_box_mesh mesh = generate_box_mesh([np.linspace(-1.0, 1.0, mesh_par)], order=order) dim = 1 dt_factor = 1.0 elif mesh_name == "disk": pytest.importorskip("meshpy") from meshpy.geometry import make_circle, GeometryBuilder from meshpy.triangle import MeshInfo, build geob = GeometryBuilder() geob.add_geometry(*make_circle(1)) mesh_info = MeshInfo() geob.set(mesh_info) mesh_info = build(mesh_info, max_volume=mesh_par) from meshmode.mesh.io import from_meshpy mesh = from_meshpy(mesh_info, order=1) dim = 2 dt_factor = 4 elif mesh_name.startswith("rect"): dim = int(mesh_name[4:]) from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, ) * dim, b=(0.5, ) * dim, n=(mesh_par, ) * dim, order=4) if dim == 2: dt_factor = 4 elif dim == 3: dt_factor = 2 else: raise ValueError("dt_factor not known for %dd" % dim) else: raise ValueError("invalid mesh name: " + mesh_name) v = np.array([0.27, 0.31, 0.1])[:dim] norm_v = la.norm(v) def f(x): return sym.sin(10 * x) def u_analytic(x): return f(-v.dot(x) / norm_v + sym.var("t", sym.DD_SCALAR) * norm_v) from grudge.models.advection import (StrongAdvectionOperator, WeakAdvectionOperator) discr = DGDiscretizationWithBoundaries(actx, mesh, order=order) op_class = { "strong": StrongAdvectionOperator, "weak": WeakAdvectionOperator, }[op_type] op = op_class(v, inflow_u=u_analytic(sym.nodes(dim, sym.BTAG_ALL)), flux_type=flux_type) bound_op = bind(discr, op.sym_operator()) u = bind(discr, u_analytic(sym.nodes(dim)))(actx, t=0) def rhs(t, u): return bound_op(t=t, u=u) if dim == 3: final_time = 0.1 else: final_time = 0.2 h_max = bind(discr, sym.h_max_from_volume(discr.ambient_dim))(actx) dt = dt_factor * h_max / order**2 nsteps = (final_time // dt) + 1 dt = final_time / nsteps + 1e-15 from grudge.shortcuts import set_up_rk4 dt_stepper = set_up_rk4("u", dt, u, rhs) last_u = None from grudge.shortcuts import make_visualizer vis = make_visualizer(discr, vis_order=order) step = 0 for event in dt_stepper.run(t_end=final_time): if isinstance(event, dt_stepper.StateComputed): step += 1 logger.debug("[%04d] t = %.5f", step, event.t) last_t = event.t last_u = event.state_component if visualize: vis.write_vtk_file("fld-%s-%04d.vtu" % (mesh_par, step), [("u", event.state_component)]) error_l2 = bind(discr, sym.norm(2, sym.var("u") - u_analytic(sym.nodes(dim))))( t=last_t, u=last_u) logger.info("h_max %.5e error %.5e", h_max, error_l2) eoc_rec.add_data_point(h_max, error_l2) logger.info( "\n%s", eoc_rec.pretty_print(abscissa_label="h", error_label="L2 Error")) assert eoc_rec.order_estimate() > order
def make_nacamesh(): def round_trip_connect(seq): result = [] for i in range(len(seq)): result.append((i, (i + 1) % len(seq))) return result pt_back = numpy.array([1, 0]) #def max_area(pt): #max_area_front = 1e-2*la.norm(pt)**2 + 1e-5 #max_area_back = 1e-2*la.norm(pt-pt_back)**2 + 1e-4 #return min(max_area_front, max_area_back) def max_area(pt): x = pt[0] if x < 0: return 1e-2 * la.norm(pt)**2 + 1e-5 elif x > 1: return 1e-2 * la.norm(pt - pt_back)**2 + 1e-5 else: return 1e-2 * pt[1]**2 + 1e-5 def needs_refinement(vertices, area): barycenter = sum(numpy.array(v) for v in vertices) / 3 return bool(area > max_area(barycenter)) from meshpy.naca import get_naca_points points = get_naca_points(naca_digits="2412", number_of_points=80) from meshpy.geometry import GeometryBuilder, Marker from meshpy.triangle import write_gnuplot_mesh profile_marker = Marker.FIRST_USER_MARKER builder = GeometryBuilder() builder.add_geometry(points=points, facets=round_trip_connect(points), facet_markers=profile_marker) builder.wrap_in_box(4, (10, 8)) from meshpy.triangle import MeshInfo, build mi = MeshInfo() builder.set(mi) mi.set_holes([builder.center()]) mesh = build( mi, refinement_func=needs_refinement, #allow_boundary_steiner=False, generate_faces=True) write_gnuplot_mesh("mesh.dat", mesh) print("%d elements" % len(mesh.elements)) fvi2fm = mesh.face_vertex_indices_to_face_marker face_marker_to_tag = { profile_marker: "noslip", Marker.MINUS_X: "inflow", Marker.PLUS_X: "outflow", Marker.MINUS_Y: "inflow", Marker.PLUS_Y: "inflow" #Marker.MINUS_Y: "minus_y", #Marker.PLUS_Y: "plus_y" } def bdry_tagger(fvi, el, fn, all_v): face_marker = fvi2fm[fvi] return [face_marker_to_tag[face_marker]] from grudge.mesh import make_conformal_mesh_ext vertices = numpy.asarray(mesh.points, order="C") from grudge.mesh.element import Triangle return make_conformal_mesh_ext( vertices, [ Triangle(i, el_idx, vertices) for i, el_idx in enumerate(mesh.elements) ], bdry_tagger, #periodicity=[None, ("minus_y", "plus_y")] )
from fealpy.mesh.TriangleMesh import TriangleMesh from fealpy.functionspace.mixed_fem_space import RaviartThomasFiniteElementSpace2d from fealpy.functionspace.mixed_fem_space import BDMFiniteElementSpace2d from fealpy.functionspace.mixed_fem_space import FirstNedelecFiniteElement2d def mesh_2dpy(mesh_info, h): mesh = build(mesh_info, max_volume=(h)**2) point = np.array(mesh.points, dtype=np.float) cell = np.array(mesh.elements, dtype=np.int) tmesh = TriangleMesh(point, cell) return tmesh mesh_info = MeshInfo() mesh_info.set_points([(0, 0), (1, 0), (1, 1), (0, 1)]) mesh_info.set_facets([[0, 1], [1, 2], [2, 3], [3, 0]]) h = 0.5 tmesh = mesh_2dpy(mesh_info, h) #point = np.array([ # (0, 0), # (1, 0), # (1, 1), # (0, 1)], dtype=np.float) #cell = np.array([ # (1, 2, 0), # (3, 0, 2)], dtype=np.int) #tmesh = TriangleMesh(point, cell)
def make_squaremesh(): def round_trip_connect(seq): result = [] for i in range(len(seq)): result.append((i, (i + 1) % len(seq))) return result def needs_refinement(vertices, area): x = sum(numpy.array(v) for v in vertices) / 3 max_area_volume = 0.7e-2 + 0.03 * (0.05 * x[1]**2 + 0.3 * min(x[0] + 1, 0)**2) max_area_corners = 1e-3 + 0.001 * max( la.norm(x - corner)**4 for corner in obstacle_corners) return bool(area > 2.5 * min(max_area_volume, max_area_corners)) from meshpy.geometry import make_box points, facets, _, _ = make_box((-0.5, -0.5), (0.5, 0.5)) obstacle_corners = points[:] from meshpy.geometry import GeometryBuilder, Marker profile_marker = Marker.FIRST_USER_MARKER builder = GeometryBuilder() builder.add_geometry(points=points, facets=facets, facet_markers=profile_marker) points, facets, _, facet_markers = make_box((-16, -22), (25, 22)) builder.add_geometry(points=points, facets=facets, facet_markers=facet_markers) from meshpy.triangle import MeshInfo, build mi = MeshInfo() builder.set(mi) mi.set_holes([(0, 0)]) mesh = build(mi, refinement_func=needs_refinement, allow_boundary_steiner=True, generate_faces=True) print("%d elements" % len(mesh.elements)) from meshpy.triangle import write_gnuplot_mesh write_gnuplot_mesh("mesh.dat", mesh) fvi2fm = mesh.face_vertex_indices_to_face_marker face_marker_to_tag = { profile_marker: "noslip", Marker.MINUS_X: "inflow", Marker.PLUS_X: "outflow", Marker.MINUS_Y: "inflow", Marker.PLUS_Y: "inflow" } def bdry_tagger(fvi, el, fn, all_v): face_marker = fvi2fm[fvi] return [face_marker_to_tag[face_marker]] from grudge.mesh import make_conformal_mesh_ext vertices = numpy.asarray(mesh.points, dtype=float, order="C") from grudge.mesh.element import Triangle return make_conformal_mesh_ext(vertices, [ Triangle(i, el_idx, vertices) for i, el_idx in enumerate(mesh.elements) ], bdry_tagger)
import numpy as np import matplotlib.pyplot as plt from meshpy.triangle import MeshInfo, build # Utility function to create lists of the form [(1,2), (2,3), (3,4), # (4,1)], given two numbers 1 and 4 from itertools import islice, cycle def loop(a, b): return list( zip(list(range(a, b)), islice(cycle(list(range(a, b))), 1, None))) info = MeshInfo() info.set_points([(0, 0), (1, 0), (1, 1), (0, 1), (2, 0), (3, 0), (3, 1), (2, 1)]) info.set_facets(loop(0, 4) + loop(4, 8), list(range( 1, 9))) # Create 8 facets and apply markers 1-8 on them info.regions.resize(2) info.regions[0] = [ 0.5, 0.5, 1, 0.1, ] # Fourth item specifies maximum area of triangles as a region attribute info.regions[1] = [ 2.5, 0.5, 2,
def test_convergence_advec(actx_factory, mesh_name, mesh_pars, op_type, flux_type, order, visualize=False): """Test whether 2D advection actually converges""" actx = actx_factory() from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() for mesh_par in mesh_pars: if mesh_name == "segment": mesh = mgen.generate_box_mesh([np.linspace(-1.0, 1.0, mesh_par)], order=order) dim = 1 dt_factor = 1.0 elif mesh_name == "disk": pytest.importorskip("meshpy") from meshpy.geometry import make_circle, GeometryBuilder from meshpy.triangle import MeshInfo, build geob = GeometryBuilder() geob.add_geometry(*make_circle(1)) mesh_info = MeshInfo() geob.set(mesh_info) mesh_info = build(mesh_info, max_volume=mesh_par) from meshmode.mesh.io import from_meshpy mesh = from_meshpy(mesh_info, order=1) dim = 2 dt_factor = 4 elif mesh_name.startswith("rect"): dim = int(mesh_name[-1:]) mesh = mgen.generate_regular_rect_mesh( a=(-0.5, ) * dim, b=(0.5, ) * dim, nelements_per_axis=(mesh_par, ) * dim, order=4) if dim == 2: dt_factor = 4 elif dim == 3: dt_factor = 2 else: raise ValueError("dt_factor not known for %dd" % dim) elif mesh_name.startswith("warped"): dim = int(mesh_name[-1:]) mesh = mgen.generate_warped_rect_mesh(dim, order=order, nelements_side=mesh_par) if dim == 2: dt_factor = 4 elif dim == 3: dt_factor = 2 else: raise ValueError("dt_factor not known for %dd" % dim) else: raise ValueError("invalid mesh name: " + mesh_name) v = np.array([0.27, 0.31, 0.1])[:dim] norm_v = la.norm(v) def f(x): return actx.np.sin(10 * x) def u_analytic(x, t=0): return f(-v.dot(x) / norm_v + t * norm_v) from grudge.models.advection import (StrongAdvectionOperator, WeakAdvectionOperator) from meshmode.mesh import BTAG_ALL dcoll = DiscretizationCollection(actx, mesh, order=order) op_class = { "strong": StrongAdvectionOperator, "weak": WeakAdvectionOperator }[op_type] adv_operator = op_class(dcoll, v, inflow_u=lambda t: u_analytic( thaw(dcoll.nodes(dd=BTAG_ALL), actx), t=t), flux_type=flux_type) nodes = thaw(dcoll.nodes(), actx) u = u_analytic(nodes, t=0) def rhs(t, u): return adv_operator.operator(t, u) if dim == 3: final_time = 0.1 else: final_time = 0.2 from grudge.dt_utils import h_max_from_volume h_max = h_max_from_volume(dcoll, dim=dcoll.ambient_dim) dt = dt_factor * h_max / order**2 nsteps = (final_time // dt) + 1 dt = final_time / nsteps + 1e-15 from grudge.shortcuts import set_up_rk4 dt_stepper = set_up_rk4("u", dt, u, rhs) last_u = None from grudge.shortcuts import make_visualizer vis = make_visualizer(dcoll) step = 0 for event in dt_stepper.run(t_end=final_time): if isinstance(event, dt_stepper.StateComputed): step += 1 logger.debug("[%04d] t = %.5f", step, event.t) last_t = event.t last_u = event.state_component if visualize: vis.write_vtk_file("fld-%s-%04d.vtu" % (mesh_par, step), [("u", event.state_component)]) error_l2 = op.norm(dcoll, last_u - u_analytic(nodes, t=last_t), 2) logger.info("h_max %.5e error %.5e", h_max, error_l2) eoc_rec.add_data_point(h_max, actx.to_numpy(error_l2)) logger.info( "\n%s", eoc_rec.pretty_print(abscissa_label="h", error_label="L2 Error")) if mesh_name.startswith("warped"): # NOTE: curvilinear meshes are hard assert eoc_rec.order_estimate() > order - 0.5 else: assert eoc_rec.order_estimate() > order
def uniform_refine_triangles(points, elements, factor=2): new_points = points[:] new_elements = [] old_face_to_new_faces = {} face_point_dict = {} points_per_edge = factor + 1 def get_refined_face(a, b): if a > b: a, b = b, a flipped = True else: flipped = False try: face_points = face_point_dict[a, b] except KeyError: a_pt, b_pt = [points[idx] for idx in [a, b]] dx = (b_pt - a_pt) / factor # build subdivided facet face_points = [a] for i in range(1, points_per_edge - 1): face_points.append(len(new_points)) new_points.append(a_pt + dx * i) face_points.append(b) face_point_dict[a, b] = face_points # build old_face_to_new_faces old_face_to_new_faces[frozenset([a, b])] = [ (face_points[i], face_points[i + 1]) for i in range(factor) ] if flipped: return face_points[::-1] else: return face_points for a, b, c in elements: a_pt, b_pt, c_pt = [points[idx] for idx in [a, b, c]] dr = (b_pt - a_pt) / factor ds = (c_pt - a_pt) / factor ab_refined, bc_refined, ac_refined = [ get_refined_face(*pt_indices) for pt_indices in [(a, b), (b, c), (a, c)] ] el_point_dict = {} # fill out edges of el_point_dict for i in range(points_per_edge): el_point_dict[i, 0] = ab_refined[i] el_point_dict[0, i] = ac_refined[i] el_point_dict[points_per_edge - 1 - i, i] = bc_refined[i] # fill out interior of el_point_dict for i in range(1, points_per_edge - 1): for j in range(1, points_per_edge - 1 - i): el_point_dict[i, j] = len(new_points) new_points.append(a_pt + dr * i + ds * j) # generate elements for i in range(0, points_per_edge - 1): for j in range(0, points_per_edge - 1 - i): new_elements.append(( el_point_dict[i, j], el_point_dict[i + 1, j], el_point_dict[i, j + 1], )) if i + 1 + j + 1 <= factor: new_elements.append(( el_point_dict[i + 1, j + 1], el_point_dict[i + 1, j], el_point_dict[i, j + 1], )) from meshpy.triangle import MeshInfo mi = MeshInfo() mi.set_points(new_points) mi.elements.resize(len(new_elements)) for i, el in enumerate(new_elements): mi.elements[i] = el from meshpy.triangle import write_gnuplot_mesh write_gnuplot_mesh("mesh.dat", mi) return new_points, new_elements, old_face_to_new_faces
from meshpy.triangle import MeshInfo, build import numpy as np import matplotlib.pyplot as plt from fealpy.mesh import TriangleMesh domain = MeshInfo() domain.set_points([(0,0),(1,0),(1,1),(0,1)]) domain.set_facets([(0,1),(1,2),(2,3),(3,0)], facet_markers=[1, 2, 3, 4]) mesh = build(domain, max_volume = 0.1**2, attributes=True) node = np.array(mesh.points, dtype = np.float) cell = np.array(mesh.elements, dtype = np.int) tmesh = TriangleMesh(node, cell) fig = plt.figure() axes = fig.gca() tmesh.add_plot(axes) cell = tmesh.entity('cell') node = tmesh.entity('node') NN = tmesh.number_of_nodes() isBdNode = tmesh.ds.boundary_node_flag() newNode = np.zeros((NN, 2), dtype=np.float) degree = np.zeros(NN, dtype=np.int) np.add.at(degree, cell, 1) for i in range(10): #bc = tmesh.entity_barycenter('cell') bc, R = tmesh.circumcenter() np.add.at(newNode, (cell, np.s_[:]), bc[:, np.newaxis, :]) newNode /= degree[:, np.newaxis] node[~isBdNode] = newNode[~isBdNode] newNode[:] = 0