def main(): parser = ArgumentParser(description=__doc__.rstrip(), formatter_class=RawDescriptionHelpFormatter) parser.add_argument('filename', help=helps['filename']) parser.add_argument('-d', '--detailed', action='store_true', dest='detailed', default=False, help=helps['detailed']) options = parser.parse_args() mesh = Mesh.from_file(options.filename) output(mesh.cmesh) output('element types:', mesh.descs) output('nodal BCs:', sorted(mesh.nodal_bcs.keys())) bbox = mesh.get_bounding_box() output('bounding box: %s' % ', '.join('%s: [%s, %s]' % (name, bbox[0, ii], bbox[1, ii]) for ii, name in enumerate('xyz'[:mesh.dim]))) output('centre:', mesh.coors.mean(0)) if not options.detailed: return from sfepy.discrete.fem.geometry_element import create_geometry_elements gels = create_geometry_elements() mesh.cmesh.set_local_entities(gels) mesh.cmesh.setup_entities() for dim in range(1, mesh.cmesh.tdim + 1): volumes = mesh.cmesh.get_volumes(dim) output('volumes of %d %dD entities: min: %s mean: %s max: %s' % (mesh.cmesh.num[dim], dim, volumes.min(), volumes.mean(), volumes.max()))
def __init__(self, name, nurbs, bmesh, regions=None, **kwargs): """ Create an IGA domain. Parameters ---------- name : str The domain name. """ Domain.__init__(self, name, nurbs=nurbs, bmesh=bmesh, regions=regions, **kwargs) from sfepy.discrete.fem.geometry_element import create_geometry_elements from sfepy.discrete.fem import Mesh from sfepy.discrete.fem.extmods.cmesh import CMesh from sfepy.discrete.fem.utils import prepare_remap ac = nm.ascontiguousarray self.nurbs.cs = [ac(nm.array(cc, dtype=nm.float64)[:, None, ...]) for cc in self.nurbs.cs] self.nurbs.degrees = self.nurbs.degrees.astype(nm.int32) self.facets = iga.get_bezier_element_entities(nurbs.degrees) tconn = iga.get_bezier_topology(bmesh.conn, nurbs.degrees) itc = nm.unique(tconn) remap = prepare_remap(itc, bmesh.conn.max() + 1) ltcoors = bmesh.cps[itc] ltconn = remap[tconn] n_nod, dim = ltcoors.shape n_el = ltconn.shape[0] self.shape = Struct(n_nod=n_nod, dim=dim, tdim=0, n_el=n_el, n_gr=1) desc = '%d_%d' % (dim, 2**dim) mat_id = nm.zeros(ltconn.shape[0], dtype=nm.int32) self.mesh = Mesh.from_data(self.name + '_topo', ltcoors, None, [ltconn], [mat_id], [desc]) self.cmesh = CMesh.from_mesh(self.mesh) gels = create_geometry_elements() self.cmesh.set_local_entities(gels) self.cmesh.setup_entities() self.shape.tdim = self.cmesh.tdim self.gel = gels[desc] if regions is not None: self.vertex_set_bcs = {} for key, val in self.regions.iteritems(): self.vertex_set_bcs[key] = remap[val] self.cell_offsets = {0 : 0} self.reset_regions()
def __init__(self, name, nurbs, bmesh, regions=None, **kwargs): """ Create an IGA domain. Parameters ---------- name : str The domain name. """ Domain.__init__(self, name, nurbs=nurbs, bmesh=bmesh, regions=regions, **kwargs) from sfepy.discrete.fem.geometry_element import create_geometry_elements from sfepy.discrete.fem import Mesh from sfepy.discrete.fem.utils import prepare_remap tconn = iga.get_bezier_topology(bmesh.conn, nurbs.degrees) itc = nm.unique(tconn) remap = prepare_remap(itc, bmesh.conn.max() + 1) ltcoors = bmesh.cps[itc] ltconn = remap[tconn] n_nod, dim = ltcoors.shape n_el = ltconn.shape[0] self.shape = Struct(n_nod=n_nod, dim=dim, tdim=0, n_el=n_el) desc = '%d_%d' % (dim, bmesh.conn.shape[1]) mat_id = nm.zeros(bmesh.conn.shape[0], dtype=nm.int32) eval_mesh = Mesh.from_data(self.name + '_eval', nurbs.cps, None, [nurbs.conn], [mat_id], [desc]) self.eval_mesh = eval_mesh desc = '%d_%d' % (dim, 2**dim) mat_id = nm.zeros(ltconn.shape[0], dtype=nm.int32) self.mesh = Mesh.from_data(self.name + '_topo', ltcoors, None, [ltconn], [mat_id], [desc]) self.cmesh = self.mesh.cmesh gels = create_geometry_elements() self.cmesh.set_local_entities(gels) self.cmesh.setup_entities() self.shape.tdim = self.cmesh.tdim self.gel = gels[desc] if regions is not None: self.vertex_set_bcs = {} for key, val in six.iteritems(self.regions): self.vertex_set_bcs[key] = remap[val] self.reset_regions()
def __init__(self, name, mesh, verbose=False, **kwargs): """Create a Domain. Parameters ---------- name : str Object name. mesh : Mesh A mesh defining the domain. """ Domain.__init__(self, name, mesh=mesh, verbose=verbose, **kwargs) self.geom_els = geom_els = {} for ig, desc in enumerate(mesh.descs): gel = GeometryElement(desc) if gel.dim > 1: # Create geometry elements of dimension - 1. gel.create_surface_facet() geom_els[desc] = gel self.geom_interps = interps = {} for gel in geom_els.itervalues(): key = gel.get_interpolation_name() gel.interp = interps.setdefault(key, fea.Interpolant(key, gel)) gel = gel.surface_facet if gel is not None: key = gel.get_interpolation_name() gel.interp = interps.setdefault(key, fea.Interpolant(key, gel)) self.vertex_set_bcs = self.mesh.nodal_bcs self.mat_ids_to_i_gs = {} for ig, mat_id in enumerate(mesh.mat_ids): self.mat_ids_to_i_gs[mat_id[0]] = ig n_nod, dim = self.mesh.coors.shape self.shape = Struct(n_nod=n_nod, dim=dim, tdim=0, n_el=0, n_gr=len(self.mesh.conns)) self.setup_groups() self.fix_element_orientation() self.reset_regions() self.clear_surface_groups() from sfepy.discrete.fem.geometry_element import create_geometry_elements from sfepy.discrete.fem.extmods.cmesh import CMesh self.cmesh = CMesh.from_mesh(mesh) gels = create_geometry_elements() self.cmesh.set_local_entities(gels) self.cmesh.setup_entities() self.shape.tdim = self.cmesh.tdim self.cell_offsets = self.mesh.el_offsets
def __init__(self, name, mesh, verbose=False, **kwargs): """Create a Domain. Parameters ---------- name : str Object name. mesh : Mesh A mesh defining the domain. """ Domain.__init__(self, name, mesh=mesh, verbose=verbose, **kwargs) if len(mesh.descs) > 1: msg = 'meshes with several cell kinds are not supported!' raise NotImplementedError(msg) self.geom_els = geom_els = {} for ig, desc in enumerate(mesh.descs): gel = GeometryElement(desc) if gel.dim > 0: # Create geometry elements of dimension - 1. gel.create_surface_facet() geom_els[desc] = gel for gel in six.itervalues(geom_els): key = gel.get_interpolation_name() gel.poly_space = PolySpace.any_from_args(key, gel, 1) gel = gel.surface_facet if gel is not None: key = gel.get_interpolation_name() gel.poly_space = PolySpace.any_from_args(key, gel, 1) self.vertex_set_bcs = self.mesh.nodal_bcs self.cmesh = self.mesh.cmesh # Must be before creating derived connectivities. self.fix_element_orientation() from sfepy.discrete.fem.geometry_element import create_geometry_elements gels = create_geometry_elements() self.cmesh.set_local_entities(gels) self.cmesh.setup_entities() n_nod, dim = self.mesh.coors.shape self.shape = Struct(n_nod=n_nod, dim=dim, tdim=self.cmesh.tdim, n_el=self.cmesh.n_el, n_gr=len(self.geom_els)) self.reset_regions() self.clear_surface_groups()
def __init__(self, name, mesh, verbose=False, **kwargs): """Create a Domain. Parameters ---------- name : str Object name. mesh : Mesh A mesh defining the domain. """ Domain.__init__(self, name, mesh=mesh, verbose=verbose, **kwargs) if len(mesh.descs) > 1: msg = 'meshes with several cell kinds are not supported!' raise NotImplementedError(msg) self.geom_els = geom_els = {} for ig, desc in enumerate(mesh.descs): gel = GeometryElement(desc) if gel.dim > 1: # Create geometry elements of dimension - 1. gel.create_surface_facet() geom_els[desc] = gel self.geom_interps = interps = {} for gel in geom_els.itervalues(): key = gel.get_interpolation_name() gel.interp = interps.setdefault(key, fea.Interpolant(key, gel)) gel = gel.surface_facet if gel is not None: key = gel.get_interpolation_name() gel.interp = interps.setdefault(key, fea.Interpolant(key, gel)) self.vertex_set_bcs = self.mesh.nodal_bcs self.cmesh = self.mesh.cmesh # Must be before creating derived connectivities. self.fix_element_orientation() from sfepy.discrete.fem.geometry_element import create_geometry_elements gels = create_geometry_elements() self.cmesh.set_local_entities(gels) self.cmesh.setup_entities() n_nod, dim = self.mesh.coors.shape self.shape = Struct(n_nod=n_nod, dim=dim, tdim=self.cmesh.tdim, n_el=self.cmesh.n_el, n_gr=len(self.geom_els)) self.reset_regions() self.clear_surface_groups()
def __init__(self, name, mesh, verbose=False, **kwargs): """Create a Domain. Parameters ---------- name : str Object name. mesh : Mesh A mesh defining the domain. """ Domain.__init__(self, name, mesh=mesh, verbose=verbose, **kwargs) self.geom_els = geom_els = {} for ig, desc in enumerate(mesh.descs): gel = GeometryElement(desc) # Create geometry elements of dimension - 1. gel.create_surface_facet() geom_els[desc] = gel self.geom_interps = interps = {} for gel in geom_els.itervalues(): key = gel.get_interpolation_name() gel.interp = interps.setdefault(key, fea.Interpolant(key, gel)) gel = gel.surface_facet if gel is not None: key = gel.get_interpolation_name() gel.interp = interps.setdefault(key, fea.Interpolant(key, gel)) self.vertex_set_bcs = self.mesh.nodal_bcs self.mat_ids_to_i_gs = {} for ig, mat_id in enumerate(mesh.mat_ids): self.mat_ids_to_i_gs[mat_id[0]] = ig n_nod, dim = self.mesh.coors.shape self.shape = Struct(n_nod=n_nod, dim=dim, tdim=0, n_el=0, n_gr=len(self.mesh.conns)) self.setup_groups() self.fix_element_orientation() self.reset_regions() self.clear_surface_groups() from sfepy.discrete.fem.geometry_element import create_geometry_elements from sfepy.discrete.fem.extmods.cmesh import CMesh self.cmesh = CMesh.from_mesh(mesh) gels = create_geometry_elements() self.cmesh.set_local_entities(gels) self.cmesh.setup_entities() self.shape.tdim = self.cmesh.tdim self.cell_offsets = self.mesh.el_offsets
def __init__(self, name, nurbs, bmesh, regions=None, **kwargs): """ Create an IGA domain. Parameters ---------- name : str The domain name. """ Domain.__init__(self, name, nurbs=nurbs, bmesh=bmesh, regions=regions, **kwargs) from sfepy.discrete.fem.geometry_element import create_geometry_elements from sfepy.discrete.fem import Mesh from sfepy.discrete.fem.utils import prepare_remap tconn = iga.get_bezier_topology(bmesh.conn, nurbs.degrees) itc = nm.unique(tconn) remap = prepare_remap(itc, bmesh.conn.max() + 1) ltcoors = bmesh.cps[itc] ltconn = remap[tconn] n_nod, dim = ltcoors.shape n_el = ltconn.shape[0] self.shape = Struct(n_nod=n_nod, dim=dim, tdim=0, n_el=n_el) desc = '%d_%d' % (dim, bmesh.conn.shape[1]) mat_id = nm.zeros(bmesh.conn.shape[0], dtype=nm.int32) eval_mesh = Mesh.from_data(self.name + '_eval', nurbs.cps, None, [nurbs.conn], [mat_id], [desc]) self.eval_mesh = eval_mesh desc = '%d_%d' % (dim, 2**dim) mat_id = nm.zeros(ltconn.shape[0], dtype=nm.int32) self.mesh = Mesh.from_data(self.name + '_topo', ltcoors, None, [ltconn], [mat_id], [desc]) self.cmesh = self.mesh.cmesh gels = create_geometry_elements() self.cmesh.set_local_entities(gels) self.cmesh.setup_entities() self.shape.tdim = self.cmesh.tdim self.gel = gels[desc] if regions is not None: self.vertex_set_bcs = {} for key, val in self.regions.iteritems(): self.vertex_set_bcs[key] = remap[val] self.reset_regions()
def get_evaluate_cache(self, cache=None, share_geometry=False, verbose=False): """ Get the evaluate cache for :func:`Variable.evaluate_at() <sfepy.discrete.variables.Variable.evaluate_at()>`. Parameters ---------- cache : Struct instance, optional Optionally, use the provided instance to store the cache data. share_geometry : bool Set to True to indicate that all the evaluations will work on the same region. Certain data are then computed only for the first probe and cached. verbose : bool If False, reduce verbosity. Returns ------- cache : Struct instance The evaluate cache. """ import time try: from scipy.spatial import cKDTree as KDTree except ImportError: from scipy.spatial import KDTree from sfepy.discrete.fem.geometry_element import create_geometry_elements if cache is None: cache = Struct(name='evaluate_cache') tt = time.clock() if (cache.get('cmesh', None) is None) or not share_geometry: mesh = self.create_mesh(extra_nodes=False) cache.cmesh = cmesh = mesh.cmesh gels = create_geometry_elements() cmesh.set_local_entities(gels) cmesh.setup_entities() cache.centroids = cmesh.get_centroids(cmesh.tdim) if self.gel.name != '3_8': cache.normals0 = cmesh.get_facet_normals() cache.normals1 = None else: cache.normals0 = cmesh.get_facet_normals(0) cache.normals1 = cmesh.get_facet_normals(1) output('cmesh setup: %f s' % (time.clock()-tt), verbose=verbose) tt = time.clock() if (cache.get('kdtree', None) is None) or not share_geometry: cache.kdtree = KDTree(cmesh.coors) output('kdtree: %f s' % (time.clock()-tt), verbose=verbose) return cache
def test_cmesh_counts(self): from sfepy.discrete.fem import Mesh from sfepy.discrete.fem.geometry_element import create_geometry_elements from sfepy.discrete.common.extmods.cmesh import CMesh, get_cmem_usage gels = create_geometry_elements() ok = True for filename in self.filename_meshes: basename = os.path.basename(filename) enum, esizes = expected[basename] self.report('mesh: %s' % basename) mesh = Mesh.from_file(filename) cmesh = mesh.cmesh cmesh.set_local_entities(gels) cmesh.setup_entities() self.report('dim:', cmesh.dim) self.report('n_vertex: %d, n_edge: %d, n_face: %d, n_cell: %d' % tuple(cmesh.num)) _ok = (enum == cmesh.num).all() if not _ok: self.report('%s == %s failed!' % (enum, cmesh.num)) ok = ok and _ok dim = cmesh.dim for ir in range(dim + 1): for ic in range(dim + 1): cmesh.setup_connectivity(ir, ic) mem_usage1 = get_cmem_usage()[0] if (ir == dim) and (ic == 0): continue cmesh.free_connectivity(ir, ic) mem_usage2 = get_cmem_usage()[0] cmesh.setup_connectivity(ir, ic) mem_usage3 = get_cmem_usage()[0] conn = cmesh.get_conn(ir, ic) self.report('(%d, %d) : (%d, %d)' % (ir, ic, conn.num, conn.n_incident)) sizes = nm.array([conn.num, conn.n_incident]) _ok = (esizes[ir, ic] == sizes).all() if not _ok: self.report('%s == %s failed!' % (esizes, sizes)) ok = ok and _ok _ok1 = mem_usage3 == mem_usage1 _ok2 = mem_usage3 > mem_usage2 if not (_ok1 and _ok2): self.report('unexpected memory usage! (%s)' % (mem_usage1, mem_usage2, mem_usage3)) ok = ok and (_ok1 and _ok2) return ok
def get_ref_coors_general(field, coors, close_limit=0.1, get_cells_fun=None, cache=None, verbose=False): """ 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. close_limit : float, optional The maximum limit distance of a point from the closest element allowed for extrapolation. get_cells_fun : callable, optional If given, a function with signature ``get_cells_fun(coors, cmesh, **kwargs)`` returning cells and offsets that potentially contain points with the coordinates `coors`. When not given, :func:`get_potential_cells()` is used. cache : Struct, optional To speed up a sequence of evaluations, the field mesh and other data can be cached. 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 mesh 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, 4 is failure due to non-convergence of the Newton iteration in tensor product cells. If close_limit is 0, then status 5 indicates points outside of the field domain that had no potential cells. """ ref_coors = get_default_attr(cache, "ref_coors", None) if ref_coors is None: extrapolate = close_limit > 0.0 get = get_potential_cells if get_cells_fun is None else get_cells_fun ref_coors = nm.empty_like(coors) cells = nm.empty((coors.shape[0],), dtype=nm.int32) status = nm.empty((coors.shape[0],), dtype=nm.int32) cmesh = get_default_attr(cache, "cmesh", None) if cmesh is None: tt = time.clock() mesh = field.create_mesh(extra_nodes=False) cmesh = mesh.cmesh gels = create_geometry_elements() cmesh.set_local_entities(gels) cmesh.setup_entities() if get_cells_fun is None: centroids = cmesh.get_centroids(cmesh.tdim) else: centroids = None output("cmesh setup: %f s" % (time.clock() - tt), verbose=verbose) else: centroids = cache.centroids tt = time.clock() potential_cells, offsets = get(coors, cmesh, centroids=centroids, extrapolate=extrapolate) output("potential cells: %f s" % (time.clock() - tt), verbose=verbose) ap = field.ap ps = ap.interp.gel.interp.poly_spaces["v"] mtx_i = ps.get_mtx_i() ac = nm.ascontiguousarray tt = time.clock() crc.find_ref_coors( ref_coors, cells, status, ac(coors), cmesh, potential_cells, offsets, ps.geometry.coors, ps.nodes, mtx_i, extrapolate, close_limit, 1e-15, 100, 1e-8, ) if extrapolate: assert_(nm.all(status < 5)) output("ref. coordinates: %f s" % (time.clock() - tt), verbose=verbose) else: cells = cache.cells status = cache.status return ref_coors, cells, status
def get_ref_coors_convex(field, coors, close_limit=0.1, cache=None, verbose=False): """ 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. 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 and other data can be cached. 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 mesh 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, 4 is failure due to non-convergence of the Newton iteration in tensor product cells. Notes ----- Outline of the algorithm for finding xi such that X(xi) = P: 1. make inverse connectivity - for each vertex have cells it is in. 2. find the closest vertex V. 3. choose initial cell: i0 = first from cells incident to V. 4. while not P in C_i, change C_i towards P, check if P in new C_i. """ ref_coors = get_default_attr(cache, "ref_coors", None) if ref_coors is None: extrapolate = close_limit > 0.0 ref_coors = nm.empty_like(coors) cells = nm.empty((coors.shape[0],), dtype=nm.int32) status = nm.empty((coors.shape[0],), dtype=nm.int32) cmesh = get_default_attr(cache, "cmesh", None) if cmesh is None: tt = time.clock() mesh = field.create_mesh(extra_nodes=False) cmesh = mesh.cmesh gels = create_geometry_elements() cmesh.set_local_entities(gels) cmesh.setup_entities() centroids = cmesh.get_centroids(cmesh.tdim) if field.gel.name != "3_8": normals0 = cmesh.get_facet_normals() normals1 = None else: normals0 = cmesh.get_facet_normals(0) normals1 = cmesh.get_facet_normals(1) output("cmesh setup: %f s" % (time.clock() - tt), verbose=verbose) else: centroids = cache.centroids normals0 = cache.normals0 normals1 = cache.normals1 kdtree = get_default_attr(cache, "kdtree", None) if kdtree is None: from scipy.spatial import cKDTree as KDTree tt = time.clock() kdtree = KDTree(cmesh.coors) 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) ics = nm.asarray(ics, dtype=nm.int32) ap = field.ap ps = ap.interp.gel.interp.poly_spaces["v"] mtx_i = ps.get_mtx_i() ac = nm.ascontiguousarray tt = time.clock() crc.find_ref_coors_convex( ref_coors, cells, status, ac(coors), cmesh, centroids, normals0, normals1, ics, ps.geometry.coors, ps.nodes, mtx_i, extrapolate, close_limit, 1e-15, 100, 1e-8, ) output("ref. coordinates: %f s" % (time.clock() - tt), verbose=verbose) else: cells = cache.cells status = cache.status return ref_coors, cells, status
def get_evaluate_cache(self, cache=None, share_geometry=False, verbose=False): """ Get the evaluate cache for :func:`Variable.evaluate_at() <sfepy.discrete.variables.Variable.evaluate_at()>`. Parameters ---------- cache : Struct instance, optional Optionally, use the provided instance to store the cache data. share_geometry : bool Set to True to indicate that all the evaluations will work on the same region. Certain data are then computed only for the first probe and cached. verbose : bool If False, reduce verbosity. Returns ------- cache : Struct instance The evaluate cache. """ import time try: from scipy.spatial import cKDTree as KDTree except ImportError: from scipy.spatial import KDTree from sfepy.discrete.fem.geometry_element import create_geometry_elements if cache is None: cache = Struct(name='evaluate_cache') tt = time.clock() if (cache.get('cmesh', None) is None) or not share_geometry: mesh = self.create_mesh(extra_nodes=False) cache.cmesh = cmesh = mesh.cmesh gels = create_geometry_elements() cmesh.set_local_entities(gels) cmesh.setup_entities() cache.centroids = cmesh.get_centroids(cmesh.tdim) if self.gel.name != '3_8': cache.normals0 = cmesh.get_facet_normals() cache.normals1 = None else: cache.normals0 = cmesh.get_facet_normals(0) cache.normals1 = cmesh.get_facet_normals(1) output('cmesh setup: %f s' % (time.clock() - tt), verbose=verbose) tt = time.clock() if (cache.get('kdtree', None) is None) or not share_geometry: cache.kdtree = KDTree(cmesh.coors) output('kdtree: %f s' % (time.clock() - tt), verbose=verbose) return cache
def get_ref_coors_convex(field, coors, close_limit=0.1, cache=None, verbose=False): """ 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. 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 and other data can be cached. 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 mesh 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, 4 is failure due to non-convergence of the Newton iteration in tensor product cells. Notes ----- Outline of the algorithm for finding xi such that X(xi) = P: 1. make inverse connectivity - for each vertex have cells it is in. 2. find the closest vertex V. 3. choose initial cell: i0 = first from cells incident to V. 4. while not P in C_i, change C_i towards P, check if P in new C_i. """ timer = Timer() ref_coors = get_default_attr(cache, 'ref_coors', None) if ref_coors is None: extrapolate = close_limit > 0.0 ref_coors = nm.empty_like(coors) cells = nm.empty((coors.shape[0], ), dtype=nm.int32) status = nm.empty((coors.shape[0], ), dtype=nm.int32) cmesh = get_default_attr(cache, 'cmesh', None) if cmesh is None: timer.start() mesh = field.create_mesh(extra_nodes=False) cmesh = mesh.cmesh gels = create_geometry_elements() cmesh.set_local_entities(gels) cmesh.setup_entities() centroids = cmesh.get_centroids(cmesh.tdim) if field.gel.name != '3_8': normals0 = cmesh.get_facet_normals() normals1 = None else: normals0 = cmesh.get_facet_normals(0) normals1 = cmesh.get_facet_normals(1) output('cmesh setup: %f s' % timer.stop(), verbose=verbose) else: centroids = cache.centroids normals0 = cache.normals0 normals1 = cache.normals1 kdtree = get_default_attr(cache, 'kdtree', None) if kdtree is None: from scipy.spatial import cKDTree as KDTree timer.start() kdtree = KDTree(cmesh.coors) output('kdtree: %f s' % timer.stop(), verbose=verbose) timer.start() ics = kdtree.query(coors)[1] output('kdtree query: %f s' % timer.stop(), verbose=verbose) ics = nm.asarray(ics, dtype=nm.int32) coors = nm.ascontiguousarray(coors) ctx = field.create_basis_context() timer.start() crc.find_ref_coors_convex(ref_coors, cells, status, coors, cmesh, centroids, normals0, normals1, ics, extrapolate, 1e-15, close_limit, ctx) output('ref. coordinates: %f s' % timer.stop(), verbose=verbose) else: cells = cache.cells status = cache.status return ref_coors, cells, status
def test_cmesh_counts(self): from sfepy.discrete.fem import Mesh from sfepy.discrete.fem.geometry_element import create_geometry_elements from sfepy.discrete.common.extmods.cmesh import CMesh, get_cmem_usage gels = create_geometry_elements() ok = True for filename in self.filename_meshes: basename = os.path.basename(filename) enum, esizes = expected[basename] self.report('mesh: %s' % basename) mesh = Mesh.from_file(filename) cmesh = mesh.cmesh cmesh.set_local_entities(gels) cmesh.setup_entities() self.report('dim:', cmesh.dim) self.report('n_vertex: %d, n_edge: %d, n_face: %d, n_cell: %d' % tuple(cmesh.num)) _ok = (enum == cmesh.num).all() if not _ok: self.report('%s == %s failed!' % (enum, cmesh.num)) ok = ok and _ok dim = cmesh.dim for ir in range(dim + 1): for ic in range(dim + 1): cmesh.setup_connectivity(ir, ic) mem_usage1 = get_cmem_usage()[0] if (ir == dim) and (ic == 0): continue cmesh.free_connectivity(ir, ic) mem_usage2 = get_cmem_usage()[0] cmesh.setup_connectivity(ir, ic) mem_usage3 = get_cmem_usage()[0] conn = cmesh.get_conn(ir, ic) self.report('(%d, %d) : (%d, %d)' % (ir, ic, conn.num, conn.n_incident)) sizes = nm.array([conn.num, conn.n_incident]) _ok = (esizes[ir, ic] == sizes).all() if not _ok: self.report('%s == %s failed!' % (esizes, sizes)) ok = ok and _ok _ok1 = mem_usage3 == mem_usage1 _ok2 = mem_usage3 > mem_usage2 if not (_ok1 and _ok2): self.report('unexpected memory usage! (%s)' % (mem_usage1, mem_usage2, mem_usage3)) ok = ok and (_ok1 and _ok2) return ok