def test_nx_ny_21_with_material(self): """Test nx, ny with 2 levels of 1 division and a material.""" ref_groups = groups_21_with_material ref_centroids = centroids_21 mocmg.initialize() gmsh.initialize() rectangular_grid(bb_44, nx=[2, 2], ny=[2, 2], material="material_UO2") group_nums = gmsh.model.getPhysicalGroups() names = [gmsh.model.getPhysicalName(*grp) for grp in group_nums] ref_names = list(ref_groups.keys()) # Check correct names/entities for i, name in enumerate(ref_names): self.assertEqual(name, names[i]) index = names.index(name) group_ents = list( gmsh.model.getEntitiesForPhysicalGroup(*group_nums[index])) ref_group_ents = ref_groups[name] self.assertEqual(group_ents, ref_group_ents) # Check correct area/centroid for ent in gmsh.model.getEntities(2): tag = ent[1] mass = gmsh.model.occ.getMass(2, tag) self.assertAlmostEqual(1.0, mass, places=5, msg="1 width, 1 height, 1 area") x, y, z = gmsh.model.occ.getCenterOfMass(2, tag) centroid = (x, y, z) for i in range(3): self.assertAlmostEqual(centroid[i], ref_centroids[tag][i]) # Check materials gmsh.clear() gmsh.finalize()
def test_x_y_nonuniform_2(self): """Test x, y with nonuniform grid with 2 levels.""" ref_groups = groups_nu2 ref_centroids = centroids_nu2 ref_areas = areas_nu2 mocmg.initialize() gmsh.initialize() rectangular_grid(bb_12_4, x=[[0.0, 12.0], [2.0, 10.0]], y=[[2.0], [1.0, 3.0]]) group_nums = gmsh.model.getPhysicalGroups() names = [gmsh.model.getPhysicalName(*grp) for grp in group_nums] ref_names = list(ref_groups.keys()) # Check correct names/entities for i, name in enumerate(ref_names): self.assertEqual(name, names[i]) index = names.index(name) group_ents = list( gmsh.model.getEntitiesForPhysicalGroup(*group_nums[index])) ref_group_ents = ref_groups[name] self.assertEqual(group_ents, ref_group_ents) # Check correct area/centroid for ent in gmsh.model.getEntities(2): tag = ent[1] mass = gmsh.model.occ.getMass(2, tag) self.assertAlmostEqual(ref_areas[tag], mass, places=5) x, y, z = gmsh.model.occ.getCenterOfMass(2, tag) centroid = (x, y, z) for i in range(3): self.assertAlmostEqual(centroid[i], ref_centroids[tag][i]) gmsh.clear() gmsh.finalize()
def test_2_rectangles_with_bad_overwrite(self): """Test a 2 rectangle case, overwriting a material that doesnt exist.""" with self.assertRaises(SystemExit): with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() gmsh.model.occ.addRectangle(0.0, 0.0, 0.0, 2.0, 2.0) gmsh.model.occ.addRectangle(1.0, 1.0, 0.0, 2.0, 2.0) gmsh.model.occ.synchronize() gmsh.model.addPhysicalGroup(2, [1]) gmsh.model.addPhysicalGroup(2, [2]) gmsh.model.addPhysicalGroup(2, [1, 2]) gmsh.model.setPhysicalName(2, 1, "Material_1") gmsh.model.setPhysicalName(2, 2, "Material_2") gmsh.model.setPhysicalName(2, 3, "All") mocmg.model.group_preserving_fragment( [(2, 1)], [(2, 2)], overwrite_material="BAD_MAT" ) gmsh.clear() gmsh.finalize() out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] err = [line.split(None, 1)[1] for line in [err[0]]] # strip times self.assertEqual(out, ref_out) self.assertEqual(err, bad_overwrite)
def reinit(self): """ Clear whole geometry model. TODO: need tests Returns: """ gmsh.clear()
def test_nx_y_11(self): """Test nx, y with 1 division.""" ref_groups = groups_11 ref_centroids = centroids_11 mocmg.initialize() gmsh.initialize() rectangular_grid(bb_44, nx=[2], y=[[2.0]]) group_nums = gmsh.model.getPhysicalGroups() names = [gmsh.model.getPhysicalName(*grp) for grp in group_nums] ref_names = list(ref_groups.keys()) # Check correct names/entities for i, name in enumerate(ref_names): self.assertEqual(name, names[i]) index = names.index(name) group_ents = list( gmsh.model.getEntitiesForPhysicalGroup(*group_nums[index])) ref_group_ents = ref_groups[name] self.assertEqual(group_ents, ref_group_ents) # Check correct area/centroid for ent in gmsh.model.getEntities(2): tag = ent[1] mass = gmsh.model.occ.getMass(2, tag) self.assertAlmostEqual(4.0, mass, places=5, msg="2 width, 2 height, 4 area") x, y, z = gmsh.model.occ.getCenterOfMass(2, tag) centroid = (x, y, z) for i in range(3): self.assertAlmostEqual(centroid[i], ref_centroids[tag][i]) gmsh.clear() gmsh.finalize()
def _embed_points(model, x, bounding_shape, **kwargs): '''Hypercube mesh with vertices x''' npoints, tdim = x.shape # Figure out how to bound it counts = bounding_shape.create_volume(model, x) # In gmsh Point(4) will be returned as fourth node vertex_map = [] # mesh_1d.x[i] is embedding_mesh[vertex_map[i]] if tdim == 2: for xi in x: vertex_map.append(model.geo.addPoint(*np.r_[xi, 0])-1) else: for xi in x: vertex_map.append(model.geo.addPoint(*xi)-1) vertex_map = np.array(vertex_map) model.addPhysicalGroup(tdim, [counts[tdim]], 1) model.geo.synchronize() model.mesh.embed(0, 1+vertex_map, tdim, counts[tdim]) model.geo.synchronize() kwargs['save_geo'] and gmsh.write('%s.geo_unrolled' % kwargs['save_geo']) model.mesh.generate(tdim) kwargs['save_msh'] and gmsh.write('%s.msh' % kwargs['save_msh']) embedding_mesh, _ = conversion.mesh_from_gmshModel(model, include_mesh_functions=None) gmsh.clear() return embedding_mesh, vertex_map
def make_mesh(gmsh, densities): gmsh.clear() gmsh.model.add("SubProblem") geo.sub.create(gmsh, densities) gmsh.model.occ.synchronize() gmsh.model.mesh.generate(2) return npyfem.from_gmsh(gmsh)
def meshObj(obj, dim, meshParms=False, tessObj=None): # Create gmsh from shape or mesh # Clear any previous models gmsh.clear() setMeshParms(meshParms, obj, tessObj) if hasattr(obj, 'Shape'): return (meshObjShape(obj, dim)) elif hasattr(obj, 'Mesh'): return (meshObjMesh(obj, dim))
def __init__(self, name): gmsh.initialize() gmsh.clear() gmsh.model.add(name) self.name = name self.model = gmsh.model self.fac = self.model.occ self.pos = gmsh.view self.vertices = np.array([]) self.tetra = np.array([])
def test_2_pins_new_material(self): """Test overlaying grid on 2 pins with a new grid material.""" ref_groups = groups_2_pins_new_mat ref_centroids = centroids_2_pins with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() gmsh.model.occ.addDisk(1.0, 1.0, 0.0, 0.5, 0.5) gmsh.model.occ.addDisk(3.0, 1.0, 0.0, 0.5, 0.5) gmsh.model.occ.synchronize() p = gmsh.model.addPhysicalGroup(2, [1]) gmsh.model.setPhysicalName(2, p, "MATERIAL_UO2") p = gmsh.model.addPhysicalGroup(2, [2]) gmsh.model.setPhysicalName(2, p, "MATERIAL_MOX") overlay_rectangular_grid(bb_42, nx=[2], ny=[1], material="MATERIAL_NEW") out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] self.assertEqual(out, reference_out) self.assertEqual(err, []) group_nums = gmsh.model.getPhysicalGroups() names = [gmsh.model.getPhysicalName(*grp) for grp in group_nums] ref_names = list(ref_groups.keys()) # Check correct names/entities for i, name in enumerate(ref_names): self.assertEqual(name, names[i]) index = names.index(name) group_ents = list( gmsh.model.getEntitiesForPhysicalGroup(*group_nums[index])) ref_group_ents = ref_groups[name] self.assertEqual(group_ents, ref_group_ents) # Check correct area/centroid for ent in gmsh.model.getEntities(2): tag = ent[1] mass = gmsh.model.occ.getMass(2, tag) if tag == 1 or tag == 2: self.assertAlmostEqual(0.785398, mass, places=5, msg="pi*0.5**2") x, y, z = gmsh.model.occ.getCenterOfMass(2, tag) centroid = (x, y, z) for i in range(3): self.assertAlmostEqual(centroid[i], ref_centroids[tag][i]) gmsh.clear() gmsh.finalize()
def meshObject(obj, dim, algol, lm, lc, lp): # Create gmsh from shape or mesh # Clear any previous models print('mesh Object - first Clear') gmsh.clear() setMeshParms(algol, lm, lc, lp) if hasattr(obj, 'Shape'): return (meshObjShape(obj, dim)) elif hasattr(obj, 'Mesh'): return (meshObjMesh(obj, dim))
def load_gmsh_elems(gmshpath, entity): ''' Wrapper function for loading gmsh elements ''' gmsh.initialize() gmsh.open(gmshpath) nodes, elem_ids, node_maps = gmsh.model.mesh.getElements( entity[0], entity[1]) gmsh.clear() return nodes, elem_ids[0] - 1, node_maps[0] - 1
def test_get_entities_for_physical_group(self): """Test the get_entities_for_physical_group_name for a regular use case.""" mocmg.initialize() gmsh.initialize() tag = gmsh.model.occ.addDisk(0.0, 0.0, 0.0, 1.0, 1.0) gmsh.model.occ.synchronize() output_tag = gmsh.model.addPhysicalGroup(2, [tag]) gmsh.model.setPhysicalName(2, output_tag, "Test Physical Group Name") ents = mocmg.gmsh_utils.get_entities_for_physical_group_name( "Test Physical Group Name") self.assertEqual([1], ents) gmsh.clear() gmsh.finalize()
def test_3_rectangles_1_not_in_frag(self): """Test 2 rectangles in frag, one off to the side.""" ref_groups = groups_3_rectangles_1_not_in_frag ref_centroids = centroids_3_rectangles_1_not_in_frag ref_areas = areas_3_rectangles_1_not_in_frag # Setup with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() gmsh.model.occ.addRectangle(0.0, 0.0, 0.0, 2.0, 2.0) gmsh.model.occ.addRectangle(1.0, 1.0, 0.0, 2.0, 2.0) gmsh.model.occ.addRectangle(4.0, 4.0, 0.0, 2.0, 2.0) gmsh.model.occ.synchronize() gmsh.model.addPhysicalGroup(2, [1]) gmsh.model.addPhysicalGroup(2, [2]) gmsh.model.addPhysicalGroup(2, [3]) gmsh.model.addPhysicalGroup(2, [1, 2, 3]) gmsh.model.setPhysicalName(2, 1, "Group 1") gmsh.model.setPhysicalName(2, 2, "Group 2") gmsh.model.setPhysicalName(2, 3, "Group 3") gmsh.model.setPhysicalName(2, 4, "All") mocmg.model.group_preserving_fragment([(2, 1)], [(2, 2)]) out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] err = [line.split(None, 1)[1] for line in err] # strip times self.assertEqual(out, ref_out) self.assertEqual(err, []) # Get info group_nums = gmsh.model.getPhysicalGroups() names = [gmsh.model.getPhysicalName(*grp) for grp in group_nums] ref_names = list(ref_groups.keys()) # Check correct group names/entities for i, name in enumerate(names): self.assertEqual(name, ref_names[i]) index = names.index(name) group_ents = list(gmsh.model.getEntitiesForPhysicalGroup(*group_nums[index])) ref_group_ents = ref_groups[name] self.assertEqual(group_ents, ref_group_ents) # Check correct area/centroid for ent in gmsh.model.getEntities(2): tag = ent[1] mass = gmsh.model.occ.getMass(2, tag) self.assertAlmostEqual(ref_areas[tag], mass, places=5) x, y, z = gmsh.model.occ.getCenterOfMass(2, tag) centroid = (x, y, z) for i in range(3): self.assertAlmostEqual(centroid[i], ref_centroids[tag][i]) # Clean up gmsh.clear() gmsh.finalize()
def stp_to_stl(file): basename = os.path.basename(file) filename, ext = os.path.splitext(basename) if ext.lower().endswith('.stp'): import gmsh stl_file = file.replace(ext, '.stl') gmsh.initialize() gmsh.open(file) gmsh.write(stl_file) gmsh.clear() os.remove(file) return stl_file else: raise TypeError
def guess_entity(msh, dim, tag): ''' Use last digit method of figuring out what the entity ID is ''' tag = str(tag) gmsh.initialize() gmsh.open(msh) ent_list = gmsh.model.getEntities() subset = [k for k in ent_list if k[0] == dim] entity = [k for k in subset if str(k[1])[-1] == tag] gmsh.clear() return entity[0]
def load_gmsh_nodes(gmshpath, entity): ''' Given a fullpath to some .msh file load in the mesh nodes IDs, triangles and coordinates. gmshpath -- path to gmsh file dimtag -- tuple specifying the (dimensionality,tagID) being loaded If entity=(dim,tag) not provided then pull the first entity and return ''' gmsh.initialize() gmsh.open(gmshpath) nodes, coords, params = gmsh.model.mesh.getNodes(entity[0], entity[1]) coords = np.array(coords).reshape((len(coords) // 3, 3)) gmsh.clear() return nodes - 1, coords, params
def test_y_noniterable_type(self): """Test rect grid with non-iterable type elements.""" with self.assertRaises(SystemExit): with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() rectangular_grid(bb_11, x=[[1]], y=[1.0]) gmsh.clear() gmsh.finalize() out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] err = [line.split(None, 1)[1] for line in [err[0]]] # strip times self.assertEqual(out, reference_out) self.assertEqual(err, y_nonlist_type) # check log file f = open("mocmg.log", "r") lines = f.readlines() f.close() lines = [line.split(None, 1)[1].rstrip("\n") for line in lines] self.assertEqual(lines, reference_out + y_nonlist_type)
def test_bad_bounding_box(self): """Test a bad bounding box that produces negative dx, dy, dz.""" with self.assertRaises(SystemExit): with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() rectangular_grid([0, 0, 0, -1, -1, -1], x=[[0.5]], y=[[0.5]]) gmsh.clear() gmsh.finalize() out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] err = [line.split(None, 1)[1] for line in [err[0]]] # strip times self.assertEqual(out, reference_out) self.assertEqual(err, bad_bb) # check log file f = open("mocmg.log", "r") lines = f.readlines() f.close() lines = [line.split(None, 1)[1].rstrip("\n") for line in lines] self.assertEqual(lines, reference_out + bad_bb)
def test_get_entities_for_physical_group_bad_name(self): """Test the get_entities_for_physical_group_name for a regular use case.""" with self.assertRaises(SystemExit): with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() tag = gmsh.model.occ.addDisk(0.0, 0.0, 0.0, 1.0, 1.0) gmsh.model.occ.synchronize() output_tag = gmsh.model.addPhysicalGroup(2, [tag]) gmsh.model.setPhysicalName(2, output_tag, "Test Physical Group Name") mocmg.gmsh_utils.get_entities_for_physical_group_name( "Bad name") out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] err = [line.split(None, 1)[1] for line in [err[0]]] # strip times self.assertEqual(out, []) self.assertEqual(err, bad_name) gmsh.clear() gmsh.finalize()
def test_y_out_of_bb(self): """Test rect grid with a y-division outside the bb.""" with self.assertRaises(SystemExit): with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() rectangular_grid(bb_11, x=[[1.0]], y=[[-1.0]]) gmsh.clear() gmsh.finalize() out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] err = [line.split(None, 1)[1] for line in [err[0]]] # strip times self.assertEqual(out, reference_out) self.assertEqual(err, out_of_bb) # check log file f = open("mocmg.log", "r") lines = f.readlines() f.close() lines = [line.split(None, 1)[1].rstrip("\n") for line in lines] self.assertEqual(lines, reference_out + out_of_bb)
def __ExportingMeshToMdpa(self): gmsh.write(self.file_name+"_3d.vtk") meshing=meshio.read(self.file_name+"_3d.vtk") meshio.mdpa.write(self.file_name+"_3d.mdpa", meshing) gmsh.clear() gmsh.finalize() toedit_mdpa=open(self.file_name+"_3d.mdpa","r") edited_mdpa = open("test.mdpa", 'w') checkWords = ("Begin Elements Triangle3D3","Begin Elements Tetrahedra3D4","Begin ElementalData CellEntityIds","End ElementalData CellEntityIds") repWords = ("Begin Elements Element3D3N","Begin Elements Element3D4N","Begin ElementalData ACTIVATION_LEVEL","End ElementalData") for line in toedit_mdpa: for check, rep in zip(checkWords, repWords): line = line.replace(check, rep) edited_mdpa.write(line) toedit_mdpa.close() edited_mdpa.close() if os.path.exists(self.file_name+"_3d.mdpa"): os.remove(self.file_name+"_3d.mdpa") os.rename("test.mdpa",self.file_name+"_3d.mdpa")
def test_ny0(self): """Test ny with 0 division.""" with self.assertRaises(SystemExit): with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() rectangular_grid(bb_11, nx=[1, 1], ny=[0, 1]) gmsh.clear() gmsh.finalize() out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] err = [line.split(None, 1)[1] for line in [err[0]]] # strip times self.assertEqual(out, reference_out) self.assertEqual(err, ny_type) # check log file f = open("mocmg.log", "r") lines = f.readlines() f.close() lines = [line.split(None, 1)[1].rstrip("\n") for line in lines] self.assertEqual(lines, reference_out + ny_type)
def test_arg_len_mismatch_nxny(self): """Test rect grid with mismatched arg len.""" with self.assertRaises(SystemExit): with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() rectangular_grid(bb_11, x=[2, 3], y=[1]) gmsh.clear() gmsh.finalize() out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] err = [line.split(None, 1)[1] for line in [err[0]]] # strip times self.assertEqual(out, reference_out) self.assertEqual(err, len_mismatch) # check log file f = open("mocmg.log", "r") lines = f.readlines() f.close() lines = [line.split(None, 1)[1].rstrip("\n") for line in lines] self.assertEqual(lines, reference_out + len_mismatch)
def test_thick_dz(self): """Test rect grid with large change in z direction.""" with self.assertRaises(SystemExit): with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() rectangular_grid(bb_dz, x=[[0.5]], y=[[0.5]]) gmsh.clear() gmsh.finalize() out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] err = [line.split(None, 1)[1] for line in [err[0]]] # strip times self.assertEqual(out, reference_out) self.assertEqual(err, thick_dz) # check log file f = open("mocmg.log", "r") lines = f.readlines() f.close() lines = [line.split(None, 1)[1].rstrip("\n") for line in lines] self.assertEqual(lines, reference_out + thick_dz)
def test_nx_ny_21_with_bad_material(self): """Test nx, ny with 2 levels of 1 division and an invalid material name.""" with self.assertRaises(SystemExit): with captured_output() as (out, err): mocmg.initialize() gmsh.initialize() rectangular_grid(bb_44, nx=[2, 2], ny=[2, 2], material="bad_mat") gmsh.clear() gmsh.finalize() out, err = out.getvalue().splitlines(), err.getvalue().splitlines() out = [line.split(None, 1)[1] for line in out] err = [line.split(None, 1)[1] for line in [err[0]]] # strip times self.assertEqual(out, reference_out) self.assertEqual(err, bad_material) # check log file f = open("mocmg.log", "r") lines = f.readlines() f.close() lines = [line.split(None, 1)[1].rstrip("\n") for line in lines] self.assertEqual(lines, reference_out + bad_material)
import gmsh # initial commands gmsh.initialize() gmsh.clear() gmsh.option.setNumber('General.Terminal', 1) msTg = 'gmsh/port2' gmsh.model.add(msTg) gmg = gmsh.model.geo # geometry (m) Lx = 5.0 Ly = 4.0 H = 0.5 # define points ms = 0.10 # mesh size gmg.addPoint(0, 0, 0, ms, 1) gmg.addPoint(H, 0, 0, ms, 2) gmg.addPoint(H, Ly - H, 0, ms, 3) gmg.addPoint(Lx - H, Ly - H, 0, ms, 4) gmg.addPoint(Lx - H, 0, 0, ms, 5) gmg.addPoint(Lx, 0, 0, ms, 6) gmg.addPoint(Lx, Ly, 0, ms, 7) gmg.addPoint(Lx / 2 + 0.5, Ly, 0, ms, 8) gmg.addPoint(Lx / 2 - 0.5, Ly, 0, ms, 9) gmg.addPoint(0, Ly, 0, ms, 10) # define lines gmg.addLine(1, 2, 1) gmg.addLine(2, 3, 2)
def gmsh_2D_stacked(celltype: str, theta: float, verbose: bool = False): res = 0.1 x0, y0, z0 = 0, 0, 0 x1, y1 = 1, 1 y2 = 2 # Check if GMSH is initialized gmsh.initialize() gmsh.option.setNumber("General.Terminal", int(verbose)) gmsh.clear() if MPI.COMM_WORLD.rank == 0: if celltype == "quadrilateral": gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 2) gmsh.option.setNumber("Mesh.RecombineAll", 2) recombine = True else: recombine = False points = [ gmsh.model.occ.addPoint(x0, y0, z0), gmsh.model.occ.addPoint(x1, y0, z0), gmsh.model.occ.addPoint(x0, y2, z0), gmsh.model.occ.addPoint(x1, y2, z0) ] bottom = gmsh.model.occ.addLine(points[0], points[1]) top = gmsh.model.occ.addLine(points[2], points[3]) gmsh.model.occ.extrude([(1, bottom)], 0, y1 - y0, 0, numElements=[int(1 / (res))], recombine=recombine) gmsh.model.occ.extrude([(1, top)], 0, y1 - y2 - 1e-12, 0, numElements=[int(1 / (2 * res))], recombine=recombine) # Syncronize to be able to fetch entities gmsh.model.occ.synchronize() # Create entity -> marker map (to be used after rotation) volumes = gmsh.model.getEntities(2) volume_entities = {"Top": [-1, 1], "Bottom": [-1, 2]} for i, volume in enumerate(volumes): com = gmsh.model.occ.getCenterOfMass(volume[0], volume[1]) if np.isclose(com[1], (y1 - y0) / 2): bottom_index = i volume_entities["Bottom"][0] = volume[1] elif np.isclose(com[1], (y2 - y1) / 2 + y1): top_index = i volume_entities["Top"][0] = volume[1] surfaces = ["Top", "Bottom", "Left", "Right"] entities: Dict[str, Dict[str, List[List[int]]]] = { "Bottom": {key: [[], []] for key in surfaces}, "Top": {key: [[], []] for key in surfaces} } # Identitfy entities for each surface of top and bottom cube # Bottom cube: Top, Right, Bottom, Left # Top cube : Top, Right, Bottom, Left facet_markers = [[4, 7, 5, 6], [3, 12, 9, 13]] bottom_surfaces = gmsh.model.getBoundary([volumes[bottom_index]], oriented=False, recursive=False) for entity in bottom_surfaces: com = gmsh.model.occ.getCenterOfMass(entity[0], abs(entity[1])) if np.allclose(com, [(x1 - x0) / 2, y0, z0]): entities["Bottom"]["Bottom"][0].append(entity[1]) entities["Bottom"]["Bottom"][1] = [facet_markers[0][2]] elif np.allclose(com, [x1, (y1 - y0) / 2, z0]): entities["Bottom"]["Right"][0].append(entity[1]) entities["Bottom"]["Right"][1] = [facet_markers[0][1]] elif np.allclose(com, [x0, (y1 - y0) / 2, z0]): entities["Bottom"]["Left"][0].append(entity[1]) entities["Bottom"]["Left"][1] = [facet_markers[0][3]] elif np.allclose(com, [(x1 - x0) / 2, y1, z0]): entities["Bottom"]["Top"][0].append(entity[1]) entities["Bottom"]["Top"][1] = [facet_markers[0][0]] # Physical markers for top top_surfaces = gmsh.model.getBoundary([volumes[top_index]], oriented=False, recursive=False) for entity in top_surfaces: com = gmsh.model.occ.getCenterOfMass(entity[0], abs(entity[1])) if np.allclose(com, [(x1 - x0) / 2, y1, z0]): entities["Top"]["Bottom"][0].append(entity[1]) entities["Top"]["Bottom"][1] = [facet_markers[1][2]] elif np.allclose(com, [x1, y1 + (y2 - y1) / 2, z0]): entities["Top"]["Right"][0].append(entity[1]) entities["Top"]["Right"][1] = [facet_markers[1][1]] elif np.allclose(com, [x0, y1 + (y2 - y1) / 2, z0]): entities["Top"]["Left"][0].append(entity[1]) entities["Top"]["Left"][1] = [facet_markers[1][3]] elif np.allclose(com, [(x1 - x0) / 2, y2, z0]): entities["Top"]["Top"][0].append(entity[1]) entities["Top"]["Top"][1] = [facet_markers[1][0]] # Note: Rotation cannot be used on recombined surfaces gmsh.model.occ.synchronize() for volume in volume_entities.keys(): gmsh.model.addPhysicalGroup(2, [volume_entities[volume][0]], tag=volume_entities[volume][1]) gmsh.model.setPhysicalName(2, volume_entities[volume][1], volume) for box in entities.keys(): for surface in entities[box].keys(): gmsh.model.addPhysicalGroup(1, entities[box][surface][0], tag=entities[box][surface][1][0]) gmsh.model.setPhysicalName(1, entities[box][surface][1][0], box + ":" + surface) # Set mesh sizes on the points from the surface we are extruding bottom_nodes = gmsh.model.getBoundary([volumes[bottom_index]], oriented=False, recursive=True) gmsh.model.occ.mesh.setSize(bottom_nodes, res) top_nodes = gmsh.model.getBoundary([volumes[top_index]], oriented=False, recursive=True) gmsh.model.occ.mesh.setSize(top_nodes, 2 * res) # NOTE: Need to synchronize after setting mesh sizes gmsh.model.occ.synchronize() # Generate mesh gmsh.option.setNumber("Mesh.MaxNumThreads1D", MPI.COMM_WORLD.size) gmsh.option.setNumber("Mesh.MaxNumThreads2D", MPI.COMM_WORLD.size) gmsh.option.setNumber("Mesh.MaxNumThreads3D", MPI.COMM_WORLD.size) gmsh.model.mesh.generate(2) gmsh.model.mesh.setOrder(1) mesh, ft = _utils.gmsh_model_to_mesh(gmsh.model, facet_data=True, gdim=2) r_matrix = _utils.rotation_matrix([0, 0, 1], theta) # NOTE: Hex mesh must be rotated after generation due to gmsh API mesh.geometry.x[:] = np.dot(r_matrix, mesh.geometry.x.T).T gmsh.clear() gmsh.finalize() MPI.COMM_WORLD.barrier() return mesh, ft
def generate_hex_boxes(x0: float, y0: float, z0: float, x1: float, y1: float, z1: float, z2: float, res: float, facet_markers: Sequence[Sequence[int]], volume_markers: Sequence[int], verbose: bool = False): """ Generate the stacked boxes [x0,y0,z0]x[y1,y1,z1] and [x0,y0,z1] x [x1,y1,z2] with different resolution in each box. The markers are is a list of arrays containing markers array of markers for [back, bottom, right, left, top, front] per box volume_markers a list of marker per volume """ gmsh.initialize() gmsh.option.setNumber("General.Terminal", int(verbose)) if MPI.COMM_WORLD.rank == 0: gmsh.clear() gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 2) gmsh.option.setNumber("Mesh.RecombineAll", 2) bottom = gmsh.model.occ.addRectangle(x0, y0, z0, x1 - x0, y1 - y0) top = gmsh.model.occ.addRectangle(x0, y0, z2, x1 - x0, y1 - y0) # Set mesh size at point gmsh.model.occ.extrude([(2, bottom)], 0, 0, z1 - z0, numElements=[int(1 / (2 * res))], recombine=True) gmsh.model.occ.extrude([(2, top)], 0, 0, z1 - z2 - 1e-12, numElements=[int(1 / (2 * res))], recombine=True) # Syncronize to be able to fetch entities gmsh.model.occ.synchronize() # Tag faces and volume tag_cube_model(gmsh.model, x0, y0, z0, x1, y1, z1, z2, facet_markers, volume_markers) # Set mesh sizes on the points from the surface we are extruding bottom_nodes = gmsh.model.getBoundary([(2, bottom)], oriented=False, recursive=True) gmsh.model.occ.mesh.setSize(bottom_nodes, res) top_nodes = gmsh.model.getBoundary([(2, top)], oriented=False, recursive=True) gmsh.model.occ.mesh.setSize(top_nodes, 2 * res) # NOTE: Need to synchronize after setting mesh sizes gmsh.model.occ.synchronize() # Generate mesh gmsh.option.setNumber("Mesh.MaxNumThreads1D", MPI.COMM_WORLD.size) gmsh.option.setNumber("Mesh.MaxNumThreads2D", MPI.COMM_WORLD.size) gmsh.option.setNumber("Mesh.MaxNumThreads3D", MPI.COMM_WORLD.size) gmsh.model.mesh.generate(3) gmsh.model.mesh.setOrder(1) mesh, ft = _utils.gmsh_model_to_mesh(gmsh.model, facet_data=True) gmsh.clear() gmsh.finalize() MPI.COMM_WORLD.barrier() return mesh, ft
def generate_tet_boxes( x0: float, y0: float, z0: float, x1: float, y1: float, z1: float, z2: float, res: float, facet_markers: Sequence[Sequence[int]], volume_markers: Sequence[int], verbose: bool = False) -> Tuple[_mesh.Mesh, _cpp.mesh.MeshTags_int32]: """ Generate the stacked boxes [x0,y0,z0]x[y1,y1,z1] and [x0,y0,z1] x [x1,y1,z2] with different resolution in each box. The markers are is a list of arrays containing markers array of markers for [back, bottom, right, left, top, front] per box volume_markers a list of marker per volume """ gmsh.initialize() gmsh.option.setNumber("General.Terminal", int(verbose)) if MPI.COMM_WORLD.rank == 0: gmsh.clear() # NOTE: Have to reset this until: # https://gitlab.onelab.info/gmsh/gmsh/-/issues/1001 # is in master gmsh.option.setNumber("Mesh.RecombineAll", 0) # Added tolerance to ensure that gmsh separates boxes tol = 1e-12 gmsh.model.occ.addBox(x0, y0, z0, x1 - x0, y1 - y0, z1 - z0) gmsh.model.occ.addBox(x0, y0, z1 + tol, x1 - x0, y1 - y0, z2 - z1) # Syncronize to be able to fetch entities gmsh.model.occ.synchronize() tag_cube_model(gmsh.model, x0, y0, z0, x1, y1, z1, z2, facet_markers, volume_markers) gmsh.model.mesh.field.add("Box", 1) gmsh.model.mesh.field.setNumber(1, "VIn", res) gmsh.model.mesh.field.setNumber(1, "VOut", 2 * res) gmsh.model.mesh.field.setNumber(1, "XMin", 0) gmsh.model.mesh.field.setNumber(1, "XMax", 1) gmsh.model.mesh.field.setNumber(1, "YMin", 0) gmsh.model.mesh.field.setNumber(1, "YMax", 1) gmsh.model.mesh.field.setNumber(1, "ZMin", 0) gmsh.model.mesh.field.setNumber(1, "ZMax", 1) gmsh.model.mesh.field.setAsBackgroundMesh(1) # NOTE: Need to synchronize after setting mesh sizes gmsh.model.occ.synchronize() # Generate mesh gmsh.option.setNumber("Mesh.MaxNumThreads1D", MPI.COMM_WORLD.size) gmsh.option.setNumber("Mesh.MaxNumThreads2D", MPI.COMM_WORLD.size) gmsh.option.setNumber("Mesh.MaxNumThreads3D", MPI.COMM_WORLD.size) gmsh.model.mesh.generate(3) gmsh.model.mesh.setOrder(1) mesh, ft = _utils.gmsh_model_to_mesh(gmsh.model, facet_data=True) gmsh.finalize() return mesh, ft