def test_quad_mesh_3d(mesh_name, order=3, visualize=False): if mesh_name == "ball": from meshmode.mesh.io import ScriptWithFilesSource script = ScriptWithFilesSource( """ Merge "ball-radius-1.step"; // Mesh.CharacteristicLengthMax = 0.1; Mesh.RecombineAll = 1; Mesh.Recombine3DAll = 1; Mesh.Recombine3DLevel = 2; Mesh.Algorithm = 8; Mesh.Algorithm3D = 8; Mesh 3; Save "output.msh"; """, ["ball-radius-1.step"]) with open("ball-quad.geo", "w") as f: f.write(script.source) elif mesh_name == "cube": from meshmode.mesh.io import ScriptSource script = ScriptSource( """ SetFactory("OpenCASCADE"); Box(1) = {0, 0, 0, 1, 1, 1}; Transfinite Line "*" = 8; Transfinite Surface "*"; Transfinite Volume "*"; Mesh.RecombineAll = 1; Mesh.Recombine3DAll = 1; Mesh.Recombine3DLevel = 2; """, "geo") else: raise ValueError(f"unknown mesh name: '{mesh_name}'") np.set_printoptions(linewidth=200) from meshmode.mesh.io import generate_gmsh logger.info("BEGIN GEN") mesh = generate_gmsh(script, 3, order=order, target_unit="MM") logger.info("END GEN") if visualize: from meshmode.mesh.visualization import write_vertex_vtk_file write_vertex_vtk_file(mesh, f"quad_mesh_3d_{mesh_name}.vtu", overwrite=True)
def test_quad_mesh_2d(): from meshmode.mesh.io import generate_gmsh, ScriptWithFilesSource print("BEGIN GEN") mesh = generate_gmsh( ScriptWithFilesSource( """ Merge "blob-2d.step"; Mesh.CharacteristicLengthMax = 0.05; Recombine Surface "*" = 0.0001; Mesh 2; Save "output.msh"; """, ["blob-2d.step"]), force_ambient_dim=2, ) print("END GEN") print(mesh.nelements)
def test_quad_mesh_2d(ambient_dim, filename, visualize=False): from meshmode.mesh.io import generate_gmsh, ScriptWithFilesSource logger.info("BEGIN GEN") mesh = generate_gmsh( ScriptWithFilesSource( f""" Merge "{filename}"; Mesh.CharacteristicLengthMax = 0.05; Recombine Surface "*" = 0.0001; Mesh 2; Save "output.msh"; """, [filename]), order=1, force_ambient_dim=ambient_dim, target_unit="MM", ) logger.info("END GEN") logger.info("nelements: %d", mesh.nelements) groups = [] for grp in mesh.groups: if not isinstance(grp, TensorProductElementGroup): # NOTE: gmsh isn't guaranteed to recombine all elements, so we # could still have some simplices sitting around, so skip them groups.append(grp.copy()) continue g = mgen.make_group_from_vertices(mesh.vertices, grp.vertex_indices, grp.order, group_cls=TensorProductElementGroup) assert g.nodes.shape == (mesh.ambient_dim, grp.nelements, grp.nunit_nodes) groups.append(g) mesh_from_vertices = Mesh(mesh.vertices, groups=groups, is_conforming=True) if visualize: from meshmode.mesh.visualization import write_vertex_vtk_file write_vertex_vtk_file(mesh, "quad_mesh_2d_orig.vtu") write_vertex_vtk_file(mesh_from_vertices, "quad_mesh_2d_groups.vtu")
def no_test_quad_mesh_3d(): from meshmode.mesh.io import generate_gmsh, ScriptWithFilesSource print("BEGIN GEN") mesh = generate_gmsh( ScriptWithFilesSource( """ Merge "ball-radius-1.step"; // Mesh.CharacteristicLengthMax = 0.1; Mesh.RecombineAll=1; Mesh.Recombine3DAll=1; Mesh.Algorithm = 8; Mesh.Algorithm3D = 9; // Mesh.Smoothing = 0; // Mesh.ElementOrder = 3; Mesh 3; Save "output.msh"; """, ["ball-radius-1.step"]), ) print("END GEN") print(mesh.nelements)
def get_mesh(self, resolution, target_order): from pytools import download_from_web_if_not_present download_from_web_if_not_present( "https://raw.githubusercontent.com/inducer/geometries/a869fc3/" "surface-3d/betterplane.brep") from meshmode.mesh.io import generate_gmsh, ScriptWithFilesSource mesh = generate_gmsh( ScriptWithFilesSource( """ Merge "betterplane.brep"; Mesh.CharacteristicLengthMax = %(lcmax)f; Mesh.ElementOrder = 2; Mesh.CharacteristicLengthExtendFromBoundary = 0; // 2D mesh optimization // Mesh.Lloyd = 1; l_superfine() = Unique(Abs(Boundary{ Surface{ 27, 25, 17, 13, 18 }; })); l_fine() = Unique(Abs(Boundary{ Surface{ 2, 6, 7}; })); l_coarse() = Unique(Abs(Boundary{ Surface{ 14, 16 }; })); // p() = Unique(Abs(Boundary{ Line{l_fine()}; })); // Characteristic Length{p()} = 0.05; Field[1] = Attractor; Field[1].NNodesByEdge = 100; Field[1].EdgesList = {l_superfine()}; Field[2] = Threshold; Field[2].IField = 1; Field[2].LcMin = 0.075; Field[2].LcMax = %(lcmax)f; Field[2].DistMin = 0.1; Field[2].DistMax = 0.4; Field[3] = Attractor; Field[3].NNodesByEdge = 100; Field[3].EdgesList = {l_fine()}; Field[4] = Threshold; Field[4].IField = 3; Field[4].LcMin = 0.1; Field[4].LcMax = %(lcmax)f; Field[4].DistMin = 0.15; Field[4].DistMax = 0.4; Field[5] = Attractor; Field[5].NNodesByEdge = 100; Field[5].EdgesList = {l_coarse()}; Field[6] = Threshold; Field[6].IField = 5; Field[6].LcMin = 0.15; Field[6].LcMax = %(lcmax)f; Field[6].DistMin = 0.2; Field[6].DistMax = 0.4; Field[7] = Min; Field[7].FieldsList = {2, 4, 6}; Background Field = 7; """ % { "lcmax": resolution, }, ["betterplane.brep"]), 2) # Flip elements--gmsh generates inside-out geometry. from meshmode.mesh.processing import perform_flips return perform_flips(mesh, np.ones(mesh.nelements))
def get_pseudo_y0_mesh(): """Generate or import a grid using `gmsh`. Input required: data/pseudoY0.brep (for mesh gen) -or- data/pseudoY0.msh (read existing mesh) This routine will generate a new grid if it does not find the grid file (data/pseudoY0.msh), but note that if the grid is generated in millimeters, then the solution initialization and BCs need to be adjusted or the grid needs to be scaled up to meters before being used with the current main driver in this example. """ from meshmode.mesh.io import ( read_gmsh, generate_gmsh, ScriptWithFilesSource ) import os if os.path.exists("data/pseudoY1nozzle.msh") is False: mesh = generate_gmsh( ScriptWithFilesSource(""" Merge "data/pseudoY1nozzle.brep"; Mesh.CharacteristicLengthMin = 1; Mesh.CharacteristicLengthMax = 10; Mesh.ElementOrder = 2; Mesh.CharacteristicLengthExtendFromBoundary = 0; // Inside and end surfaces of nozzle/scramjet Field[1] = Distance; Field[1].NNodesByEdge = 100; Field[1].FacesList = {5,7,8,9,10}; Field[2] = Threshold; Field[2].IField = 1; Field[2].LcMin = 1; Field[2].LcMax = 10; Field[2].DistMin = 0; Field[2].DistMax = 20; // Edges separating surfaces with boundary layer // refinement from those without // (Seems to give a smoother transition) Field[3] = Distance; Field[3].NNodesByEdge = 100; Field[3].EdgesList = {5,10,14,16}; Field[4] = Threshold; Field[4].IField = 3; Field[4].LcMin = 1; Field[4].LcMax = 10; Field[4].DistMin = 0; Field[4].DistMax = 20; // Min of the two sections above Field[5] = Min; Field[5].FieldsList = {2,4}; Background Field = 5; """, ["data/pseudoY1nozzle.brep"]), 3, target_unit="MM") else: mesh = read_gmsh("data/pseudoY1nozzle.msh") return mesh