Source code for pyleecan.Functions.GMSH.gen_3D_mesh

from os import replace
from numpy import pi
from ...Classes.Arc import Arc
import sys
import gmsh
from os.path import splitext


[docs]def gen_3D_mesh( lamination, save_path="Lamination.msh", sym=-1, mesh_size=5e-3, user_mesh_dict=None, is_rect=False, Nlayer=20, display=True, ): """Draw 3D mesh of the lamination Parameters ---------- lamination: LamSlot Lamintation with slot to draw save_path: str Path to save the msh result file sym : int Number of symmetry to apply mesh_size : float Size of the mesh [m] user_mesh_dict : dict To enforce the number of elements on the lines is_rect : bool To use rectangular elements Nlayer : int Number of mesh layer on Z axis display : bool To display gmsh logs Returns ------- None """ # The defaut symmetry is Zs => We draw only one tooth if sym == -1: tooth_surf = lamination.slot.get_surface_tooth() Zs = lamination.get_Zs() else: tooth_surf = lamination.build_geometry(sym=sym)[0] Zs = sym # For readibility model = gmsh.model factory = model.geo L = lamination.L1 # Lamination length # Start a new model gmsh.initialize() gmsh.option.setNumber("General.Terminal", int(display)) gmsh.option.setNumber("Geometry.CopyMeshingMethod", 1) model.add("Pyleecan") # Create all the points of the tooth NPoint = 0 # Number of point created for line in tooth_surf.get_lines(): Z = line.get_begin() NPoint += 1 factory.addPoint(Z.real, Z.imag, -L / 2, mesh_size, NPoint) # Draw all the lines of the tooth NLine = 0 # Number of line created for line in tooth_surf.get_lines(): NLine += 1 if NLine == len(tooth_surf.get_lines()): if isinstance(line, Arc): Zc = line.get_center() NPoint += 1 factory.addPoint(Zc.real, Zc.imag, -L / 2, mesh_size, NPoint) factory.addCircleArc(NLine, NPoint - 1, 1, NLine) else: factory.addLine(NLine, 1, NLine) else: if isinstance(line, Arc): Zc = line.get_center() NPoint += 1 factory.addPoint(Zc.real, Zc.imag, -L / 2, mesh_size, NPoint) factory.addCircleArc(NLine, NPoint, NLine + 1, NLine) else: factory.addLine(NLine, NLine + 1, NLine) # Create the Tooth surface gmsh.model.geo.addCurveLoop(list(range(1, NLine + 1)), 1) gmsh.model.geo.addPlaneSurface([1], 1) gmsh.model.addPhysicalGroup(2, [1], 1) gmsh.model.setPhysicalName(2, 1, "Tooth") # convert triangle mesh to rectangle mesh if is_rect: factory.mesh.setRecombine(2, 1) # Change the mesh size for each line if user_mesh_dict is not None: # Compute basic mesh_dict mesh_dict = tooth_surf.comp_mesh_dict(element_size=mesh_size) # Overwrite basic mesh dict with user one mesh_dict.update(user_mesh_dict) # Apply the number of element on each line of the surface for ii, line in enumerate(tooth_surf.get_lines()): factory.mesh.setTransfiniteCurve( ii + 1, mesh_dict[str(ii)] + 1, "Progression" ) # Copy/Rotate all the tooth to get the 2D lamination surf_list = [1] for ii in range(Zs): ov = factory.copy([(2, 1)]) factory.rotate(ov, 0, 0, -L / 2, 0, 0, 1, (ii + 1) * 2 * pi / Zs) surf_list.append(ov[0][1]) gmsh.model.addPhysicalGroup(2, surf_list, 2) gmsh.model.setPhysicalName(2, 2, "Lamination") # Extrude the lamination for surf in surf_list: if is_rect == True: ov = factory.extrude( [(2, surf)], 0, 0, L, numElements=[Nlayer], recombine=True ) else: ov = factory.extrude( [(2, surf)], 0, 0, L, numElements=[Nlayer], recombine=False ) model.addPhysicalGroup(3, list(range(1, Zs + 1)), 1) if lamination.is_stator: model.setPhysicalName(3, 1, "stator") else: model.setPhysicalName(3, 1, "rotor") # Generate the 3D mesh factory.synchronize() filename, file_extension = splitext(save_path) if file_extension == ".geo": gmsh.write(filename + ".geo_unrolled") replace(filename + ".geo_unrolled", filename + file_extension) else: gmsh.model.mesh.generate(3) gmsh.write(save_path) # Save and close gmsh.finalize()