Exemple #1
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
Exemple #2
0
    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
Exemple #3
0
    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
Exemple #4
0
    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)
Exemple #5
0
    def detect_orientation(self, orientation):
        # 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()) & uniq_types)

        # 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, orient_types)
        l = len(list(self.subdomain.grid.basis[0])) - 1
        for vec in self.subdomain.grid.basis:
            # FIXME: we currently only process the primary directions
            if vec.dot(vec) != 1:
                continue
            shifted_map = self._type_map
            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) & (orientation == 0)
            orientation[idx] = self.subdomain.grid.vec_to_dir(list(vec))
Exemple #6
0
    def _draw_geometry(self, tg_buffer, width, height, block):
        geo_map = np.zeros((height, width), dtype=np.uint8)
        geo_map.reshape(width * height)[:] = block.vis_geo_buffer[:]

        geo_map = np.rot90(geo_map, 3)
        dry_types = geo_map.dtype.type(node_type.get_dry_node_type_ids())
        tg_buffer[util.in_anyd_fast(geo_map, dry_types)] = self._color_wall
Exemple #7
0
    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))
Exemple #8
0
    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))
Exemple #9
0
 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)
Exemple #10
0
    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
Exemple #11
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
Exemple #12
0
    def _postprocess_nodes(self):
        uniq_types = set(np.unique(self._type_map_base))
        dry_types = list(set(nt.get_dry_node_type_ids()) & uniq_types)
        dry_types = self._type_map.dtype.type(dry_types)

        # Find nodes which are walls themselves and are completely surrounded by
        # walls.  These nodes are marked as unused, as they do not contribute to
        # the dynamics of the fluid in any way.
        cnt = np.zeros_like(self._type_map_base).astype(np.uint32)
        for i, vec in enumerate(self.grid.basis):
            a = np.roll(self._type_map_base, int(-vec[0]), axis=1)
            a = np.roll(a, int(-vec[1]), axis=0)
            cnt[util.in_anyd_fast(a, dry_types)] += 1

        self._type_map_base[(cnt == self.grid.Q)] = nt._NTUnused.id
Exemple #13
0
    def _postprocess_nodes(self):
        uniq_types = set(np.unique(self._type_map.base))
        dry_types = list(set(nt.get_dry_node_type_ids()) & uniq_types)
        dry_types = self._type_map.dtype.type(dry_types)

        # Find nodes which are walls themselves and are completely surrounded by
        # walls.  These nodes are marked as unused, as they do not contribute to
        # the dynamics of the fluid in any way.
        cnt = np.zeros_like(self._type_map.base).astype(np.uint32)
        for i, vec in enumerate(self.grid.basis):
            a = np.roll(self._type_map.base, int(-vec[0]), axis=1)
            a = np.roll(a, int(-vec[1]), axis=0)
            cnt[util.in_anyd_fast(a, dry_types)] += 1

        self._type_map.base[(cnt == self.grid.Q)] = nt._NTUnused.id
Exemple #14
0
    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
Exemple #15
0
    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
Exemple #16
0
    def _postprocess_nodes(self):
        uniq_types = set(np.unique(self._type_map.base))
        dry_types = list(set(nt.get_dry_node_type_ids()) & uniq_types)
        dry_types = self._type_map.dtype.type(dry_types)

        # Find nodes which are walls themselves and are completely surrounded by
        # walls. These nodes are marked as unused, as they do not contribute to
        # the dynamics of the fluid in any way.
        dry_map = util.in_anyd_fast(self._type_map.base,
                                    dry_types).astype(np.uint8)
        neighbors = np.zeros((3, 3, 3), dtype=np.uint8)
        neighbors[1,1,1] = 1
        for ei in self.grid.basis:
            neighbors[1 + ei[2], 1 + ei[1], 1 + ei[0]] = 1

        where = (filters.convolve(dry_map, neighbors, mode='wrap') == self.grid.Q)
        self._type_map.base[where] = nt._NTUnused.id
Exemple #17
0
    def _postprocess_nodes(self):
        uniq_types = set(np.unique(self._type_map_base))
        dry_types = list(set(nt.get_dry_node_type_ids()) & uniq_types)
        dry_types = self._type_map.dtype.type(dry_types)

        # Find nodes which are walls themselves and are completely surrounded by
        # walls. These nodes are marked as unused, as they do not contribute to
        # the dynamics of the fluid in any way.
        dry_map = util.in_anyd_fast(self._type_map_base,
                                    dry_types).astype(np.uint8)
        neighbors = np.zeros((3, 3, 3), dtype=np.uint8)
        neighbors[1, 1, 1] = 1
        for ei in self.grid.basis:
            neighbors[1 + ei[2], 1 + ei[1], 1 + ei[0]] = 1

        where = (filters.convolve(dry_map, neighbors,
                                  mode='wrap') == self.grid.Q)
        self._type_map_base[where] = nt._NTUnused.id
Exemple #18
0
    def detect_orientation(self, orientation):
        # 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()) & uniq_types)

        # 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, orient_types)
        l = len(list(self.subdomain.grid.basis[0])) - 1
        for vec in self.subdomain.grid.basis:
            # FIXME: we currently only process the primary directions
            if vec.dot(vec) != 1:
                continue
            shifted_map = self._type_map
            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) & (orientation == 0)
            orientation[idx] = self.subdomain.grid.vec_to_dir(list(vec))
Exemple #19
0
    def test_inanyd_fast(self):
        a = np.random.random_integers(0, 20, (128, 128))
        b = np.uint32([1, 4, 6, 10, 19])

        np.testing.assert_array_equal(
                util.in_anyd(a, b), util.in_anyd_fast(a, b))
Exemple #20
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)
Exemple #21
0
    def test_inanyd_fast(self):
        a = np.random.random_integers(0, 20, (128, 128))
        b = np.uint32([1, 4, 6, 10, 19])

        np.testing.assert_array_equal(util.in_anyd(a, b),
                                      util.in_anyd_fast(a, b))
Exemple #22
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)
Exemple #23
0
 def _draw_geometry(self, tg_buffer, width, height, subdomain):
     geo_map = np.rot90(self._get_geo_map(width, height, subdomain), 3)
     dry_types = geo_map.dtype.type(node_type.get_dry_node_type_ids())
     tg_buffer[util.in_anyd_fast(geo_map, dry_types)] = self._color_wall
Exemple #24
0
 def _draw_geometry(self, tg_buffer, width, height, block):
     geo_map = np.rot90(self._get_geo_map(width, height, block), 3)
     dry_types = geo_map.dtype.type(node_type.get_dry_node_type_ids())
     tg_buffer[util.in_anyd_fast(geo_map, dry_types)] = self._color_wall