def _fluid_map_base(self): assert not self._type_map_encoded uniq_types = set(np.unique(self._type_map_base)) wet_types = list(set(nt.get_wet_node_type_ids()) & uniq_types) wet_types = self._type_map.dtype.type(wet_types) return util.in_anyd_fast(self._type_map_base, wet_types)
def fluid_map(self): """Returns a boolean array indicating which nodes are "wet" ( represent fluid and have valid macroscopic fields).""" fm = self.visualization_map() uniq_types = set(np.unique(fm)) wet_types = list(set(nt.get_wet_node_type_ids()) & uniq_types) wet_types = self._type_map.dtype.type(wet_types) return util.in_anyd_fast(fm, wet_types)
def _fluid_map_base(self, wet=True): assert not self._type_map_encoded if wet: uniq_types = set(np.unique(self._type_map_base)) wet_types = list(set(nt.get_wet_node_type_ids()) & uniq_types) wet_types = self._type_map.dtype.type(wet_types) return util.in_anyd_fast(self._type_map_base, wet_types) else: return self._type_map_base == 0
def fluid_map(self, wet=True): """Returns a boolean array indicating which nodes are "wet" ( represent fluid and have valid macroscopic fields).""" fm = self.visualization_map() if wet: uniq_types = set(np.unique(fm)) wet_types = list(set(nt.get_wet_node_type_ids()) & uniq_types) wet_types = self._type_map.dtype.type(wet_types) return util.in_anyd_fast(fm, wet_types) else: return fm == 0
def encode(self): assert self._type_map is not None orientation = np.zeros_like(self._type_map) cnt = np.zeros_like(self._type_map) # 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_orientation_node_type_ids()) & uniq_types) # 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) # Check if there are any node types that need the orientation vector. needs_orientation = False for nt_code in uniq_types: if nt._NODE_TYPES[nt_code].needs_orientation: needs_orientation = True break if needs_orientation: for i, vec in enumerate(self.subdomain.grid.basis): l = len(list(vec)) - 1 shifted_map = self._type_map for j, shift in enumerate(vec): shifted_map = np.roll(shifted_map, int(-shift), axis=l-j) cnt[util.in_anyd_fast(shifted_map, dry_types)] += 1 # FIXME: we're currently only processing the primary directions # here if vec.dot(vec) == 1: idx = np.logical_and( util.in_anyd_fast(self._type_map, orient_types), shifted_map == 0) orientation[idx] = self.subdomain.grid.vec_to_dir(list(vec)) # Remap type IDs. max_type_code = max(self._type_id_remap.keys()) type_choice_map = np.zeros(max_type_code + 1, dtype=np.uint32) for orig_code, new_code in self._type_id_remap.iteritems(): type_choice_map[orig_code] = new_code self._type_map[:] = self._encode_node(orientation, self._encoded_param_map, np.choose(np.int32(self._type_map), type_choice_map), self._scratch_map) # Drop the reference to the map array. self._type_map = None
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
def _fluid_map(self, wet=True, base=True, allow_unused=None): assert not self._type_map_encoded if base: src = self._type_map_base else: src = self._type_map if wet: uniq_types = set(np.unique(src)) wet_types = list(set(nt.get_wet_node_type_ids(allow_unused=allow_unused)) & uniq_types) wet_types = self._type_map.dtype.type(wet_types) return util.in_anyd_fast(src, wet_types) else: return src == 0
def fluid_map(self): fm = self.visualization_map() uniq_types = set(np.unique(fm)) wet_types = list(set(nt.get_wet_node_type_ids()) & uniq_types) wet_types = self._type_map.dtype.type(wet_types) return util.in_anyd_fast(fm, wet_types)