def get_ref_coors(field, coors, strategy='kdtree', close_limit=0.1, cache=None): """ Get reference element coordinates and elements corresponding to given physical coordinates. Parameters ---------- field : Field instance The field defining the approximation. coors : array The physical coordinates. strategy : str, optional The strategy for finding the elements that contain the coordinates. Only 'kdtree' is supported for the moment. close_limit : float, optional The maximum limit distance of a point from the closest element allowed for extrapolation. cache : Struct, optional To speed up a sequence of evaluations, the field mesh, the inverse connectivity of the field mesh and the KDTree instance can be cached as `cache.mesh`, `cache.offsets`, `cache.iconn` and `cache.kdtree`. Optionally, the cache can also contain the reference element coordinates as `cache.ref_coors`, `cache.cells` and `cache.status`, if the evaluation occurs in the same coordinates repeatedly. In that case the KDTree related data are ignored. Returns ------- ref_coors : array The reference coordinates. cells : array The cell indices corresponding to the reference coordinates. status : array The status: 0 is success, 1 is extrapolation within `close_limit`, 2 is extrapolation outside `close_limit`, 3 is failure. """ ref_coors = get_default_attr(cache, 'ref_coors', None) if ref_coors is None: mesh = get_default_attr(cache, 'mesh', None) if mesh is None: mesh = field.create_mesh(extra_nodes=False) scoors = mesh.coors output('reference field: %d vertices' % scoors.shape[0]) iconn = get_default_attr(cache, 'iconn', None) if iconn is None: offsets, iconn = make_inverse_connectivity(mesh.conns, mesh.n_nod, ret_offsets=True) ii = nm.where(offsets[1:] == offsets[:-1])[0] if len(ii): raise ValueError('some vertices not in any element! (%s)' % ii) else: offsets = cache.offsets if strategy == 'kdtree': kdtree = get_default_attr(cache, 'kdtree', None) if kdtree is None: from scipy.spatial import cKDTree as KDTree tt = time.clock() kdtree = KDTree(scoors) output('kdtree: %f s' % (time.clock() - tt)) tt = time.clock() ics = kdtree.query(coors)[1] output('kdtree query: %f s' % (time.clock() - tt)) tt = time.clock() ics = nm.asarray(ics, dtype=nm.int32) vertex_coorss, nodess, mtx_is = [], [], [] conns = [] for ig, ap in field.aps.iteritems(): ps = ap.interp.gel.interp.poly_spaces['v'] vertex_coorss.append(ps.geometry.coors) nodess.append(ps.nodes) mtx_is.append(ps.get_mtx_i()) conns.append(mesh.conns[ig].copy()) # Get reference element coordinates corresponding to # destination coordinates. ref_coors = nm.empty_like(coors) cells = nm.empty((coors.shape[0], 2), dtype=nm.int32) status = nm.empty((coors.shape[0], ), dtype=nm.int32) find_ref_coors(ref_coors, cells, status, coors, ics, offsets, iconn, scoors, conns, vertex_coorss, nodess, mtx_is, 1, close_limit, 1e-15, 100, 1e-8) output('ref. coordinates: %f s' % (time.clock() - tt)) elif strategy == 'crawl': raise NotImplementedError else: raise ValueError('unknown search strategy! (%s)' % strategy) else: ref_coors = cache.ref_coors cells = cache.cells status = cache.status return ref_coors, cells, status
def __init__(self, name, mesh, share_mesh=True, n_point=None, **kwargs): """ Parameters ---------- name : str The probe name, set automatically by the subclasses. mesh : Mesh instance The FE mesh where the variables to be probed are defined. share_mesh : bool Set to True to indicate that all the probes will work on the same mesh. Certain data are then computed only for the first probe and cached. n_point : int The (fixed) number of probe points, when positive. When non-positive, the number of points is adaptively increased starting from -n_point, until the neighboring point distance is less than the diameter of the elements enclosing the points. When None, it is set to -10. For additional parameters see the __init__() docstrings of the subclasses. Notes ----- If the mesh contains vertices that are not contained in any element, we shift coordinates of such vertices so that they never match in the nearest node search. """ Struct.__init__(self, name=name, mesh=mesh, **kwargs) self.set_n_point(n_point) self.options = Struct() self.set_options(close_limit=0.1, size_hint=None) self.is_refined = False tt = time.clock() if share_mesh: if Probe.cache.iconn is None: offsets, iconn = make_inverse_connectivity(mesh.conns, mesh.n_nod, ret_offsets=True) Probe.cache.iconn = iconn Probe.cache.offsets = offsets self.cache = Probe.cache else: offsets, iconn = make_inverse_connectivity(mesh.conns, mesh.n_nod, ret_offsets=True) self.cache = Struct(name='probe_cache', offsets=offsets, iconn=iconn, kdtree=None) output('iconn: %f s' % (time.clock()-tt)) i_bad = nm.where(nm.diff(self.cache.offsets) == 0)[0] if len(i_bad): bbox = mesh.get_bounding_box() mesh.coors[i_bad] = bbox[1] + bbox[1] - bbox[0] output('warning: some vertices are not in any element!') output('warning: vertex-based results will be wrong!') tt = time.clock() if share_mesh: if Probe.cache.kdtree is None: self.cache.kdtree = KDTree(mesh.coors) else: self.cache.kdtree = KDTree(mesh.coors) output('kdtree: %f s' % (time.clock()-tt))
def __init__(self, name, mesh, share_mesh=True, n_point=None, **kwargs): """ Parameters ---------- name : str The probe name, set automatically by the subclasses. mesh : Mesh instance The FE mesh where the variables to be probed are defined. share_mesh : bool Set to True to indicate that all the probes will work on the same mesh. Certain data are then computed only for the first probe and cached. n_point : int The (fixed) number of probe points, when positive. When non-positive, the number of points is adaptively increased starting from -n_point, until the neighboring point distance is less than the diameter of the elements enclosing the points. When None, it is set to -10. For additional parameters see the __init__() docstrings of the subclasses. Notes ----- If the mesh contains vertices that are not contained in any element, we shift coordinates of such vertices so that they never match in the nearest node search. """ Struct.__init__(self, name=name, mesh=mesh, **kwargs) self.set_n_point(n_point) self.options = Struct(close_limit=0.1, size_hint=None) self.is_refined = False tt = time.clock() if share_mesh: if Probe.cache.iconn is None: offsets, iconn = make_inverse_connectivity(mesh.conns, mesh.n_nod, ret_offsets=True) Probe.cache.iconn = iconn Probe.cache.offsets = offsets self.cache = Probe.cache else: offsets, iconn = make_inverse_connectivity(mesh.conns, mesh.n_nod, ret_offsets=True) self.cache = Struct(name='probe_cache', offsets=offsets, iconn=iconn, kdtree=None) output('iconn: %f s' % (time.clock()-tt)) i_bad = nm.where(nm.diff(self.cache.offsets) == 0)[0] if len(i_bad): bbox = mesh.get_bounding_box() mesh.coors[i_bad] = bbox[1] + bbox[1] - bbox[0] output('warning: some vertices are not in any element!') output('warning: vertex-based results will be wrong!') tt = time.clock() if share_mesh: if Probe.cache.kdtree is None: self.cache.kdtree = KDTree(mesh.coors) else: self.cache.kdtree = KDTree(mesh.coors) output('kdtree: %f s' % (time.clock()-tt))
def get_ref_coors(field, coors, strategy='kdtree', close_limit=0.1, cache=None, verbose=True): """ Get reference element coordinates and elements corresponding to given physical coordinates. Parameters ---------- field : Field instance The field defining the approximation. coors : array The physical coordinates. strategy : str, optional The strategy for finding the elements that contain the coordinates. Only 'kdtree' is supported for the moment. close_limit : float, optional The maximum limit distance of a point from the closest element allowed for extrapolation. cache : Struct, optional To speed up a sequence of evaluations, the field mesh, the inverse connectivity of the field mesh and the KDTree instance can be cached as `cache.mesh`, `cache.offsets`, `cache.iconn` and `cache.kdtree`. Optionally, the cache can also contain the reference element coordinates as `cache.ref_coors`, `cache.cells` and `cache.status`, if the evaluation occurs in the same coordinates repeatedly. In that case the KDTree related data are ignored. verbose : bool If False, reduce verbosity. Returns ------- ref_coors : array The reference coordinates. cells : array The cell indices corresponding to the reference coordinates. status : array The status: 0 is success, 1 is extrapolation within `close_limit`, 2 is extrapolation outside `close_limit`, 3 is failure. """ ref_coors = get_default_attr(cache, 'ref_coors', None) if ref_coors is None: mesh = get_default_attr(cache, 'mesh', None) if mesh is None: mesh = field.create_mesh(extra_nodes=False) scoors = mesh.coors output('reference field: %d vertices' % scoors.shape[0], verbose=verbose) iconn = get_default_attr(cache, 'iconn', None) if iconn is None: offsets, iconn = make_inverse_connectivity(mesh.conns, mesh.n_nod, ret_offsets=True) ii = nm.where(offsets[1:] == offsets[:-1])[0] if len(ii): raise ValueError('some vertices not in any element! (%s)' % ii) else: offsets = cache.offsets if strategy == 'kdtree': kdtree = get_default_attr(cache, 'kdtree', None) if kdtree is None: from scipy.spatial import cKDTree as KDTree tt = time.clock() kdtree = KDTree(scoors) output('kdtree: %f s' % (time.clock()-tt), verbose=verbose) tt = time.clock() ics = kdtree.query(coors)[1] output('kdtree query: %f s' % (time.clock()-tt), verbose=verbose) tt = time.clock() ics = nm.asarray(ics, dtype=nm.int32) vertex_coorss, nodess, mtx_is = [], [], [] conns = [] for ig, ap in field.aps.iteritems(): ps = ap.interp.gel.interp.poly_spaces['v'] vertex_coorss.append(ps.geometry.coors) nodess.append(ps.nodes) mtx_is.append(ps.get_mtx_i()) conns.append(mesh.conns[ig].copy()) # Get reference element coordinates corresponding to # destination coordinates. ref_coors = nm.empty_like(coors) cells = nm.empty((coors.shape[0], 2), dtype=nm.int32) status = nm.empty((coors.shape[0],), dtype=nm.int32) find_ref_coors(ref_coors, cells, status, coors, ics, offsets, iconn, scoors, conns, vertex_coorss, nodess, mtx_is, 1, close_limit, 1e-15, 100, 1e-8) output('ref. coordinates: %f s' % (time.clock()-tt), verbose=verbose) elif strategy == 'crawl': raise NotImplementedError else: raise ValueError('unknown search strategy! (%s)' % strategy) else: ref_coors = cache.ref_coors cells = cache.cells status = cache.status return ref_coors, cells, status