def test_mixedmap_cache_hit(self, base_map, base_map2): mm = op2.MixedMap([base_map, base_map2]) mm2 = op2.MixedMap([base_map, base_map2]) assert mm is mm2 assert not mm != mm2 assert mm == mm2
def test_mixedmap_cache_miss(self, base_map, base_map2): ms = op2.MixedMap([base_map, base_map2]) ms2 = op2.MixedMap([base_map2, base_map]) assert ms is not ms2 assert ms != ms2 assert not ms == ms2 ms3 = op2.MixedMap([base_map, base_map2]) assert ms is ms3 assert not ms != ms3 assert ms == ms3
def exterior_facet_boundary_node_map(self): '''The :class:`pyop2.MixedMap` from exterior facets to the nodes on those facets. Note that this differs from :meth:`exterior_facet_node_map` in that only surface nodes are referenced, not all nodes in cells touching the surface.''' return op2.MixedMap(s.exterior_facet_boundary_node_map for s in self._spaces)
def coarse_to_fine_node_map(coarse, fine): if len(coarse) > 1: assert len(fine) == len(coarse) return op2.MixedMap( coarse_to_fine_node_map(c, f) for c, f in zip(coarse, fine)) mesh = coarse.mesh() assert hasattr(mesh, "_shared_data_cache") if not (coarse.ufl_element() == fine.ufl_element()): raise ValueError("Can't transfer between different spaces") ch, level = get_level(mesh) fh, fine_level = get_level(fine.mesh()) if ch is not fh: raise ValueError("Can't map between different hierarchies") refinements_per_level = ch.refinements_per_level if refinements_per_level * level + 1 != refinements_per_level * fine_level: raise ValueError("Can't map between level %s and level %s" % (level, fine_level)) c2f, vperm = ch._cells_vperm[int(level * refinements_per_level)] key = entity_dofs_key(coarse.finat_element.entity_dofs()) + (level, ) cache = mesh._shared_data_cache["hierarchy_cell_node_map"] try: return cache[key] except KeyError: from .impl import create_cell_node_map map_vals, offset = create_cell_node_map(coarse, fine, c2f, vperm) return cache.setdefault( key, op2.Map(mesh.cell_set, fine.node_set, map_vals.shape[1], map_vals, offset=offset))
def cell_node_map(self, level): """A :class:`pyop2.MixedMap` from cells on a coarse mesh to the corresponding degrees of freedom on a the fine mesh below it. :arg level: the coarse level the map should be from. """ return op2.MixedMap(s.cell_node_map(level) for s in self.split())
def cell_node_map(self): r"""A :class:`pyop2.MixedMap` from the :attr:`Mesh.cell_set` of the underlying mesh to the :attr:`node_set` of this :class:`MixedFunctionSpace`. This is composed of the :attr:`FunctionSpace.cell_node_map`\s of the underlying :class:`FunctionSpace`\s of which this :class:`MixedFunctionSpace` is composed.""" return op2.MixedMap(s.cell_node_map() for s in self._spaces)
def coarse_cell_to_fine_node_map(Vc, Vf): if len(Vf) > 1: assert len(Vf) == len(Vc) return op2.MixedMap( coarse_cell_to_fine_node_map(f, c) for f, c in zip(Vf, Vc)) mesh = Vc.mesh() assert hasattr(mesh, "_shared_data_cache") hierarchyf, levelf = get_level(Vf.ufl_domain()) hierarchyc, levelc = get_level(Vc.ufl_domain()) if hierarchyc != hierarchyf: raise ValueError("Can't map across hierarchies") hierarchy = hierarchyf increment = Fraction(1, hierarchyf.refinements_per_level) if levelc + increment != levelf: raise ValueError("Can't map between level %s and level %s" % (levelc, levelf)) key = (entity_dofs_key(Vf.finat_element.entity_dofs()) + (levelc, levelf)) cache = mesh._shared_data_cache["hierarchy_coarse_cell_to_fine_node_map"] try: return cache[key] except KeyError: assert Vc.extruded == Vf.extruded if Vc.mesh().variable_layers or Vf.mesh().variable_layers: raise NotImplementedError( "Not implemented for variable layers, sorry") if Vc.extruded and Vc.mesh().layers != Vf.mesh().layers: raise ValueError( "Coarse and fine meshes must have same number of layers") coarse_to_fine = hierarchy.coarse_to_fine_cells[levelc] _, ncell = coarse_to_fine.shape iterset = Vc.mesh().cell_set arity = Vf.finat_element.space_dimension() * ncell coarse_to_fine_nodes = numpy.full((iterset.total_size, arity), -1, dtype=IntType) values = Vf.cell_node_map().values[coarse_to_fine, :].reshape( iterset.size, arity) coarse_to_fine_nodes[:Vc.mesh().cell_set.size, :] = values offset = Vf.offset if offset is not None: offset = numpy.tile(offset, ncell) return cache.setdefault( key, op2.Map(iterset, Vf.node_set, arity=arity, values=coarse_to_fine_nodes, offset=offset))
def test_sparsity_cache_hit(self, base_set, base_map): dsets = (base_set, base_set) maps = (base_map, base_map) sp = op2.Sparsity(dsets, maps) sp2 = op2.Sparsity(dsets, maps) assert sp is sp2 assert not sp != sp2 assert sp == sp2 dsets = op2.MixedSet([base_set, base_set]) maps = op2.MixedMap([base_map, base_map]) sp = op2.Sparsity(dsets, maps) dsets2 = op2.MixedSet([base_set, base_set]) maps2 = op2.MixedMap([base_map, base_map]) sp2 = op2.Sparsity(dsets2, maps2) assert sp is sp2 assert not sp != sp2 assert sp == sp2
def exterior_facet_node_map(self, bcs=None): """Return the :class:`pyop2.Map` from exterior facets to function space nodes. If present, bcs must be a tuple of :class:`.DirichletBC`\s. In this case, the facet_node_map will return negative node indices where boundary conditions should be applied. Where a PETSc matrix is employed, this will cause the corresponding values to be discarded during matrix assembly.""" # FIXME: these want caching of sorts bc_list = [[] for _ in self] if bcs: for bc in bcs: bc_list[bc.function_space().index].append(bc) return op2.MixedMap(s.exterior_facet_node_map(bc_list[i]) for i, s in enumerate(self._spaces))
def cell_node_map(self, bcs=None): """A :class:`pyop2.MixedMap` from the :attr:`Mesh.cell_set` of the underlying mesh to the :attr:`node_set` of this :class:`MixedFunctionSpace`. This is composed of the :attr:`FunctionSpace.cell_node_map`\s of the underlying :class:`FunctionSpace`\s of which this :class:`MixedFunctionSpace` is composed.""" # FIXME: these want caching of sorts bc_list = [[] for _ in self] if bcs: for bc in bcs: bc_list[bc.function_space().index].append(bc) return op2.MixedMap(s.cell_node_map(bc_list[i]) for i, s in enumerate(self._spaces))
def coarse_node_to_fine_node_map(Vc, Vf): if len(Vf) > 1: assert len(Vf) == len(Vc) return op2.MixedMap( coarse_node_to_fine_node_map(f, c) for f, c in zip(Vf, Vc)) mesh = Vc.mesh() assert hasattr(mesh, "_shared_data_cache") hierarchyf, levelf = get_level(Vf.ufl_domain()) hierarchyc, levelc = get_level(Vc.ufl_domain()) if hierarchyc != hierarchyf: raise ValueError("Can't map across hierarchies") hierarchy = hierarchyf increment = Fraction(1, hierarchyf.refinements_per_level) if levelc + increment != levelf: raise ValueError("Can't map between level %s and level %s" % (levelc, levelf)) key = (entity_dofs_key(Vc.finat_element.entity_dofs()) + entity_dofs_key(Vf.finat_element.entity_dofs()) + (levelc, levelf)) cache = mesh._shared_data_cache["hierarchy_coarse_node_to_fine_node_map"] try: return cache[key] except KeyError: assert Vc.extruded == Vf.extruded if Vc.mesh().variable_layers or Vf.mesh().variable_layers: raise NotImplementedError( "Not implemented for variable layers, sorry") if Vc.extruded and not ((Vf.mesh().layers - 1) / (Vc.mesh().layers - 1)).is_integer(): raise ValueError( "Coarse and fine meshes must have an integer ratio of layers") coarse_to_fine = hierarchy.coarse_to_fine_cells[levelc] coarse_to_fine_nodes = impl.coarse_to_fine_nodes( Vc, Vf, coarse_to_fine) return cache.setdefault( key, op2.Map(Vc.node_set, Vf.node_set, coarse_to_fine_nodes.shape[1], values=coarse_to_fine_nodes))
def fine_node_to_coarse_node_map(Vf, Vc): if len(Vf) > 1: assert len(Vf) == len(Vc) return op2.MixedMap( fine_node_to_coarse_node_map(f, c) for f, c in zip(Vf, Vc)) mesh = Vf.mesh() assert hasattr(mesh, "_shared_data_cache") hierarchyf, levelf = get_level(Vf.ufl_domain()) hierarchyc, levelc = get_level(Vc.ufl_domain()) if hierarchyc != hierarchyf: raise ValueError("Can't map across hierarchies") hierarchy = hierarchyf if levelc + 1 != levelf: raise ValueError("Can't map between level %s and level %s" % (levelc, levelf)) key = (entity_dofs_key(Vc.finat_element.entity_dofs()) + entity_dofs_key(Vf.finat_element.entity_dofs()) + (levelc, levelf)) cache = mesh._shared_data_cache["hierarchy_fine_node_to_coarse_node_map"] try: return cache[key] except KeyError: assert Vc.extruded == Vf.extruded if Vc.mesh().variable_layers or Vf.mesh().variable_layers: raise NotImplementedError( "Not implemented for variable layers, sorry") if Vc.extruded and Vc.mesh().layers != Vf.mesh().layers: raise ValueError( "Coarse and fine meshes must have same number of layers") fine_to_coarse = hierarchy.fine_to_coarse_cells[levelc + 1] fine_to_coarse_nodes = impl.fine_to_coarse_nodes( Vf, Vc, fine_to_coarse) return cache.setdefault( key, op2.Map(Vf.node_set, Vc.node_set, fine_to_coarse_nodes.shape[1], values=fine_to_coarse_nodes))
def test_sparsity_cache_miss(self, base_set, base_set2, base_map, base_map2): dsets = (base_set, base_set) maps = (base_map, base_map) sp = op2.Sparsity(dsets, maps, iteration_regions=[(op2.ALL, )]) dsets2 = op2.MixedSet([base_set, base_set]) maps2 = op2.MixedMap([base_map, base_map]) sp2 = op2.Sparsity(dsets2, maps2, iteration_regions=[(op2.ALL, )]) assert sp is not sp2 assert sp != sp2 assert not sp == sp2 dsets2 = (base_set, base_set2) maps2 = (base_map, base_map2) sp2 = op2.Sparsity(dsets2, maps2, iteration_regions=[(op2.ALL, )]) assert sp is not sp2 assert sp != sp2 assert not sp == sp2
def test_sparsity_cache_miss(self, base_set, base_set2, base_map, base_map2): dsets = (base_set, base_set) maps = (base_map, base_map) sp = op2.Sparsity(dsets, maps) dsets2 = op2.MixedSet([base_set, base_set]) maps2 = op2.MixedMap([base_map, base_map]) maps2 = op2.DecoratedMap(maps2, [op2.ALL]) sp2 = op2.Sparsity(dsets2, maps2) assert sp is not sp2 assert sp != sp2 assert not sp == sp2 dsets2 = (base_set, base_set2) maps2 = (base_map, base_map2) sp2 = op2.Sparsity(dsets2, maps2) assert sp is not sp2 assert sp != sp2 assert not sp == sp2
def mmap(mset): elem, node = mset return op2.MixedMap((op2.Map(elem, elem, 1, [0, 1, 2]), op2.Map(elem, node, 2, [0, 1, 1, 2, 2, 3])))
def mmap(iterset2indset, iterset2unitset): return op2.MixedMap((iterset2indset, iterset2unitset))
def exterior_facet_node_map(self): r"""Return the :class:`pyop2.Map` from exterior facets to function space nodes.""" return op2.MixedMap(s.exterior_facet_node_map() for s in self)