Source code for pyleecan.Functions.GMSH.draw_surf_line

from .get_boundary_condition import get_boundary_condition
from numpy import pi
from ...Classes.Arc import Arc
from ...Classes.Arc2 import Arc2
import cmath

tol = 1e-6


[docs]def draw_surf_line( surf, mesh_dict, boundary_prop, factory, gmsh_dict, nsurf, mesh_size, ): """Draw the lines of a surface and handles the Arc>180deg Parameters ---------- surf : Surface Surface object to draw mesh_dict : dict Dictionary to enforce the mesh (key: line id, value:nb element) boundary_prop : dict Dictionary to set the Boundary conditions factory : gmsh.model.geo gmsh_dict: dict dictionary containing the main parameters of GMSH File nsurf : int Index of the surface to draw mesh_size: float Default mesh element size """ for ii, line in enumerate(surf.get_lines()): n_elem = mesh_dict[str(ii)] n_elem = n_elem if n_elem is not None else 0 bc_name = get_boundary_condition(line, boundary_prop) # Gmsh built-in engine does not allow arcs larger than 180deg # so arcs are split into two if isinstance(line, Arc) and abs(line.get_angle() * 180.0 / pi) >= 180.0: rot_dir = 1 if line.is_trigo_direction == True else -1 arc1 = Arc2( begin=line.get_begin(), center=line.get_center(), angle=rot_dir * pi / 2.0, prop_dict=line.prop_dict, ) arc2 = Arc2( begin=arc1.get_end(), center=line.get_center(), angle=rot_dir * pi / 2.0, prop_dict=line.prop_dict, ) for arc in [arc1, arc2]: _add_agline_to_dict( geo=factory, line=arc, d=gmsh_dict, idx=nsurf, mesh_size=mesh_size, n_elements=n_elem, bc=bc_name, ) elif isinstance(line, Arc) and (abs(line.get_angle() * 180.0 / pi) <= tol): # Don't draw anything, this is a circle and usually is repeated ? pass else: _add_agline_to_dict( geo=factory, line=line, d=gmsh_dict, idx=nsurf, mesh_size=mesh_size, n_elements=n_elem, bc=bc_name, )
def _add_agline_to_dict(geo, line, d={}, idx=0, mesh_size=1e-2, n_elements=0, bc=None): """Draw a new Air Gap line and add it to GMSH dictionary if it does not exist Parameters ---------- geo : Model GMSH Model objet line : Object Line Object d : Dictionary GMSH dictionary idx : int Surface index it belongs to mesh_size : float Points mesh size n_elements : int Number of elements on the line for meshing control Returns ------- None """ # TO-DO: Allow repeated points for the rotor and stator sliding bands dlines = list() ltag = None btag, bx, by = _find_point_tag(d, line.get_begin()) etag, ex, ey = _find_point_tag(d, line.get_end()) if btag is None: btag = geo.addPoint(bx, by, 0, meshSize=mesh_size, tag=-1) else: dlines.extend(_find_lines_from_point(d, btag)) if etag is None: etag = geo.addPoint(ex, ey, 0, meshSize=mesh_size, tag=-1) else: dlines.extend(_find_lines_from_point(d, etag)) if isinstance(line, Arc): ctag, cx, cy = _find_point_tag(d, line.get_center()) if ctag is None: ctag = geo.addPoint(cx, cy, 0, meshSize=mesh_size, tag=-1) else: dlines.extend(_find_lines_from_point(d, ctag)) if len(dlines) > 0: for iline in dlines: p = _find_points_from_line(d, iline) if p[0] == btag and p[1] == etag and p[2] == ctag: ltag = iline break elif p[0] == etag and p[1] == btag and p[2] == ctag: ltag = -iline break else: pass if ltag is None: ltag = geo.addCircleArc(btag, ctag, etag, tag=-1) if n_elements > 0: geo.mesh.setTransfiniteCurve(ltag, n_elements + 1, "Progression") else: ltag = geo.addCircleArc(btag, ctag, etag, tag=-1) if n_elements > 0: geo.mesh.setTransfiniteCurve(ltag, n_elements + 1, "Progression") # To avoid fill the dictionary with repeated lines repeated = False for lvalues in d[idx].values(): if type(lvalues) is not dict: continue else: if lvalues["tag"] == ltag: repeated = True if not repeated: nline = len(d[idx]) - 2 arc_angle = cmath.phase(complex(ex, ey)) - cmath.phase(complex(bx, by)) d[idx].update( { nline: { "tag": ltag, "n_elements": n_elements, "bc_name": bc, "begin": {"tag": btag, "coord": complex(bx, by)}, "end": {"tag": etag, "coord": complex(ex, ey)}, "cent": {"tag": ctag, "coord": complex(cx, cy)}, "arc_angle": arc_angle, "line_angle": None, } } ) else: if len(dlines) > 0: for iline in dlines: p = _find_points_from_line(d, iline) if p[0] == btag and p[1] == etag: ltag = iline break elif p[0] == etag and p[1] == btag: ltag = -iline break else: pass if ltag is None: ltag = geo.addLine(btag, etag, tag=-1) if n_elements > 0: geo.mesh.setTransfiniteCurve(ltag, n_elements + 1, "Progression") else: ltag = geo.addLine(btag, etag, tag=-1) if n_elements > 0: geo.mesh.setTransfiniteCurve(ltag, n_elements + 1, "Progression") # To avoid fill the dictionary with repeated lines repeated = False for lvalues in d[idx].values(): if type(lvalues) is not dict: continue else: if lvalues["tag"] == ltag: repeated = True if not repeated: nline = len(d[idx]) - 2 line_angle = 0.5 * ( cmath.phase(complex(ex, ey)) + cmath.phase(complex(bx, by)) ) d[idx].update( { nline: { "tag": ltag, "n_elements": n_elements, "bc_name": bc, "begin": {"tag": btag, "coord": complex(bx, by)}, "end": {"tag": etag, "coord": complex(ex, ey)}, "arc_angle": None, "line_angle": line_angle, } } ) return None def _find_lines_from_point(d={}, ptag=-1): """Find lines that have the given point tag Parameters ---------- d : Dictionary GMSH dictionary ptag : int point tag Returns ------- ltag : int List of line tags """ lines = list() for s_data in d.values(): for lvalues in s_data.values(): if type(lvalues) is not dict: continue for pvalues in lvalues.values(): if type(pvalues) is not dict: continue if pvalues["tag"] == ptag: lines.append(lvalues["tag"]) return lines def _add_line_to_dict(geo, line, d={}, idx=0, mesh_size=1e-2, n_elements=0, bc=None): """Draw a new line and add it to GMSH dictionary if it does not exist Parameters ---------- geo : Model GMSH Model objet line : Object Line Object d : Dictionary GMSH dictionary idx : int Surface index it belongs to mesh_size : float Points mesh size n_elements : int Number of elements on the line for meshing control Returns ------- None """ dlines = list() ltag = None btag, bx, by = _find_point_tag(d, line.get_begin()) etag, ex, ey = _find_point_tag(d, line.get_end()) if btag is None: btag = geo.addPoint(bx, by, 0, meshSize=mesh_size, tag=-1) else: dlines.extend(_find_lines_from_point(d, btag)) if etag is None: etag = geo.addPoint(ex, ey, 0, meshSize=mesh_size, tag=-1) else: dlines.extend(_find_lines_from_point(d, etag)) if isinstance(line, Arc): ctag, cx, cy = _find_point_tag(d, line.get_center()) if ctag is None: ctag = geo.addPoint(cx, cy, 0, meshSize=mesh_size, tag=-1) else: dlines.extend(_find_lines_from_point(d, ctag)) if len(dlines) > 0: for iline in dlines: p = _find_points_from_line(d, iline) if p[0] == btag and p[1] == etag and p[2] == ctag: ltag = iline break elif p[0] == etag and p[1] == btag and p[2] == ctag: ltag = -iline break else: pass if ltag is None: ltag = geo.addCircleArc(btag, ctag, etag, tag=-1) if n_elements > 0: geo.mesh.setTransfiniteCurve(ltag, n_elements + 1, "Progression") else: ltag = geo.addCircleArc(btag, ctag, etag, tag=-1) if n_elements > 0: geo.mesh.setTransfiniteCurve(ltag, n_elements + 1, "Progression") # To avoid fill the dictionary with repeated lines repeated = False for lvalues in d[idx].values(): if type(lvalues) is not dict: continue else: if lvalues["tag"] == ltag: repeated = True if not repeated: nline = len(d[idx]) - 2 arc_angle = cmath.phase(complex(ex, ey)) - cmath.phase(complex(bx, by)) d[idx].update( { nline: { "tag": ltag, "n_elements": n_elements, "bc_name": bc, "begin": {"tag": btag, "coord": complex(bx, by)}, "end": {"tag": etag, "coord": complex(ex, ey)}, "cent": {"tag": ctag, "coord": complex(cx, cy)}, "arc_angle": arc_angle, "line_angle": None, # "label": line.label, } } ) else: if len(dlines) > 0: for iline in dlines: p = _find_points_from_line(d, iline) if p[0] == btag and p[1] == etag: ltag = iline break elif p[0] == etag and p[1] == btag: ltag = -iline break else: pass if ltag is None: ltag = geo.addLine(btag, etag, tag=-1) if n_elements > 0: geo.mesh.setTransfiniteCurve(ltag, n_elements + 1, "Progression") else: ltag = geo.addLine(btag, etag, tag=-1) if n_elements > 0: geo.mesh.setTransfiniteCurve(ltag, n_elements + 1, "Progression") # To avoid fill the dictionary with repeated lines repeated = False for lvalues in d[idx].values(): if type(lvalues) is not dict: continue else: if lvalues["tag"] == ltag: repeated = True if not repeated: nline = len(d[idx]) - 2 line_angle = 0.5 * ( cmath.phase(complex(ex, ey)) + cmath.phase(complex(bx, by)) ) d[idx].update( { nline: { "tag": ltag, "n_elements": n_elements, "bc_name": bc, "begin": {"tag": btag, "coord": complex(bx, by)}, "end": {"tag": etag, "coord": complex(ex, ey)}, "arc_angle": None, "line_angle": line_angle, # "label": line.label, } } ) return None def _find_point_tag(d={}, p=complex(0.0, 0.0)): """Find a point in the GMSH dictionary Parameters ---------- d : Dictionary GMSH dictionary p : Complex Point coordinates Returns ------- tag : int Existing tag number or new one if it does not exist real : float Real coordinates of point imag : float Imaginary coordinates of point """ tol = 1e-6 for s_data in d.values(): for lvalues in s_data.values(): if type(lvalues) is not dict: continue for pvalues in lvalues.values(): if type(pvalues) is not dict: continue if pvalues["tag"] is not None: b = pvalues["coord"] if abs(p.real - b.real) < tol and abs(p.imag - b.imag) < tol: return pvalues["tag"], b.real, b.imag return None, p.real, p.imag def _find_points_from_line(d={}, ltag=-1): """Find points tag from existing lines Parameters ---------- d : Dictionary GMSH dictionary ltag : int line tag Returns ------- coord : float Coordinates of point if found """ btag = None etag = None ctag = None for s_data in d.values(): for lvalues in s_data.values(): if type(lvalues) is not dict: continue if lvalues["tag"] != ltag: continue else: for pid, pvalues in lvalues.items(): if type(pvalues) is not dict: continue if pid == "begin": btag = pvalues["tag"] elif pid == "end": etag = pvalues["tag"] elif pid == "cent": ctag = pvalues["tag"] break return [btag, etag, ctag]