def plot_edges(ax, gel, length, show=False): """ Plot edges of a geometry element as numbered arrows. """ dim = gel.dim ax = _get_axes(ax, dim) l2 = 0.5 * length for ii, edge in enumerate(gel.edges): cc = gel.coors[edge] centre = 0.5 * cc.sum(axis=0) vdir = (cc - centre) normalize_vectors(vdir) cc = l2 * vdir + centre draw_arrow(ax, cc, length=0.3 * length, linewidth=3, color='b') if dim == 3: cx, cy, cz = centre ax.text(cx, cy, cz, ii, color='b', fontsize=10, weight='light') else: cx, cy = centre ax.text(cx, cy, ii, color='b', fontsize=10, weight='light') return ax
def plot_edges(ax, gel, length, show=False): """ Plot edges of a geometry element as numbered arrows. """ dim = gel.dim ax = _get_axes(ax, dim) l2 = 0.5 * length for ii, edge in enumerate(gel.edges): cc = gel.coors[edge] centre = 0.5 * cc.sum(axis=0) vdir = (cc - centre) normalize_vectors(vdir) cc = l2 * vdir + centre draw_arrow(ax, cc, length=0.3*length, linewidth=3, color='b') if dim == 3: cx, cy, cz = centre ax.text(cx, cy, cz, ii, color='b', fontsize=10, weight='light') else: cx, cy = centre ax.text(cx, cy, ii, color='b', fontsize=10, weight='light') return ax
def test_normals(self): """ Check orientations of surface normals on the reference elements. """ import sfepy from sfepy.discrete import Integral from sfepy.discrete.fem import Mesh, FEDomain from sfepy.discrete.fem.poly_spaces import PolySpace from sfepy.discrete.fem.mappings import SurfaceMapping from sfepy.linalg import normalize_vectors ok = True for geom in ['2_3', '2_4', '3_4', '3_8']: mesh = Mesh.from_file('meshes/elements/%s_1.mesh' % geom, prefix_dir=sfepy.data_dir) domain = FEDomain('domain', mesh) surface = domain.create_region('Surface', 'vertices of surface', 'facet') domain.create_surface_group(surface) sd = domain.surface_groups[surface.name] coors = domain.get_mesh_coors() gel = domain.geom_els[geom].surface_facet ps = PolySpace.any_from_args('aux', gel, 1) mapping = SurfaceMapping(coors, sd.get_connectivity(), ps) integral = Integral('i', order=1) vals, weights = integral.get_qp(gel.name) # Evaluate just in the first quadrature point... geo = mapping.get_mapping(vals[:1], weights[:1]) expected = expected_normals[geom].copy() normalize_vectors(expected) _ok = nm.allclose(expected, geo.normal[:, 0, :, 0], rtol=0.0, atol=1e-14) self.report('%s: %s' % (geom, _ok)) if not _ok: self.report('expected:') self.report(expected) self.report('actual:') self.report(geo.normal[:, 0, :, 0]) ok = ok and _ok return ok
def compute_nodal_edge_dirs(nodes, region, field, return_imap=False): """ Nodal edge directions are computed by simple averaging of direction vectors of edges a node is contained in. Edges are assumed to be straight and a node must be on a single edge (a border node) or shared by exactly two edges. """ coors = region.domain.mesh.coors dim = coors.shape[1] graph = region.get_edge_graph() imap = prepare_remap(nodes, nodes.max() + 1) mask = nm.zeros_like(imap) try: paths = get_edge_paths(graph, mask) except ValueError: raise ValueError('more than 2 edges sharing a vertex in region %s!' % region.name) # All nodes must have an edge direction. if not nm.all(mask[nodes]): raise ValueError('region %s has not complete edges!' % region.name) edge_dirs = nm.zeros((nodes.shape[0], dim), dtype=nm.float64) for path in paths: pcoors = coors[path] edirs = nm.diff(pcoors, axis=0) la.normalize_vectors(edirs, eps=1e-12) im = imap[nm.c_[path[:-1], path[1:]]] for ii, edir in enumerate(edirs): edge_dirs[im[ii]] += edir la.normalize_vectors(edge_dirs, eps=1e-12) if return_imap: return edge_dirs, imap else: return edge_dirs
def plot_edges(ax, gel, length): """ Plot edges of a geometry element as numbered arrows. """ dim = gel.dim ax = _get_axes(ax, dim) if gel.edges is None: return ax l2 = 0.5 * length for ii, edge in enumerate(gel.edges): cc = gel.coors[edge] centre = 0.5 * cc.sum(axis=0) vdir = (cc - centre) normalize_vectors(vdir) cc = l2 * vdir + centre draw_arrow(ax, cc, length=0.3*length, linewidth=3, color='b') ax.text(*centre, s=ii, color='b', fontsize=10, weight='light') return ax