def test(lcar=0.05): geom = pygmsh.built_in.Geometry() # Draw a square poly = geom.add_polygon( [[+0.5, +0.0, 0.0], [+0.0, +0.5, 0.0], [-0.5, +0.0, 0.0], [+0.0, -0.5, 0.0]], lcar=lcar, ) axis = [0, 0, 1.0] geom.extrude( poly, translation_axis=axis, rotation_axis=axis, point_on_axis=[0.0, 0.0, 0.0], angle=0.5 * pi, num_layers=5, recombine=True, ) ref = 3.98156496566 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def test(lcar=0.05): geom = pygmsh.built_in.Geometry() # Draw a cross with a circular hole circ = geom.add_circle([0.0, 0.0, 0.0], 0.1, lcar=lcar) poly = geom.add_polygon( [ [+0.0, +0.5, 0.0], [-0.1, +0.1, 0.0], [-0.5, +0.0, 0.0], [-0.1, -0.1, 0.0], [+0.0, -0.5, 0.0], [+0.1, -0.1, 0.0], [+0.5, +0.0, 0.0], [+0.1, +0.1, 0.0], ], lcar=lcar, holes=[circ], ) axis = [0, 0, 1.0] geom.extrude( poly, translation_axis=axis, rotation_axis=axis, point_on_axis=[0, 0, 0], angle=2.0 / 6.0 * np.pi, ) ref = 0.16951514066385628 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def test(): geom = pygmsh.built_in.Geometry() X0 = np.array( [[+0.0, +0.0, 0.0], [+0.5, +0.3, 0.1], [-0.5, +0.3, 0.1], [+0.5, -0.3, 0.1]] ) R = np.array([0.1, 0.2, 0.1, 0.14]) holes = [ geom.add_ball(x0, r, with_volume=False, lcar=0.2 * r).surface_loop for x0, r in zip(X0, R) ] # geom.add_box( # -1, 1, # -1, 1, # -1, 1, # lcar=0.2, # holes=holes # ) geom.add_ball([0, 0, 0], 1.0, lcar=0.2, holes=holes) # geom.add_physical_volume(ball, label="cheese") ref = 4.07064892966291 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 2.0e-2 * ref return mesh
def test(): geom = pygmsh.built_in.Geometry() geom.add_circle([0, 0, 0], 1, 0.1, make_surface=False) mesh = pygmsh.generate_mesh(geom) ref = 2 * np.pi assert np.abs(compute_volume(mesh) - ref) < 1e-2 * ref return
def test_fragments_diff_union(): """Test planar surface with holes. Construct it with boolean operations and verify that it is the same. """ # construct surface using boolean geo_object = pygmsh.opencascade.Geometry(0.04, 0.04) geo_object, square = square_loop(geo_object) geo_object, line_loop = circle_loop(geo_object) surf1 = geo_object.add_plane_surface(square) surf2 = geo_object.add_plane_surface(line_loop) geo_object.add_physical([surf1], label=1) geo_object.add_physical([surf2], label=2) surf_diff = geo_object.boolean_difference([surf1], [surf2], delete_other=False) geo_object.boolean_union([surf_diff, surf2]) mesh = pygmsh.generate_mesh(geo_object) assert np.abs((compute_volume(mesh) - 1) / 1) < 1e-3 surf = 1 - 0.1 ** 2 * np.pi outer_mask = np.where(mesh.cell_data["triangle"]["gmsh:physical"] == 1)[0] outer_cells = {} outer_cells["triangle"] = mesh.cells["triangle"][outer_mask] inner_mask = np.where(mesh.cell_data["triangle"]["gmsh:physical"] == 2)[0] inner_cells = {} inner_cells["triangle"] = mesh.cells["triangle"][inner_mask] value = compute_volume(meshio.Mesh(mesh.points, outer_cells)) assert np.abs((value - surf)) < 1e-2 * surf return
def test(): geom = pygmsh.opencascade.Geometry( characteristic_length_min=2.0, characteristic_length_max=2.0 ) rect1 = geom.add_rectangle([10.0, 0.0, 0.0], 20.0, 40.0, corner_radius=5.0) rect2 = geom.add_rectangle([0.0, 10.0, 0.0], 40.0, 20.0, corner_radius=5.0) disk1 = geom.add_disk([14.5, 35.0, 0.0], 1.85) disk2 = geom.add_disk([25.5, 5.0, 0.0], 1.85) rect3 = geom.add_rectangle([10.0, 30.0, 0.0], 10.0, 1.0) rect4 = geom.add_rectangle([20.0, 9.0, 0.0], 10.0, 1.0) r1 = geom.add_rectangle([9.0, 0.0, 0.0], 21.0, 20.5, corner_radius=8.0) r2 = geom.add_rectangle([10.0, 00.0, 0.0], 20.0, 19.5, corner_radius=7.0) diff1 = geom.boolean_difference([r1], [r2]) r22 = geom.add_rectangle([9.0, 10.0, 0.0], 11.0, 11.0) inter1 = geom.boolean_intersection([diff1, r22]) r3 = geom.add_rectangle([10.0, 19.5, 0.0], 21.0, 21.0, corner_radius=8.0) r4 = geom.add_rectangle([10.0, 20.5, 0.0], 20.0, 20.0, corner_radius=7.0) diff2 = geom.boolean_difference([r3], [r4]) r33 = geom.add_rectangle([20.0, 19.0, 0.0], 11.0, 11.0) inter2 = geom.boolean_intersection([diff2, r33]) geom.boolean_difference( [rect1, rect2], [disk1, disk2, rect3, rect4, inter1, inter2] ) mesh = pygmsh.generate_mesh(geom) ref = 1082.4470502181903 assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def test(lcar=1.0): lbw = [2, 3, 5] geom = pygmsh.built_in.Geometry() points = [geom.add_point([x, 0.0, 0.0], lcar) for x in [0.0, lbw[0]]] line = geom.add_line(*points) _, rectangle, _ = geom.extrude( line, translation_axis=[0.0, lbw[1], 0.0], num_layers=lbw[1], recombine=True ) geom.extrude( rectangle, translation_axis=[0.0, 0.0, lbw[2]], num_layers=lbw[2], recombine=True, ) # compute_volume only supports 3D for tetras, but does return # surface area for quads ref = sum(l * w for l, w in permutations(lbw, 2)) # surface area mesh = pygmsh.generate_mesh(geom, prune_vertices=False) # TODO compute hex volumes assert ( abs( compute_volume(meshio.Mesh(mesh.points, {"quad": mesh.cells["quad"]})) - ref ) < 1.0e-2 * ref ) return mesh
def test(lcar=0.05): geom = pygmsh.built_in.Geometry() # Draw a cross with a circular hole circ = geom.add_circle([0.0, 0.0, 0.0], 0.1, lcar=lcar, make_surface=False) poly = geom.add_polygon( [ [+0.0, +0.5, 0.0], [-0.1, +0.1, 0.0], [-0.5, +0.0, 0.0], [-0.1, -0.1, 0.0], [+0.0, -0.5, 0.0], [+0.1, -0.1, 0.0], [+0.5, +0.0, 0.0], [+0.1, +0.1, 0.0], ], lcar=lcar, holes=[circ], ) axis = [0, 0, 1.0] geom.extrude(poly, translation_axis=axis, num_layers=1) ref = 0.16951514066385628 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def test_square_circle_slice(): """Test planar suface square with circular hole. Also test for surface area of fragments. """ geo_object = built_in_opencascade_geos_fragments() # Gmsh 4 default format MSH4 doesn't have geometrical entities. mesh = pygmsh.generate_mesh(geo_object, extra_gmsh_arguments=["-format", "msh2"]) ref = 1 val = compute_volume(mesh) assert np.abs(val - ref) < 1e-3 * ref outer_mask = np.where(mesh.cell_data["triangle"]["gmsh:geometrical"] == 13)[0] outer_cells = {} outer_cells["triangle"] = mesh.cells["triangle"][outer_mask] inner_mask = np.where(mesh.cell_data["triangle"]["gmsh:geometrical"] == 12)[0] inner_cells = {} inner_cells["triangle"] = mesh.cells["triangle"][inner_mask] ref = 1 - 0.1 ** 2 * np.pi value = compute_volume(meshio.Mesh(mesh.points, outer_cells)) assert np.abs(value - ref) < 1e-2 * ref return
def test(): # Characteristic length lcar = 1e-1 # Coordinates of lower-left and upper-right vertices of a square domain xmin = 0.0 xmax = 5.0 ymin = 0.0 ymax = 5.0 # Vertices of a square hole squareHoleCoordinates = np.array([[1, 1, 0], [4, 1, 0], [4, 4, 0], [1, 4, 0]]) # Create geometric object geom = pygmsh.built_in.Geometry() # Create square hole squareHole = geom.add_polygon(squareHoleCoordinates, lcar, make_surface=False) # Create square domain with square hole geom.add_rectangle(xmin, xmax, ymin, ymax, 0.0, lcar, holes=[squareHole.line_loop]) mesh = pygmsh.generate_mesh(geom, extra_gmsh_arguments=["-order", "2"]) # TODO support for volumes of triangle6 # ref = 16.0 # from helpers import compute_volume # assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return mesh
def mesh(mesh_path, lc, H, L, b_dist, b_h, b_l, f_l, f_h, **NS_namespace): # Name mesh after local cell length mesh_path = mesh_path.format(lc) if not path.exists(mesh_path): # Initialize geometry geom = pygmsh.built_in.geometry.Geometry() # Surounding box b0 = geom.add_point([0, 0, 0], lcar=lc*2) b1 = geom.add_point([L, 0, 0], lcar=lc*2) b2 = geom.add_point([L, H, 0], lcar=lc*2) b3 = geom.add_point([0, H, 0], lcar=lc*2) # Inner geometry f0 = geom.add_point([b_dist, H / 2 - b_h / 2, 0], lcar=lc/3) f1 = geom.add_point([b_dist + b_l, H / 2 - b_h / 2, 0], lcar=lc/3) f2 = geom.add_point([b_dist + b_l, H / 2 - f_h / 2, 0], lcar=lc/3) f3 = geom.add_point([b_dist + b_l + f_l, H / 2 - f_h / 2, 0], lcar=lc/3) f4 = geom.add_point([b_dist + b_l + f_l, H / 2 + f_h / 2, 0], lcar=lc/3) f5 = geom.add_point([b_dist + b_l, H / 2 + f_h / 2, 0], lcar=lc/3) f6 = geom.add_point([b_dist + b_l, H / 2 + b_h / 2, 0], lcar=lc/3) f7 = geom.add_point([b_dist, H / 2 + b_h / 2, 0], lcar=lc/3) # Draw lines l0 = geom.add_line(b0, b1) l1 = geom.add_line(b1, b2) l2 = geom.add_line(b2, b3) l3 = geom.add_line(b3, b0) l4 = geom.add_line(f0, f1) l5 = geom.add_line(f1, f2) l6 = geom.add_line(f2, f3) l7 = geom.add_line(f3, f4) l8 = geom.add_line(f4, f5) l9 = geom.add_line(f5, f6) l10 = geom.add_line(f6, f7) l11 = geom.add_line(f7, f0) # Gather lines ll_outer = geom.add_line_loop(lines=[l0, l1, l2, l3]) ll_inner = geom.add_line_loop(lines=[l4, l5, l6, l7, l8, l9, l10, l11]) # Set surface ps = geom.add_plane_surface(ll_outer, [ll_inner]) # Mesh surface points, cells, point_data, cell_data, field_data = pygmsh.generate_mesh(geom) # Write mesh meshio.write(mesh_path, meshio.Mesh( points=points, cells={"triangle": cells["triangle"]})) mesh = Mesh() with XDMFFile(MPI.comm_world, mesh_path) as infile: infile.read(mesh) return mesh
def test(): geom = pygmsh.built_in.Geometry() geom.add_ellipsoid([0.0, 0.0, 0.0], [1.0, 0.5, 0.75], 0.05) ref = 1.5676038497587947 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def front_mesh(res=0.025): geometry = Geometry() c = geometry.add_point((c_x, c_y, 0)) mesh_r = 5 * res # Width of mesh # Elliptic obstacle p1 = geometry.add_point((c_x - r_x, c_y, 0)) p2 = geometry.add_point((c_x, c_y + r_y, 0)) p3 = geometry.add_point((c_x + r_x, c_y, 0)) p4 = geometry.add_point((c_x, c_y - r_y, 0)) arc_1 = geometry.add_ellipse_arc(p1, c, p2, p2) arc_2 = geometry.add_ellipse_arc(p2, c, p3, p3) arc_3 = geometry.add_ellipse_arc(p3, c, p4, p4) arc_4 = geometry.add_ellipse_arc(p4, c, p1, p1) obstacle_loop = geometry.add_line_loop([arc_1, arc_2, arc_3, arc_4]) # Surrounding mesh p1 = geometry.add_point((c_x - r_x - mesh_r, c_y, 0)) p2 = geometry.add_point((c_x, c_y + r_y + mesh_r, 0)) p3 = geometry.add_point((c_x + r_x + mesh_r, c_y, 0)) p4 = geometry.add_point((c_x, c_y - r_y - mesh_r, 0)) arc_5 = geometry.add_ellipse_arc(p1, c, p2, p2) arc_6 = geometry.add_ellipse_arc(p2, c, p3, p3) arc_7 = geometry.add_ellipse_arc(p3, c, p4, p4) arc_8 = geometry.add_ellipse_arc(p4, c, p1, p1) loop = geometry.add_line_loop([arc_5, arc_6, arc_7, arc_8]) mesh = geometry.add_plane_surface(loop, holes=[obstacle_loop]) geometry.add_physical_surface(mesh, label=12) geometry.add_physical_line(loop.lines, label=outer_marker) geometry.add_physical_line(obstacle_loop.lines, label=inner_marker) # Create refined mesh around geometry field = geometry.add_boundary_layer(edges_list=obstacle_loop.lines, hfar=res, hwall_n=res / 2, thickness=2 * res) geometry.add_background_field([field]) # Generate mesh (points, cells, point_data, cell_data, field_data) = generate_mesh(geometry, prune_z_0=True, geo_filename="meshes/test.geo") # Save mesh and mesh-function to file meshio.write( "meshes/multimesh_1.xdmf", meshio.Mesh(points=points, cells={"triangle": cells["triangle"]})) meshio.write( "meshes/mf_1.xdmf", meshio.Mesh(points=points, cells={"line": cells["line"]}, cell_data={ "line": { "name_to_read": cell_data["line"]["gmsh:physical"] } }))
def main(): size = 0.02 geom = pg.opencascade.Geometry(characteristic_length_min=size, characteristic_length_max=size) main_rect = geom.add_rectangle([0.0, 0.0, 0.0], width, height) mouth_inlet1 = geom.add_rectangle([-inlet_depth, ymin1, 0.0], inlet_depth, inlet_width) mouth_inlet2 = geom.add_rectangle([-inlet_depth, ymin2, 0.0], inlet_depth, inlet_width) mouth_outlet1 = geom.add_rectangle([width, ymin1, 0.0], inlet_depth, inlet_width) mouth_outlet2 = geom.add_rectangle([width, ymin2, 0.0], inlet_depth, inlet_width) print("ymin1 :{}".format(ymin1)) print("ymin2 :{}".format(ymin2)) geom.add_physical(mouth_inlet1, INMOUTH1) geom.add_physical(mouth_inlet2, INMOUTH2) geom.add_physical(mouth_outlet1, OUTMOUTH1) geom.add_physical(mouth_outlet2, OUTMOUTH2) geom.add_physical([main_rect], DOMAIN) _ = geom.boolean_fragments( [main_rect], [mouth_inlet1, mouth_inlet2, mouth_outlet1, mouth_outlet2]) geom.add_raw_code("""vb1[] = Boundary{{Surface{{ {0} }};}}; vb2[] = Boundary{{Surface{{ {1} }};}}; vb3[] = Boundary{{Surface{{ {2} }};}}; vb4[] = Boundary{{Surface{{ {3} }};}}; vb0[] = Boundary{{Surface{{ {4} }};}};""".format( mouth_inlet1.id, mouth_inlet2.id, mouth_outlet1.id, mouth_outlet2.id, main_rect.id, )) geom.add_raw_code("""Physical Curve({0}) = {{vb0[], vb1[0], vb1[2], vb2[0], vb2[2], vb3[0], vb3[2], vb4[0], vb4[2]}};""".format(WALLS)) geom.add_raw_code( "Physical Curve({0}) -= {{-vb1[1], -vb2[1], -vb3[3], -vb4[3]}};\n \ Physical Curve({1}) = {{vb1[3]}};\n \ Physical Curve({2}) = {{vb3[1]}};\n \ Physical Curve({3}) = {{vb2[3]}};\n \ Physical Curve({4}) = {{vb4[1]}};".format( WALLS, INLET1, OUTLET1, INLET2, OUTLET2)) mesh = pg.generate_mesh(geom, geo_filename="2D_mesh.geo") import meshio meshio.write("2D_mesh_heat_exchanger.vtk", mesh)
def single_mesh(res=0.025): """ Creates a single mesh containing a circular obstacle """ geometry = Geometry() c = geometry.add_point((c_x, c_y, 0)) # Elliptic obstacle p1 = geometry.add_point((c_x - r_x, c_y, 0)) p2 = geometry.add_point((c_x, c_y + r_x, 0)) p3 = geometry.add_point((c_x + r_x, c_y, 0)) p4 = geometry.add_point((c_x, c_y - r_x, 0)) arc_1 = geometry.add_ellipse_arc(p1, c, p2, p2) arc_2 = geometry.add_ellipse_arc(p2, c, p3, p3) arc_3 = geometry.add_ellipse_arc(p3, c, p4, p4) arc_4 = geometry.add_ellipse_arc(p4, c, p1, p1) obstacle_loop = geometry.add_line_loop([arc_1, arc_2, arc_3, arc_4]) rectangle = geometry.add_rectangle(0, L, 0, H, 0, res, holes=[obstacle_loop]) flow_list = [rectangle.line_loop.lines[3]] obstacle_list = obstacle_loop.lines walls_list = [rectangle.line_loop.lines[0], rectangle.line_loop.lines[2]] geometry.add_physical_surface(rectangle.surface, label=12) geometry.add_physical_line(flow_list, label=inflow) geometry.add_physical_line(walls_list, label=walls) geometry.add_physical_line([rectangle.line_loop.lines[1]], label=outflow) geometry.add_physical_line(obstacle_list, label=obstacle) field = geometry.add_boundary_layer(edges_list=obstacle_loop.lines, hfar=res, hwall_n=res / 8, thickness=res / 2) geometry.add_background_field([field]) (points, cells, point_data, cell_data, field_data) = generate_mesh(geometry, prune_z_0=True, geo_filename="test.geo") meshio.write( "mesh.xdmf", meshio.Mesh(points=points, cells={"triangle": cells["triangle"]})) meshio.write( "mf.xdmf", meshio.Mesh(points=points, cells={"line": cells["line"]}, cell_data={ "line": { "name_to_read": cell_data["line"]["gmsh:physical"] } }))
def test(): geom = pygmsh.built_in.Geometry() geom.add_rectangle(0.0, 1.0, 0.0, 1.0, 0.0, 0.1) ref = 1.0 mesh = pygmsh.generate_mesh(geom, mesh_file_type="vtk") assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def single_mesh(res=0.025): """ Create rectangular background mesh for the Poisson problem """ geometry = Geometry() c = geometry.add_point((c_x, c_y, 0)) mesh_r = 5 * res # Width of mesh # Elliptic obstacle p1 = geometry.add_point((c_x - r_x, c_y, 0)) p2 = geometry.add_point((c_x, c_y + r_y, 0)) p3 = geometry.add_point((c_x + r_x, c_y, 0)) p4 = geometry.add_point((c_x, c_y - r_y, 0)) arc_1 = geometry.add_ellipse_arc(p1, c, p2, p2) arc_2 = geometry.add_ellipse_arc(p2, c, p3, p3) arc_3 = geometry.add_ellipse_arc(p3, c, p4, p4) arc_4 = geometry.add_ellipse_arc(p4, c, p1, p1) obstacle_loop = geometry.add_line_loop([arc_1, arc_2, arc_3, arc_4]) # Surrounding mesh rectangle = geometry.add_rectangle(0, L, 0, H, 0, res, holes=[obstacle_loop]) geometry.add_physical_surface(rectangle.surface, label=12) geometry.add_physical_line(obstacle_loop.lines, label=inner_marker) geometry.add_physical_line(rectangle.line_loop.lines, label=outer_marker) # Create refined mesh around geometry field = geometry.add_boundary_layer(edges_list=obstacle_loop.lines, hfar=res, hwall_n=res / 2, thickness=2 * res) geometry.add_background_field([field]) # Generate mesh (points, cells, point_data, cell_data, field_data) = generate_mesh(geometry, prune_z_0=True, geo_filename="meshes/test_single.geo") # Save mesh and mesh-function to file meshio.write( "meshes/singlemesh.xdmf", meshio.Mesh(points=points, cells={"triangle": cells["triangle"]})) meshio.write( "meshes/mf.xdmf", meshio.Mesh(points=points, cells={"line": cells["line"]}, cell_data={ "line": { "name_to_read": cell_data["line"]["gmsh:physical"] } }))
def test(): geom = pygmsh.opencascade.Geometry() geom.add_wedge([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], top_extent=0.4, char_length=0.1) ref = 0.7 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def front_mesh_symmetric(res=0.025): """ Creates a donut mesh with symmetry line through y = c_y """ geometry = Geometry() mesh_r = width_scale*res c = geometry.add_point((c_x,c_y,0)) # Elliptic obstacle p1 = geometry.add_point((c_x-r_x, c_y,0)) p2 = geometry.add_point((c_x+r_x, c_y,0)) # embed() arc_1 = geometry.add_circle_arc(p1, c, p2) arc_2 = geometry.add_circle_arc(p2, c, p1) # Surrounding mesh p3 = geometry.add_point((c_x-r_x-mesh_r, c_y,0)) p4 = geometry.add_point((c_x+r_x+mesh_r, c_y,0)) arc_5 = geometry.add_circle_arc(p3, c, p4) arc_6 = geometry.add_circle_arc(p4, c, p3) line_front = geometry.add_line(p3, p1) line_back = geometry.add_line(p2, p4) surface_top = geometry.add_line_loop([line_front, arc_1, line_back, -arc_5]) surface_bottom = geometry.add_line_loop([line_front, -arc_2, line_back, arc_6]) obstacle_loop = geometry.add_line_loop([arc_1, arc_2]) outer_loop = geometry.add_line_loop([arc_5,arc_6]) top = geometry.add_plane_surface(surface_top) bottom = geometry.add_plane_surface(surface_bottom) geometry.add_physical_surface([top, bottom],label=12) geometry.add_physical_line(obstacle_loop.lines, label=inner_marker) geometry.add_physical_line(outer_loop.lines, label=outer_marker) # Create refined mesh around geometry field = geometry.add_boundary_layer(edges_list=obstacle_loop.lines, hfar=res, hwall_n=res/3, thickness=0.1*mesh_r) geometry.add_background_field([field]) # Generate mesh (points, cells, point_data, cell_data, field_data) = generate_mesh(geometry, prune_z_0=True, geo_filename="meshes/test.geo") # Save mesh and mesh-function to file meshio.write("multimesh_1.xdmf", meshio.Mesh( points=points, cells={"triangle": cells["triangle"]})) meshio.write("mf_1.xdmf", meshio.Mesh( points=points, cells={"line": cells["line"]}, cell_data={"line": {"name_to_read": cell_data["line"]["gmsh:physical"]}})) import os os.system("mv multimesh_1.* meshes/") os.system("mv mf_1.* meshes/")
def test(): geom = pygmsh.opencascade.Geometry() geom.add_box([0.0, 0.0, 0.0], [1, 2, 3], char_length=0.1) ref = 6 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def test_square_circle_hole(): """Test planar surface with holes. Construct it with boolean operations and verify that it is the same. """ for geo_object in built_in_opencascade_geos(): points, cells, _, _, _ = pygmsh.generate_mesh(geo_object) surf = 1 - 0.1 ** 2 * np.pi assert np.abs((compute_volume(points, cells) - surf) / surf) < 1e-3
def test(): geom = pygmsh.built_in.Geometry() geom.add_rectangle(0.0, 1.0, 0.0, 1.0, 0.0, 0.1) ref = 1.0 points, cells, _, _, _ = pygmsh.generate_mesh(geom, fast_conversion=True) assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return points, cells
def test(): geom = pygmsh.opencascade.Geometry() geom.add_torus([0.0, 0.0, 0.0], 1.0, 0.3, 1.25 * pi, char_length=0.1) ref = 1.09994740709 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def test(): geom = pygmsh.opencascade.Geometry() geom.add_cylinder([0.0, 0.0, 0.0], [0.0, 0.0, 1.0], 0.5, 0.25 * pi, char_length=0.1) ref = 0.097625512963 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def mesh_TUB(h, recombine=False): geom = pygmsh.built_in.Geometry() polygon = geom.add_polygon([[1 / 3, 1 / 3, 0], [1, 0, 0], [0.5, 0.5, 0]], lcar=h) if recombine: geom.add_raw_code("Recombine Surface {%s};" % polygon.surface.id) mesh = pygmsh.generate_mesh(geom, dim=2, verbose=False, prune_z_0=True) pymapping.cleanup_mesh_meshio(mesh) return mesh
def mesh(mesh_path, mesh_function_path, lc, **NS_namespace): # Inspired from # https://gist.github.com/michalhabera/bbe8a17f788192e53fd758a67cbf3bed geom = pygmsh.built_in.geometry.Geometry() r1 = 1.7*2 r2 = 3.8*2 # Create geometry p0 = geom.add_point([ 0, 0, 0], lcar=lc) p1 = geom.add_point([ r1, 0, 0], lcar=lc) p2 = geom.add_point([ 0, -2*r2, 0], lcar=lc) p3 = geom.add_point([-r1, 0, 0], lcar=lc) p4 = geom.add_point([ 1.615, 0, 0], lcar=lc) p5 = geom.add_point([-0.085, 0, 0], lcar=lc) p6 = geom.add_point([-0.272, 0, 0], lcar=lc) p7 = geom.add_point([-1.632, 0, 0], lcar=lc) l0 = geom.add_ellipse_arc(p1, p0, p2, p2) l1 = geom.add_ellipse_arc(p2, p0, p3, p3) #l2 = geom.add_line(p3, p1) l3 = geom.add_line(p3, p7) l4 = geom.add_line(p7, p6) l5 = geom.add_line(p6, p5) l6 = geom.add_line(p5, p4) l7 = geom.add_line(p4, p1) #ll = geom.add_line_loop(lines=[l0, l1, l2]) ll = geom.add_line_loop(lines=[l7, l0, l1, l3, l4, l5, l6]) ps = geom.add_plane_surface(ll) # Tag line and surface geom.add_physical_line(lines=l4, label=1) geom.add_physical_line(lines=l6, label=2) geom.add_physical_line(lines=[l7, l0, l1, l3, l5], label=3) geom.add_physical_surface(surfaces=ps, label=4) # Mesh surface points, cells, point_data, cell_data, field_data = pygmsh.generate_mesh(geom) # Write, then read mesh and MeshFunction meshio.write(mesh_path, meshio.Mesh( points=points, cells={"triangle": cells["triangle"]})) meshio.write(mesh_function_path, meshio.Mesh( points=points, cells={"line": cells["line"]}, cell_data={"line": {"boundary": cell_data["line"]["gmsh:physical"]}} )) mesh = Mesh() with XDMFFile(MPI.comm_world, mesh_path) as infile: infile.read(mesh) return mesh
def test(): geom = pygmsh.opencascade.Geometry() geom.add_ellipsoid([1.0, 1.0, 1.0], [1.0, 2.0, 3.0], char_length=0.1) ref = 8.0 * pi mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def test(): geom = pygmsh.opencascade.Geometry() geom.add_box([0.0, 0.0, 0.0], [1, 2, 3], char_length=0.1) ref = 6 points, cells, _, _, _ = pygmsh.generate_mesh(geom) assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return points, cells
def test(): kernels = [pygmsh.built_in, pygmsh.opencascade] for kernel in kernels: geom = kernel.Geometry() p = geom.add_point([0, 0, 0], 1) p_top, _, _ = geom.extrude(p, translation_axis=[1, 0, 0]) # The mesh should now contain exactly two points, # the second one should be where the translation pointed. mesh = pygmsh.generate_mesh(geom) assert len(mesh.points) == 2 assert np.array_equal(mesh.points[-1], [1, 0, 0]) # Check that the top entity (a PointBase) can be extruded correctly # again. _, _, _ = geom.extrude(p_top, translation_axis=[1, 0, 0]) mesh = pygmsh.generate_mesh(geom) assert len(mesh.points) == 3 assert np.array_equal(mesh.points[-1], [2, 0, 0]) # Set up new geometry with one line. geom = kernel.Geometry() p1 = geom.add_point([0, 0, 0], 1) p2 = geom.add_point([1, 0, 0], 1) line = geom.add_line(p1, p2) l_top, _, _ = geom.extrude(line, [0, 1, 0]) mesh = pygmsh.generate_mesh(geom) assert len(mesh.points) == 5 assert np.array_equal(mesh.points[-2], [1, 1, 0]) # Check again for top entity (a LineBase). _, _, _ = geom.extrude(l_top, [0, 1, 0]) mesh = pygmsh.generate_mesh(geom) assert len(mesh.points) == 8 assert np.array_equal(mesh.points[-3], [1, 2, 0]) # Check that extrusion works on a Polygon poly = geom.add_polygon( [[5.0, 0.0, 0.0], [6.0, 0.0, 0.0], [5.0, 1.0, 0.0]], lcar=1e20) _, _, poly_lat = geom.extrude(poly, [0.0, 0.0, 1.0], num_layers=1) mesh = pygmsh.generate_mesh(geom) assert len(mesh.points) == 8 + 6 assert len(poly_lat) == 3
def mesh_borehole(*, hole_diameter=1): """ Mesh the borehole geometry. See https://en.wikipedia.org/wiki/Snell%27s_law Parameters ---------- hole_diameter : float Diameter of the borehole. Returns ------- theta : float refraction angle Examples -------- A ray enters an air--water boundary at pi/4 radians (45 degrees). Compute exit angle. >>> mesh_borehole(hole_diameter = 1) 0.5605584137424605 """ import pygmsh import numpy as np hole_radius = 2 * hole_diameter box_size = 20 * hole_diameter mesh_size_hole = hole_diameter / 100 mesh_size_box = box_size / 5 geom = pygmsh.built_in.Geometry() circle = geom.add_circle(x0=[0.5 * box_size, 0.5 * box_size, 0.0], radius=hole_radius, lcar=mesh_size_hole, num_sections=4, make_surface=False) geom.add_rectangle(0.0, box_size, 0.0, box_size, 0.0, lcar=mesh_size_box, holes=[circle.line_loop]) mesh = pygmsh.generate_mesh(geom, geo_filename="h.geo") ele_cnn = np.array(mesh.cells_dict["triangle"]) nod_crd = np.array(mesh.points) print(ele_cnn.size) print(nod_crd.size) pass
def test_square_circle_hole(): """Test planar surface with holes. Construct it with boolean operations and verify that it is the same. """ for geo_object in built_in_opencascade_geos(): mesh = pygmsh.generate_mesh(geo_object) surf = 1 - 0.1 ** 2 * np.pi assert np.abs((compute_volume(mesh) - surf) / surf) < 1e-3 return
def pyGmsh(): PyGmsh = request.form.get("PyGmsh") geom = pygmsh.built_in.Geometry() exec(PyGmsh) points, cells, point_data, cell_data, field_data = pygmsh.generate_mesh( geom) #points, cells, _, _, _ = pygmsh.generate_mesh(geom) meshio.write('mesh.vtu', points, cells, cell_data=cell_data) return send_file("mesh.vtu")
def background_mesh(res=0.025): """ Create rectangular background mesh for the Poisson problem """ geo = Geometry() # Create points for square with two inlets and one outlet points = [] points.append(geo.add_point((0, 0, 0), res)) points.append(geo.add_point((1, 0, 0), res)) points.append(geo.add_point((1, 1, 0), res)) points.append(geo.add_point(outlet[1], res)) points.append(geo.add_point(outlet[0], res)) points.append(geo.add_point((0, 1, 0), res)) points.append(geo.add_point(inlet1[1], res)) points.append(geo.add_point(inlet1[0], res)) points.append(geo.add_point(inlet0[1], res)) points.append(geo.add_point(inlet0[0], res)) # Connect points as lines lines = [] for i in range(len(points) - 1): lines.append(geo.add_line(points[i], points[i + 1])) lines.append(geo.add_line(points[-1], points[0])) # Create geometry line_loop = geo.add_line_loop(lines) square = geo.add_plane_surface(line_loop) # Create cell and facet function wall_lines = lines[0:3] + lines[4:6] + [lines[7]] + [lines[9]] inlet0_lines = [lines[8]] inlet1_lines = [lines[6]] outlet_lines = [lines[3]] geo.add_physical_surface([square], label=12) geo.add_physical_line(inlet0_lines, label=inlet0_marker) geo.add_physical_line(inlet1_lines, label=inlet1_marker) geo.add_physical_line(outlet_lines, label=outlet_marker) geo.add_physical_line(wall_lines, label=wall_marker) # Create mesh (points, cells, point_data, cell_data, field_data) = generate_mesh(geo, prune_z_0=True) #, #geo_filename="meshes/tmp.geo") meshio.write( "meshes/multimesh_0.xdmf", meshio.Mesh(points=points, cells={"triangle": cells["triangle"]})) meshio.write( "meshes/mf_0.xdmf", meshio.Mesh(points=points, cells={"line": cells["line"]}, cell_data={ "line": { "name_to_read": cell_data["line"]["gmsh:physical"] } }))
def make_meshes(self): """ Makes a 2D mesh from a border which ElmerGrid can interpret INPUT: a border .xy file, distanc is characteristic distance between points OUTPUT: a .geo file of the border (gmsh geo object format) and gmsh mesh .msh file for use in ElmerGrid """ mesh_file_type = 'msh' input_root, input_ext = os.path.splitext(self.perimeter_file) self.output_filenames = [] #for each different resolution for i, distance in enumerate(self.resolutions): input_array = np.array(self.perimeters_newres[i]) length, q = input_array.shape input_array = np.hstack((input_array, np.zeros([length, 1]))) #load np array to pygmsh geometry class geom = pyg.Geometry() poly = geom.add_polygon(input_array, distance) #poly = geom.add_polygon(input_array,dist) #geom.add_physical_surface(poly,'poly') #make a mesh out of it output_filename = input_root + "_" + str(distance) mesh = pygmsh.generate_mesh(geom, verbose=False, dim=2, geo_filename=output_filename + ".geo", mesh_file_type=mesh_file_type) self.output_filenames.append(output_filename) # write the mesh to gmsh msh format using meshio meshio.write_points_cells(output_filename + "." + mesh_file_type, mesh.points, mesh.cells, point_data=mesh.point_data, cell_data=mesh.cell_data, field_data=mesh.field_data, file_format='gmsh2-ascii') # write the mesh to vtu for viewing in paraview meshio.write_points_cells(output_filename + ".vtu", mesh.points, mesh.cells, point_data=mesh.point_data, cell_data=mesh.cell_data, field_data=mesh.field_data) print(input_root + " written as " + output_filename + ".geo and " + output_filename + ".msh and " + output_filename + ".vtu") return
def test(): geom = pygmsh.opencascade.Geometry() geom.add_cone( [0.0, 0.0, 0.0], [0.0, 0.0, 1.0], 1.0, 0.3, 1.25 * pi, char_length=0.1 ) ref = 0.90779252263 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def test(lcar=1.0): geom = pygmsh.built_in.Geometry() poly = geom.add_polygon( [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0]], lcar) geom.set_transfinite_surface(poly.surface, size=[11, 9]) mesh = pygmsh.generate_mesh(geom, geo_filename="transfinite.geo") assert len(mesh.cells["triangle"]) == 10 * 8 * 2 return mesh
def test(): geom = pygmsh.opencascade.Geometry() geom.add_ball( [0.0, 0.0, 0.0], 1.0, x0=-0.9, x1=+0.9, alpha=0.5 * pi, char_length=0.1 ) ref = 0.976088698545 points, cells, _, _, _ = pygmsh.generate_mesh(geom) assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return points, cells
def gmsh(): import pygmsh geom = pygmsh.built_in.Geometry() geom.add_circle([0.0, 0.0, 0.0], 1.0, lcar=1.0e-1, num_sections=4, compound=True) mesh = pygmsh.generate_mesh(geom) meshio.write("circle-gmsh.vtk", mesh) return
def test(): geom = pygmsh.built_in.Geometry() rectangle = geom.add_rectangle(0.0, 1.0, 0.0, 1.0, 0.0, 0.1) geom.add_raw_code("Recombine Surface {%s};" % rectangle.surface.id) ref = 1.0 mesh = pygmsh.generate_mesh(geom, dim=2) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def translation2d(): """Translation of a surface object.""" geom = pygmsh.opencascade.Geometry(0.05, 0.05) disk = geom.add_disk([0, 0, 0], 1) disk2 = geom.add_disk([1.5, 0, 0], 1) geom.translate(disk, [1.5, 0, 0]) geom.boolean_union([disk2, disk]) points, cells, _, _, _ = pygmsh.generate_mesh(geom) surf = np.pi assert np.abs((compute_volume(points, cells) - surf) / surf) < 1e-3
def test(): geom = pygmsh.opencascade.Geometry() geom.add_cone( [0.0, 0.0, 0.0], [0.0, 0.0, 1.0], 1.0, 0.3, 1.25 * pi, char_length=0.1 ) ref = 0.90779252263 points, cells, _, _, _ = pygmsh.generate_mesh(geom) assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return points, cells
def siatka(w, l_list, d_list, epsilon, lcar=1, scale=0.1): """ Simple function that generate polygon as in the example. I am not exactly sure if this is what we were suppose to do so I didn't develop it much and it isn't particularity flexible. The arguments of the function keep the terminology from the picture we received w: value w l_list: list of all the values d d_list: -||- epsilon: the value of how thin should be the blue line lcar: I don't really know because but I think it is something with density of triangles """ ## scale the arguments # w *= scale # dl = list(map(lambda x: x*scale, d_list)) # d_list = dl # ll = list(map(lambda x: x*scale, l_list)) # l_list = ll geom = pygmsh.built_in.Geometry() # I draw separatly the top line and the bottom line than reverse the top # line and merge to with bottom line to create closed polygon x = 0.0 # first two points list_top = [[0.0, w, 0.0]] list_down = [[0.0, 0.0, 0.0]] for l, d in zip(l_list, d_list): x += l length = (w - d) / 2 list_down.append([x, 0.0, 0.0]) list_down.append([x, length, 0.0]) list_down.append([x + epsilon, length, 0.0]) list_down.append([x + epsilon, 0.0, 0.0]) list_top.append([x, w, 0.0]) list_top.append([x, w - length, 0.0]) list_top.append([x + epsilon, w - length, 0.0]) list_top.append([x + epsilon, w, 0.0]) # there will be one more element in l_list then in d_list # so need to add the last one x += l_list[-1] list_down.append([x, 0.0, 0.0]) list_top.append([x, w, 0.0]) list_top.reverse() # tu na koncu lcar geom.add_polygon(list_down + list_top, lcar) points, cells, _, _, _ = pygmsh.generate_mesh(geom) return points, cells
def test(): geom = pygmsh.opencascade.Geometry() geom.add_ball( [0.0, 0.0, 0.0], 1.0, x0=-0.9, x1=+0.9, alpha=0.5 * pi, char_length=0.1 ) ref = 0.976088698545 mesh = pygmsh.generate_mesh(geom) assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def test(lcar=1.): geom = pygmsh.built_in.Geometry() poly = geom.add_polygon( [[0., 0., 0.], [1., 0., 0.], [1., 1., 0.], [0., 1., 0.]], lcar) geom.set_transfinite_surface(poly.surface, size=[11, 9]) points, cells, _, _, _ = pygmsh.generate_mesh( geom, geo_filename='transfinite.geo') assert len(cells['triangle']) == 10 * 8 * 2 return points, cells
def test(lcar=1.0): geom = pygmsh.built_in.Geometry() poly = geom.add_polygon( [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0]], lcar ) geom.set_transfinite_surface(poly.surface, size=[11, 9]) mesh = pygmsh.generate_mesh(geom, geo_filename="transfinite.geo") assert len(mesh.cells["triangle"]) == 10 * 8 * 2 return mesh
def coreMesh(self, eleSize, outLineList, inLineList=None): """ Core concrete mesh Input: eleSize: fiber size outLineList: border line intersect points between outside cover and core [(x1,y1),(x2,y2),...,(xn,yn)] inLineList:border line intersect points between inner cover and core[[(x1,y1),(x2,y2),...,(xn,yn)], [(x1,y1),(x2,y2),...,(xn,yn)]] Output: triEleInfoList: core fiber infomation [(xc1,yc1,area1),(xc2,yc2,area2)] """ triEleInfoList = None outNOdeList = [[outLineList[i1][0], outLineList[i1][1], 0] for i1 in range(len(outLineList))] if inLineList == None: geom = pygmsh.opencascade.Geometry() geom.add_polygon(outNOdeList, lcar=eleSize) mesh = pygmsh.generate_mesh(geom) points = mesh.points triangles = [ each[1] for each in mesh.cells if each.type == 'triangle' ][0] triEleInfoList = self._triEleInfo(points, triangles) else: geom = pygmsh.opencascade.Geometry() outPolygon = geom.add_polygon(outNOdeList, lcar=eleSize) for eachInnerList in inLineList: inNodeList = [[eachInnerList[i2][0], eachInnerList[i2][1], 0] for i2 in range(len(eachInnerList))] inPolygon = geom.add_polygon(inNodeList, lcar=eleSize) differencePolygon = geom.boolean_difference([outPolygon], [inPolygon]) outPolygon = differencePolygon mesh = pygmsh.generate_mesh(geom) points = mesh.points triangles = [ each[1] for each in mesh.cells if each.type == 'triangle' ][0] triEleInfoList = self._triEleInfo(points, triangles) return triEleInfoList, points, triangles
def test(irad=0.05, orad=0.6): """Torus, rotated in space. """ geom = pygmsh.built_in.Geometry() R = pygmsh.rotation_matrix([1.0, 0.0, 0.0], np.pi / 2) geom.add_torus(irad=irad, orad=orad, lcar=0.03, x0=[0.0, 0.0, -1.0], R=R) ref = 2 * np.pi ** 2 * orad * irad ** 2 mesh = pygmsh.generate_mesh(geom) assert np.isclose(compute_volume(mesh), ref, rtol=5e-2) return mesh
def test_translation2d(): """Translation of a surface object.""" geom = pygmsh.opencascade.Geometry(0.05, 0.05) disk = geom.add_disk([0, 0, 0], 1) disk2 = geom.add_disk([1.5, 0, 0], 1) geom.translate(disk, [1.5, 0, 0]) geom.boolean_union([disk2, disk]) mesh = pygmsh.generate_mesh(geom) surf = np.pi assert np.abs(compute_volume(mesh) - surf) < 1e-3 * surf return
def geometry_gmsh_grid_from_dict(geom_dict: dict, h: np.float64, rho: np.float64, D=None, E=None, nu=None): path = geom_dict['geofile'] geo = pygmsh.built_in.Geometry() # TODO: this is awful mb can fix it with open(path, 'r') as ifile: geo._GMSH_CODE.append(ifile.read()) mesh = pygmsh.generate_mesh(geo, verbose=False, dim=2) return mb.generate_from_gmsh_mesh(mesh, h, rho, D, E, nu)
def get_circle_mesh(k): import pygmsh h = 0.5 ** k geom = pygmsh.built_in.Geometry() geom.add_circle([0.0, 0.0, 0.0], 1.0, lcar=h) points, cells, _, _, _ = pygmsh.generate_mesh(geom, verbose=False) cells = cells["triangle"] # toss away unused points uvertices, uidx = numpy.unique(cells, return_inverse=True) cells = uidx.reshape(cells.shape) points = points[uvertices] return meshplex.MeshTri(points, cells)
def test(): geom = pygmsh.built_in.Geometry() poly = geom.add_polygon( [[0.0, 0.5, 0.0], [1.0, 0.5, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0]], lcar=0.05 ) geom.symmetry(poly, [0.0, 1.0, 0.0, -0.5]) mesh = pygmsh.generate_mesh(geom) ref = 1.0 assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def generate(verbose=False): cache_file = "cruc_cache.msh" if os.path.isfile(cache_file): print("Using mesh from cache '{}'.".format(cache_file)) mesh = meshio.read(cache_file) out = mesh.points, mesh.cells, mesh.point_data, mesh.cell_data, mesh.field_data else: out = pygmsh.generate_mesh(_define(), verbose=verbose) points, cells, point_data, cell_data, _ = out meshio.write_points_cells( cache_file, points, cells, point_data=point_data, cell_data=cell_data ) return out
def test(): geom = pygmsh.built_in.Geometry() circle = geom.add_circle( x0=[0.5, 0.5, 0.0], radius=0.25, lcar=0.1, num_sections=4, make_surface=False ) geom.add_rectangle(0.0, 1.0, 0.0, 1.0, 0.0, lcar=0.1, holes=[circle.line_loop]) ref = 0.8086582838174551 mesh = pygmsh.generate_mesh(geom, geo_filename="h.geo") assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh
def test(): geom = pygmsh.built_in.Geometry() # internal radius of torus irad = 0.15 # external radius of torus orad = 0.27 Z_pos = (irad + orad) * np.concatenate( [+np.ones(8), -np.ones(8), +np.ones(8), -np.ones(8)] ) Alpha = np.concatenate( [ np.arange(8) * np.pi / 4.0, np.arange(8) * np.pi / 4.0 + np.pi / 16.0, np.arange(8) * np.pi / 4.0, np.arange(8) * np.pi / 4.0 + np.pi / 16.0, ] ) A1 = ( (irad + orad) / np.tan(np.pi / 8.0) * np.concatenate( [1.6 * np.ones(8), 1.6 * np.ones(8), 1.9 * np.ones(8), 1.9 * np.ones(8)] ) ) for alpha, a1, z in zip(Alpha, A1, Z_pos): # Rotate torus to the y-z-plane. R1 = pygmsh.rotation_matrix([0.0, 1.0, 0.0], 0.5 * np.pi) R2 = pygmsh.rotation_matrix([0.0, 0.0, 1.0], alpha) x0 = np.array([a1, 0.0, 0.0]) x1 = np.array([0.0, 0.0, z]) # First rotate to y-z-plane, then move out to a1, rotate by angle # alpha, move up by z. # # xnew = R2*(R1*x+x0) + x1 # geom.add_torus( irad=irad, orad=orad, lcar=0.1, R=np.dot(R2, R1), x0=np.dot(R2, x0) + x1 ) geom.add_box(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, lcar=0.3) ref = len(A1) * 2 * np.pi ** 2 * orad * irad ** 2 + 2.0 ** 3 mesh = pygmsh.generate_mesh(geom) assert np.isclose(compute_volume(mesh), ref, rtol=2e-2) return mesh