def make_wingmesh(): import numpy from math import pi, cos, sin from meshpy.tet import MeshInfo, build from meshpy.geometry import GeometryBuilder, Marker, \ generate_extrusion, make_box geob = GeometryBuilder() profile_marker = Marker.FIRST_USER_MARKER wing_length = 2 wing_subdiv = 5 rz_points = [ (0, -wing_length * 1.05), (0.7, -wing_length * 1.05), ] + [(r, x) for x, r in zip( numpy.linspace(-wing_length, 0, wing_subdiv, endpoint=False), numpy.linspace(0.8, 1, wing_subdiv, endpoint=False))] + [(1, 0)] + [ (r, x) for x, r in zip( numpy.linspace(wing_length, 0, wing_subdiv, endpoint=False), numpy.linspace(0.8, 1, wing_subdiv, endpoint=False)) ][::-1] + [(0.7, wing_length * 1.05), (0, wing_length * 1.05)] from meshpy.naca import get_naca_points geob.add_geometry(*generate_extrusion( rz_points=rz_points, base_shape=get_naca_points("0012", number_of_points=20), ring_markers=(wing_subdiv * 2 + 4) * [profile_marker])) def deform_wing(p): x, y, z = p return numpy.array([ x + 0.8 * abs(z / wing_length)**1.2, y + 0.1 * abs(z / wing_length)**2, z ]) geob.apply_transform(deform_wing) points, facets, facet_markers = make_box( numpy.array([-1.5, -1, -wing_length - 1], dtype=numpy.float64), numpy.array([3, 1, wing_length + 1], dtype=numpy.float64)) geob.add_geometry(points, facets, facet_markers=facet_markers) mesh_info = MeshInfo() geob.set(mesh_info) mesh_info.set_holes([(0.5, 0, 0)]) mesh = build(mesh_info) 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.PLUS_Z: "inflow", Marker.MINUS_Z: "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 return make_conformal_mesh(mesh.points, mesh.elements, bdry_tagger)
x = np.sin(theta) y = np.cos(theta) base.extend([(x, y)]) (points, facets, facet_holestarts, markers) = generate_extrusion(rz_points=rz, base_shape=base) p_array = np.array(points) xs = p_array[:, 0] ys = p_array[:, 1] zs = p_array[:, 2] fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.scatter(xs, ys, zs) for f in facets: plt.plot(xs[list(f[0])], ys[list(f[0])], zs[list(f[0])]) plt.show() for i_facet, poly_list in enumerate(facets): print(poly_list) mesh_info = MeshInfo() mesh_info.set_points(points) mesh_info.set_facets_ex(facets, facet_holestarts, markers) mesh = build(mesh_info) print(mesh.elements) mesh.write_vtk('test.vtk')
def main(): import numpy # from math import pi, cos, sin from meshpy.tet import MeshInfo, build from meshpy.geometry import GeometryBuilder, Marker, generate_extrusion, make_box from meshpy.naca import get_naca_points geob = GeometryBuilder() box_marker = Marker.FIRST_USER_MARKER wing_length = 2 wing_subdiv = 5 rz_points = ([ (0, -wing_length * 1.05), (0.7, -wing_length * 1.05), ] + [(r, x) for x, r in zip( numpy.linspace(-wing_length, 0, wing_subdiv, endpoint=False), numpy.linspace(0.8, 1, wing_subdiv, endpoint=False), )] + [(1, 0)] + [(r, x) for x, r in zip( numpy.linspace(wing_length, 0, wing_subdiv, endpoint=False), numpy.linspace(0.8, 1, wing_subdiv, endpoint=False), )][::-1] + [(0.7, wing_length * 1.05), (0, wing_length * 1.05)]) geob.add_geometry(*generate_extrusion( rz_points=rz_points, base_shape=get_naca_points("0012", verbose=False, number_of_points=20), ring_markers=(wing_subdiv * 2 + 4) * [box_marker], )) from meshpy.tools import make_swizzle_matrix swizzle_matrix = make_swizzle_matrix("z:x,y:y,x:z") geob.apply_transform(lambda p: numpy.dot(swizzle_matrix, p)) def deform_wing(p): x, y, z = p return numpy.array([ x, y + 0.1 * abs(x / wing_length)**2, z + 0.8 * abs(x / wing_length)**1.2, ]) geob.apply_transform(deform_wing) points, facets, _, facet_markers = make_box( numpy.array([-wing_length - 1, -1, -1.5]), numpy.array([wing_length + 1, 1, 3])) geob.add_geometry(points, facets, facet_markers=facet_markers) mesh_info = MeshInfo() geob.set(mesh_info) mesh_info.set_holes([(0, 0, 0.5)]) mesh = build(mesh_info) print("%d elements" % len(mesh.elements)) mesh.write_vtk("airfoil3d.vtk")
def ProcessGlobalAction(ActionType, GlobalAction, NumberedPoints, Elements, Points): ExtendedData = {'ElementPropertyIndex' : {}} if ActionType == 'SpecialEntities': Filters = json.loads(GlobalAction['Filters']) if not 'SpecialEntities' in ExtendedData: ExtendedData['SpecialEntities'] = [] for Element in Elements: if Element and Element['filter'] in Filters: ExtendedData['SpecialEntities'].append(Element) return ExtendedData, False if ActionType == 'Nonlinear': Output = {} #for key in GlobalAction: # if 'ElementPropertyMaxIndex' in ExtendedData: # ExtendedData['ElementPropertyMaxIndex'] += 1 # else: # ExtendedData['ElementPropertyMaxIndex'] = 1 # propertyindex = ExtendedData['ElementPropertyMaxIndex'] # ExtendedData['ElementPropertyIndex'][key] = propertyindex # ExtendedData['NonlinearPropertyIndex'][key] = nonlinearindex # # # ExtendedData['ElementPropertyIndex'][key] = workingindex #In this same notation we can get the index when writing elements # Output[index] = "" return ExtendedData, Output #Here we have Output ready to be printed and ExtendedData, a mapper to Output if ActionType == 'ElementProperties': Output = {} for key in GlobalAction: if 'ElementPropertyMaxIndex' in ExtendedData: ExtendedData['ElementPropertyMaxIndex'] += 1 else: ExtendedData['ElementPropertyMaxIndex'] = 1 workingindex = ExtendedData['ElementPropertyMaxIndex'] ExtendedData['ElementPropertyIndex'][key] = workingindex #In this same notation we can get the index when writing elements Output[workingindex] = GlobalAction[key] return ExtendedData, Output #Here we have Output ready to be printed and ExtendedData, a mapper to Output if ActionType == 'Orphans': Output = [] for Number, Point in NumberedPoints['points'].iteritems(): ElementAmount = len(Point['elementnumbers']) if ElementAmount < 2: print "Orphan node {}!".format(Number) Output.append({'element_type': 'POINT', 'position': Point['point'], 'layer': 'Errors', 'nodenumber': Number}) return {'information':'addObjects'}, Output#Here we have Output ready to be printed and ExtendedData, a mapper to Output if ActionType == 'Meshing': EntityModelData = json.loads(GlobalAction['EntityModelData']) if 'EntityModelData' in GlobalAction else {} ExtendedModelData = json.loads(GlobalAction['ExtendedModelData']) if 'ExtendedModelData' in GlobalAction else {} Semantic = json.loads(GlobalAction['Semantic']) if 'Semantic' in GlobalAction else {} if 'exclude filters' in Semantic: if not 'ExcludeFilters' in ExtendedData: ExtendedData['ExcludeFilters'] = [] ExtendedData['ExcludeFilters'] = ExtendedData['ExcludeFilters'] + Semantic['exclude filters'] Boundaries = [] Output = [] Geometry = json.loads(GlobalAction['Geometry']) if 'Geometry' in GlobalAction else {} Parameters = json.loads(GlobalAction['Parameters']) if 'Parameters' in GlobalAction else {} AdditionalPointsFilters = Geometry['points'] if 'points' in Geometry else [] for Filter in Geometry['boundaries']: print "Using filter {} as finite element domain boundary.".format(Filter) for Element in Elements: if Element and Element['filter'] == Filter and Element['elementclass'] in ['FACE_3NODES', 'FACE_4NODES', 'POLYLINE', 'PLINE_5NODES']: Boundaries.append(Element) AdditionalPoints = [] for Filter in AdditionalPointsFilters: print "Using filter {} as additional points container.".format(Filter) for Element in Elements: if Element and Element['filter'] == Filter and Element['elementclass'] in ['FACE_3NODES', 'FACE_4NODES', 'POLYLINE', 'LINE_2NODES']: AdditionalPoints.extend( Element['points'] ) print "Assembling FE domain" mesh_info = MeshInfo() #additional_points = MeshInfo() #additional_points.set_points(list(set(AdditionalPoints))) MeshPoints = [] MeshFacets = [] MeshPointsIndex = {} PointIndex = 0 for BoundaryElement in Boundaries: ElementPoints = BoundaryElement['points'] MeshFacet = [] if Parameters['type'] == 'divide_4p_faces': for point in [ElementPoints[0],ElementPoints[1],ElementPoints[2]]: if not point in MeshPointsIndex: MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 MeshFacet.append(MeshPointsIndex[point]) MeshFacets.append(MeshFacet) MeshFacet = [] if ElementPoints[2] != ElementPoints[3]: for point in [ElementPoints[0],ElementPoints[2],ElementPoints[3]]: if not point in MeshPointsIndex: MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 MeshFacet.append(MeshPointsIndex[point]) MeshFacets.append(MeshFacet) else: for point in ElementPoints: if not point in MeshPointsIndex: MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 if not MeshPointsIndex[point] in MeshFacet: MeshFacet.append(MeshPointsIndex[point]) else: print "Mesh error or 3-point 3DFACE." MeshFacets.append(MeshFacet) MeshFacet = [] for point in list(set(AdditionalPoints)): if not point in MeshPointsIndex: #See whether the point is already indexed by its native number MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 saveobject(MeshFacets, r'MeshFacets') saveobject(MeshPoints, r'MeshPoints') mesh_info.set_facets(MeshFacets) mesh_info.set_points(MeshPoints) #insertaddpoints #points = np.array([list(x) for x in MeshPoints]) #qhull = scipy.spatial.Delaunay(points) #mesh_info.Options(switches='pq') #mesh_info.set_points([ # (0,0,0), (12,0,0), (12,12,0), (0,12,0), # (0,0,12), (12,0,12), (12,12,12), (0,12,12), # ]) #mesh_info.set_facets([ # [0,1,2,3], # [4,5,6,7], # [0,4,5,1], # [1,5,6,2], # [2,6,7,3], # [3,7,4,0], # ]) #opts = Options(switches='pq') #opts.maxvolume = 0.0001 #opts.parse_switches() mesh_info.regions.resize(1) mesh_info.regions[0] = [ MeshPoints[0][0], MeshPoints[0][1], MeshPoints[0][2], # point in volume -> first box 0, # region tag (user-defined number) Parameters['maxvolume'], # max tet volume in region ] mesh = build(mesh_info, options=Options(switches="pqT", epsilon=Parameters['tolerance']), volume_constraints=True) print "Created mesh with {} points, {} faces and {} elements.".format(len(mesh.points), len(mesh.faces), len(mesh.elements)) #mesh = build(mesh_info, options=Options(switches="pTi", epsilon=Parameters['tolerance'], insertaddpoints=True), volume_constraints=True, insert_points=additional_points) #mesh.write_vtk("test.vtk") #mesh.points #mesh.elements #mesh.faces filename = "test" #mesh.save_elements(filename) #mesh.save_nodes(filename) #mesh.save_elements(filename) #mesh.save_faces(filename) #mesh.save_edges(filename) #mesh.save_neighbors(filename) #mesh.save_poly(filename) #for element in qhull.simplices: # Position = [list(qhull.points[x]) for x in element] # Output.append({'element_type': '3DFACE', 'position': Position, 'layer': 'Elements'}) #NumberedPoints['points'][compoundObject['points'][0]]['point'] if not Boundaries: return False, False Precision = int(GlobalAction['Precision']) if 'Precision' in GlobalAction else 4 if not 'output' in Semantic or Semantic['output'].lower() == 'graphics': for face in mesh.faces: Position = [mesh.points[x] for x in face] Output.append({'element_type': '3DFACE', 'position': Position, 'layer': 'Faces'}) for element in mesh.elements: Position = [mesh.points[x] for x in element] Output.append({'element_type': '3DFACE', 'position': Position, 'layer': 'Elements'}) return {'information':'addObjects'}, Output elif Semantic['output'].lower() == 'fea': Points = {} for NumberedPoint in NumberedPoints['points']: Points[NumberedPoints['points'][NumberedPoint]['point']] = NumberedPoint NodeNumber = NumberedPoints['maximumNode'] for element in mesh.elements: Position = [mesh.points[x] for x in element] for i, point in enumerate(Position): Position[i] = [round(x, Precision) for x in point] #else: # if tuple([round(x, PrepPrecision) for x in Coords]) in [(4.95,-17.69,58.9), (4.96,-17.69,58.9)]: # pass # object['points'][i] = tuple([round(x, PrepPrecision) for x in Coords]) # if not object['points'][i] in GlobalPointIndex: # GlobalPointIndex.append(object['points'][i]) ElementPoints = [] ElementNumber = len(Elements) for point in Position: #Update NumberedPoints and construct all necessary data for Elements point = NeighborhoodRaw(tuple(point), Precision, Points) if not tuple(point) in Points: NodeNumber += 1 Points[tuple(point)] = NodeNumber #PointsNumbered.append(None) NumberedPoints['points'][NodeNumber] = {'point': tuple(point), 'elementnumbers': []} NumberedPoints['maximumNode'] = NodeNumber CurrentPointNumber = Points[tuple(point)] ElementPoints.append(CurrentPointNumber) NumberedPoints['points'][CurrentPointNumber]['elementnumbers'].append(ElementNumber) #Update Points if possible #Update Elements Element = { 'points' : ElementPoints, 'elementclass' : 'SOLID_4NODES', 'elementnum': ElementNumber, #??? 'filter': Semantic['filter'], 'entity_model_data': EntityModelData, 'extended_model_data': ExtendedModelData, 'generation_order': None, } Elements.append(None) Elements[ElementNumber] = Element return ExtendedData, False if ActionType == 'AddShells': ExtendedData = {} EntityModelData = json.loads(GlobalAction['EntityModelData']) if 'EntityModelData' in GlobalAction else {} ExtendedModelData = json.loads(GlobalAction['ExtendedModelData']) if 'ExtendedModelData' in GlobalAction else {} Filters = json.loads(GlobalAction['Filters']) if 'Filters' in GlobalAction else {} for Element in Elements: if not Element or not Element['filter'] in Filters: continue if Element['generation_order'] == 0 and Element['entity_model_data']['layer'] != "Concrete bases crown": ElementPoints = [Element['points'][0], Element['points'][1], Element['points'][2]] ElementNumber = len(Elements) NewElement = { 'points' : ElementPoints, 'elementclass' : 'FACE_3NODES', 'elementnum': ElementNumber, #??? 'filter': GlobalAction['AssignedFilter'], 'entity_model_data': EntityModelData, 'extended_model_data': ExtendedModelData, 'generation_order': None, } Elements.append(None) Elements[ElementNumber] = NewElement if Element['elementclass'] == 'SOLID_8NODES': ElementPoints = [Element['points'][0], Element['points'][2], Element['points'][3]] ElementNumber = len(Elements) NewElement = { 'points' : ElementPoints, 'elementclass' : 'FACE_3NODES', 'elementnum': ElementNumber, #??? 'filter': GlobalAction['AssignedFilter'], 'entity_model_data': EntityModelData, 'extended_model_data': ExtendedModelData, 'generation_order': None, } Elements.append(None) Elements[ElementNumber] = NewElement if Element['elementclass'] == 'SOLID_10NODES': pass pass return {}, {} return False
def generateConeMesh(plot=True): x0 = 0 y0 = 0 z0 = 1 h = 1 r_bottom = 1.3 r_top = 1.5 r_scale = r_top / r_bottom rz = [(0, z0), (1, z0), (r_scale, z0 + h), (0, z0 + h)] base = [] # Create circle for theta in np.linspace(0, 2 * np.pi, 40): x = r_bottom * np.sin(theta) y = r_bottom * np.cos(theta) base.extend([(x, y)]) (points, facets, facet_holestarts, markers) = generate_extrusion(rz_points=rz, base_shape=base) if plot: p_array = np.array(points) xs = p_array[:, 0] + x0 ys = p_array[:, 1] + y0 zs = p_array[:, 2] fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.scatter(xs, ys, zs) for f in facets: plt.plot(xs[list(f[0])], ys[list(f[0])], zs[list(f[0])]) if True: axLim = ax.get_w_lims() MAX = np.max(axLim) for direction in (-1, 1): for point in np.diag(direction * MAX * np.array([1, 1, 1])): ax.plot([point[0]], [point[1]], [np.abs(point[2])], 'w') x = [0, 0] y = [0, 0] z = [1, 1 + 0.2] plt.plot(x, y, z) plt.show() mesh_info = MeshInfo() mesh_info.set_points(points) mesh_info.set_facets_ex(facets) mesh = build(mesh_info) # print(mesh.elements) cellList = [] vertexList = [] mupifMesh = Mesh.UnstructuredMesh() for i, p in enumerate(mesh.points): p = (p[0] + x0, p[1] + y0, p[2]) vertexList.extend([Vertex.Vertex(i, i, p)]) for i, t in enumerate(mesh.elements): cellList.extend([Cell.Tetrahedron_3d_lin(mupifMesh, i, i, t)]) mupifMesh.setup(vertexList, cellList) return (mupifMesh)
def make_tetgen_mesh(): global mn_section_dict global face_marker_plane_dict # Make single volume vert_stack = [] face_stack = [] face_marker_stack = [] face_marker_brdr = 1 # are positive face_marker_surf = -1 # are negative # Make sure we don't double count any planes # Sides ids to face marker plane_sides_ids_done = {} # Go through all the sections for sec_id in mn_section_dict.keys(): sec = mn_section_dict[sec_id] # Check that there are any borders if len(sec.planes_sc_brdrs[0]) == 0 and len(sec.planes_sc_brdrs[1]) == 0 and sec.plane_surf == -1: print("Error! No bounding planes for this section!") # Add the surface plane... if not sec.plane_surf.sides_ids in plane_sides_ids_done: vert_stack += [sec.plane_surf.vert_list] face_stack += [sec.plane_surf.face_list] face_marker_stack += [len(sec.plane_surf.face_list)*[face_marker_surf]] face_marker_plane_dict[face_marker_surf] = sec.plane_surf sec.face_marker_dict[face_marker_surf] = -1 plane_sides_ids_done[sec.plane_surf.sides_ids] = face_marker_surf face_marker_surf -= 1 else: # Do this for EVERY section sec.face_marker_dict[plane_sides_ids_done[sec.plane_surf.sides_ids]] = -1 # And the borders... for i,brdr in enumerate(sec.planes_sc_brdrs): for j,plane in enumerate(brdr): if not plane.sides_ids in plane_sides_ids_done: vert_stack += [plane.vert_list] face_stack += [plane.face_list] # Face marker face_marker_stack += [len(plane.face_list)*[face_marker_brdr]] face_marker_plane_dict[face_marker_brdr] = plane sec.face_marker_dict[face_marker_brdr] = (i,j) ''' if mn_sec.sc_id == (1,3): global shared_3_27 PLANE_SHARED = True for v in shared_3_27: if not v in plane.vert_list: PLANE_SHARED = False break if PLANE_SHARED: print("THIS IS THE SHARED PLANE: marker: " + str(face_marker_brdr)) if triplet[0] in shared_3_27 and triplet[1] in shared_3_27 and triplet[2] in shared_3_27: print("Trip: " + str(triplet) + " is shared; has face marker: " + str(face_marker)) ''' plane_sides_ids_done[plane.sides_ids] = face_marker_brdr face_marker_brdr += 1 else: # Do this for EVERY section sec.face_marker_dict[plane_sides_ids_done[plane.sides_ids]] = (i,j) # Create a correctly indexed closed volume vert_list, face_list, face_marker_list = stack_lists(vert_stack,face_stack,face_marker_stack=face_marker_stack) # Make the tetgen mesh mesh_info = MeshInfo() # Points mesh_info.set_points(vert_list) # Faces mesh_info.set_facets(face_list, markers = face_marker_list) # --- TEMP --- ''' # Make an object from the surface we are planning to tetrahedronalize mesh_new = bpy.data.meshes.new("pre_tet_mesh") mesh_new.from_pydata(vert_list,[],face_list) mesh_new.validate(verbose=False) # Important! and i dont know why mesh_new.update() obj_new = bpy.data.objects.new("pre_tet",mesh_new) context.scene.objects.link(obj_new) # return ''' # --- FIN TEMP --- # Tetrahedralize # Options: # neighout = Write out neighbors # facesout = Write out faces # edgesout = Write out edges # regionattrib = Write out element_attributes = unique id for every tet in a distinct volume # nobisect = Dont alter surface print("> Starting TetGen") opts = Options(switches='pq', neighout = True, facesout = True, edgesout = True, regionattrib = True, verbose = True, docheck = True) mesh_built = build(mesh_info, options=opts) print("> Finished TetGen successfully") return mesh_built
def generate_TetMesh(): bpy.ops.object.mode_set(mode = 'OBJECT', toggle = False) bpy.context.scene.update() print("Scene Updated!") config = bpy.context.scene.CONFIG_MeshPy tetIndex = 0 vertList = [] faceList = [] meshPoints = [] meshFacets = [] split_faceList = [] split_vertList = [] ob = bpy.context.active_object obname = ob.name #convert all faces to triangles for testing ### that did not help with the crash problem:( ''' for vert in ob.data.vertices: vert.select = True bpy.ops.object.mode_set(mode = 'EDIT', toggle = False) bpy.ops.mesh.quads_convert_to_tris() bpy.ops.object.mode_set(mode = 'OBJECT', toggle = False) ''' #compute mesh compute_vertices(ob, meshPoints) compute_faces(ob, meshFacets) if config.make_subdivision == False: arg = "Y" else: arg = "" mesh_info = MeshInfo() mesh_info.set_points(meshPoints) mesh_info.set_facets(meshFacets) debugArg = "" args = (debugArg + "pq" + str(config.ratio_quality) + "a" + str(config.ratio_maxsize) + str(arg)) #args = ("o2" + str(arg)) tetmesh = build(mesh_info, Options(args), verbose = True, attributes = False, volume_constraints = False, max_volume = None, diagnose = False, insert_points = None) compute_mesh(tetmesh, vertList, faceList) ##all this should only be executed when preview is disabled if config.make_split == True: ##add counter to iterate to iterate the loop through all tetras #print(len(tetmesh.elements)) while tetIndex < len(tetmesh.elements): compute_mesh_split(tetmesh, split_faceList, split_vertList, vertList) #print("split_faceList ", tetIndex, ": ", split_faceList[tetIndex]) #print("split_vertList ", tetIndex, ": ", split_vertList[tetIndex]) #put this in a separate loop maybe bring some speed up #create mesh tetname = obname + "Tet" tet = create_mesh(tetname, split_vertList[tetIndex], split_faceList[tetIndex]) #run configs enable_game(config, tet) enable_physics(config, tet, tetname) #bpy.ops.group.create(name='test') world_correction(config, ob, tet) tetIndex = tetIndex + 1 else: #create mesh tetname = obname + "Tet" tetMesh = create_mesh(tetname, vertList, faceList) #run configs enable_game(config, tetMesh) enable_physics(config, tetMesh, tetname) world_correction(config, ob, tetMesh)
def make_boxmesh(): from meshpy.tet import MeshInfo, build from meshpy.geometry import GeometryBuilder, Marker, make_box geob = GeometryBuilder() box_marker = Marker.FIRST_USER_MARKER extent_small = 0.1 * numpy.ones(3, dtype=numpy.float64) geob.add_geometry(*make_box(-extent_small, extent_small)) # make small "separator box" for region attribute geob.add_geometry( *make_box(-extent_small * 4, numpy.array([4, 0.4, 0.4], dtype=numpy.float64))) geob.add_geometry(*make_box(numpy.array([-1, -1, -1], dtype=numpy.float64), numpy.array([5, 1, 1], dtype=numpy.float64))) mesh_info = MeshInfo() geob.set(mesh_info) mesh_info.set_holes([(0, 0, 0)]) # region attributes mesh_info.regions.resize(1) mesh_info.regions[0] = ( # point in region list(extent_small * 2) + [ # region number 1, # max volume in region #0.0001 0.005 ]) mesh = build(mesh_info, max_volume=0.02, volume_constraints=True, attributes=True) print "%d elements" % len(mesh.elements) #mesh.write_vtk("box-in-box.vtk") #print "done writing" fvi2fm = mesh.face_vertex_indices_to_face_marker face_marker_to_tag = { box_marker: "noslip", Marker.MINUS_X: "inflow", Marker.PLUS_X: "outflow", Marker.MINUS_Y: "inflow", Marker.PLUS_Y: "inflow", Marker.PLUS_Z: "inflow", Marker.MINUS_Z: "inflow" } def bdry_tagger(fvi, el, fn, all_v): face_marker = fvi2fm[fvi] return [face_marker_to_tag[face_marker]] from hedge.mesh import make_conformal_mesh return make_conformal_mesh(mesh.points, mesh.elements, bdry_tagger)
def make_extrusion_with_fine_core(rz, inner_r, max_volume_inner=1e-4, max_volume_outer=5e-2, radial_subdiv=20): min_z = min(rz_pt[1] for rz_pt in rz) max_z = max(rz_pt[1] for rz_pt in rz) from meshpy.tet import MeshInfo, build from meshpy.geometry import generate_surface_of_revolution MINUS_Z_MARKER = 1 PLUS_Z_MARKER = 2 inner_points, inner_facets, inner_holes, inner_markers = \ generate_surface_of_revolution( [ (0, min_z), (inner_r, min_z), (inner_r, max_z), (0, max_z), ], ring_markers=[ MINUS_Z_MARKER, 0, PLUS_Z_MARKER ], radial_subdiv=radial_subdiv, ) inner_point_indices = tuple(range(len(inner_points))) outer_points, outer_facets, outer_holes, outer_markers = \ generate_surface_of_revolution( [(inner_r,min_z)] + rz + [(inner_r, max_z)], ring_markers=[MINUS_Z_MARKER] + [0]*(len(rz)-1) + [PLUS_Z_MARKER], point_idx_offset=len(inner_points), radial_subdiv=radial_subdiv, ring_point_indices= [ inner_point_indices[:radial_subdiv] ] + [None]*len(rz) + [inner_point_indices[radial_subdiv:]] ) mesh_info = MeshInfo() mesh_info.set_points(inner_points + outer_points) mesh_info.set_facets_ex( inner_facets + outer_facets, inner_holes + outer_holes, inner_markers + outer_markers, ) # set regional max. volume mesh_info.regions.resize(2) mesh_info.regions[0] = [0, 0, (max_z + min_z) / 2, 0, max_volume_inner] mesh_info.regions[1] = [ inner_r + (rz[0][0] - inner_r) / 2, 0, (max_z + min_z) / 2, 0, max_volume_outer ] # add periodicity mesh_info.pbc_groups.resize(1) pbcg = mesh_info.pbc_groups[0] pbcg.facet_marker_1 = MINUS_Z_MARKER pbcg.facet_marker_2 = PLUS_Z_MARKER pbcg.set_transform(translation=[0, 0, max_z - min_z]) mesh = build(mesh_info, verbose=True, volume_constraints=True) #print "%d elements" % len(mesh.elements) #mesh.write_vtk("gun.vtk") fvi2fm = mesh.face_vertex_indices_to_face_marker def zper_boundary_tagger(fvi, el, fn, points): face_marker = fvi2fm[frozenset(fvi)] if face_marker == MINUS_Z_MARKER: return ["minus_z"] elif face_marker == PLUS_Z_MARKER: return ["plus_z"] else: return ["shell"] vertices = numpy.asarray(mesh.points, dtype=float, order="C") from hedge.mesh import make_conformal_mesh_ext from hedge.mesh.element import Tetrahedron return make_conformal_mesh_ext( vertices, [ Tetrahedron(i, el_idx, vertices) for i, el_idx in enumerate(mesh.elements) ], zper_boundary_tagger, periodicity=[None, None, ("minus_z", "plus_z")])