def detect_orientation(self, use_tags): # Limit dry and wet types to these that are actually used in the simulation. uniq_types = set(np.unique(self._type_map.base)) dry_types = list(set(nt.get_dry_node_type_ids()) & uniq_types) orient_types = list( (set(nt.get_orientation_node_type_ids()) - set(nt.get_link_tag_node_type_ids() if use_tags else [])) & uniq_types) if not orient_types: return # Convert to a numpy array. dry_types = self._type_map.dtype.type(dry_types) orient_types = self._type_map.dtype.type(orient_types) orient_map = util.in_anyd_fast(self._type_map_base, orient_types) l = self.grid.dim - 1 for vec in self.grid.basis: # Orientaion only handles the primary directions. More complex # setups need link tagging. if vec.dot(vec) != 1: continue shifted_map = self._type_map_base for j, shift in enumerate(vec): if shift == 0: continue shifted_map = np.roll(shifted_map, int(-shift), axis=l - j) # Only set orientation where it's not already defined (=0). idx = orient_map & (shifted_map == 0) & (self._orientation_base == 0) self._orientation_base[idx] = self.grid.vec_to_dir(list(vec))
def detect_orientation(self, use_tags): # Limit dry and wet types to these that are actually used in the simulation. uniq_types = set(np.unique(self._type_map.base)) dry_types = list(set(nt.get_dry_node_type_ids()) & uniq_types) orient_types = list((set(nt.get_orientation_node_type_ids()) - set(nt.get_link_tag_node_type_ids() if use_tags else [])) & uniq_types) if not orient_types: return # Convert to a numpy array. dry_types = self._type_map.dtype.type(dry_types) orient_types = self._type_map.dtype.type(orient_types) orient_map = util.in_anyd_fast(self._type_map_base, orient_types) l = self.grid.dim - 1 for vec in self.grid.basis: # Orientaion only handles the primary directions. More complex # setups need link tagging. if vec.dot(vec) != 1: continue shifted_map = self._type_map_base for j, shift in enumerate(vec): if shift == 0: continue shifted_map = np.roll(shifted_map, int(-shift), axis=l-j) # Only set orientation where it's not already defined (=0). idx = orient_map & (shifted_map == 0) & (self._orientation_base == 0) self._orientation_base[idx] = self.grid.vec_to_dir(list(vec))
def tag_directions(self): """Creates direction tags for nodes that support it. Direction tags are a way of summarizing which distributions at a node will be undefined after streaming. :rvalue: True if there are any nodes supporting tagging, False otherwise """ # For directions which are not periodic, keep the ghost nodes to avoid # detecting some missing directions. ngs = list(self.spec._nonghost_slice) for i, periodic in enumerate(reversed(self.spec._periodicity)): if not periodic: ngs[i] = slice(None) ngs = tuple(ngs) # Limit dry and wet types to these that are actually used in the simulation. uniq_types = set(np.unique(self._type_map.base)) dry_types = list(set(nt.get_dry_node_type_ids()) & uniq_types) wet_types = list(set(nt.get_wet_node_type_ids()) & uniq_types) orient_types = list(set(nt.get_link_tag_node_type_ids()) & uniq_types) if not orient_types: return False # Convert to a numpy array. dry_types = self._type_map.dtype.type(dry_types) wet_types = self._type_map.dtype.type(wet_types) orient_types = self._type_map.dtype.type(orient_types) # Only do direction tagging for nodes that do not have # orientation/direction already. orient_map = ( util.in_anyd_fast(self._type_map_base[ngs], orient_types) & (self._orientation_base[ngs] == 0)) l = self.grid.dim - 1 # Skip the stationary vector. for i, vec in enumerate(self.grid.basis[1:]): shifted_map = self._type_map_base[ngs] for j, shift in enumerate(vec): if shift == 0: continue shifted_map = np.roll(shifted_map, int(-shift), axis=l-j) # If the given distribution points to a fluid node, tag it as # active. idx = orient_map & util.in_anyd_fast(shifted_map, wet_types) self._orientation_base[ngs][idx] |= (1 << i) self.config.logger.debug('... link tagging done.') return True
def tag_directions(self): """Creates direction tags for nodes that support it. Direction tags are a way of summarizing which distributions at a node will be undefined after streaming. :rvalue: True if there are any nodes supporting tagging, False otherwise """ # For directions which are not periodic, keep the ghost nodes to avoid # detecting some missing directions. ngs = list(self.spec._nonghost_slice) for i, periodic in enumerate(reversed(self.spec._periodicity)): if not periodic: ngs[i] = slice(None) # Limit dry and wet types to these that are actually used in the simulation. uniq_types = set(np.unique(self._type_map.base)) dry_types = list(set(nt.get_dry_node_type_ids()) & uniq_types) wet_types = list(set(nt.get_wet_node_type_ids()) & uniq_types) orient_types = list(set(nt.get_link_tag_node_type_ids()) & uniq_types) if not orient_types: return False # Convert to a numpy array. dry_types = self._type_map.dtype.type(dry_types) wet_types = self._type_map.dtype.type(wet_types) orient_types = self._type_map.dtype.type(orient_types) # Only do direction tagging for nodes that do not have # orientation/direction already. orient_map = ( util.in_anyd_fast(self._type_map_base[ngs], orient_types) & (self._orientation_base[ngs] == 0)) l = self.grid.dim - 1 # Skip the stationary vector. for i, vec in enumerate(self.grid.basis[1:]): shifted_map = self._type_map_base[ngs] for j, shift in enumerate(vec): if shift == 0: continue shifted_map = np.roll(shifted_map, int(-shift), axis=l-j) # If the given distribution points to a fluid node, tag it as # active. idx = orient_map & util.in_anyd_fast(shifted_map, wet_types) self._orientation_base[ngs][idx] |= (1 << i) self.config.logger.debug('... link tagging done.') return True