Exemplo n.º 1
0
    def _verify_params(self, where, node_type):
        """Verifies that the node parameters are set correctly."""

        for name, param in node_type.params.iteritems():
            # Single number.
            if util.is_number(param):
                continue
            # Single vector.
            elif type(param) is tuple:
                for el in param:
                    if not util.is_number(el):
                        raise ValueError("Tuple elements have to be numbers.")
            # Field.  If more than a single number is needed per node, this
            # needs to be a numpy record array.  Use node_util.multifield()
            # to create this array easily.
            elif isinstance(param, np.ndarray):
                assert param.size == np.sum(where), ("Your array needs to "
                        "have exactly as many nodes as there are True values "
                        "in the 'where' array.  Use node_util.multifield() to "
                        "generate the array in an easy way.")
            elif isinstance(param, nt.DynamicValue):
                if param.has_symbols(sym.S.time):
                    self.config.time_dependence = True
                if param.has_symbols(sym.S.gx, sym.S.gy, sym.S.gz):
                    self.config.space_dependence = True
                continue
            else:
                raise ValueError("Unrecognized node param: {0} (type {1})".
                        format(name, type(param)))
Exemplo n.º 2
0
    def _verify_params(self, where, node_type):
        """Verifies that the node parameters are set correctly."""

        for name, param in node_type.params.items():
            # Single number.
            if util.is_number(param):
                continue
            # Single vector.
            elif type(param) is tuple:
                for el in param:
                    if not util.is_number(el):
                        raise ValueError("Tuple elements have to be numbers.")
            # Field.  If more than a single number is needed per node, this
            # needs to be a numpy record array.  Use node_util.multifield()
            # to create this array easily.
            elif isinstance(param, np.ndarray):
                assert param.size == np.sum(where), (
                    "Your array needs to "
                    "have exactly as many nodes as there are True values "
                    "in the 'where' array.  Use node_util.multifield() to "
                    "generate the array in an easy way.")
            elif isinstance(param, nt.DynamicValue):
                if param.has_symbols(sym.S.time) or list(
                        zip(param.get_timeseries())):
                    self.config.time_dependence = True
                if param.has_symbols(sym.S.gx, sym.S.gy, sym.S.gz):
                    self.config.space_dependence = True
                continue
            elif isinstance(param, ImmutableDenseMatrix):
                continue
            else:
                raise ValueError(
                    "Unrecognized node param: {0} (type {1})".format(
                        name, type(param)))
Exemplo n.º 3
0
 def _get_structured_array(self, params):
     """Returns a structured numpy array with spatial data"""
     data = ()
     where = []
     for param in params:
         if isinstance(param, SpatialArray):
             data += (param._data, )
             if where != [] and where is not None:
                 assert where == param._where
             else:
                 where = param._where.copy()
             continue
         elif is_number(param):
             data += (param, )
             continue
         elif not isinstance(param, expr.Expr):
             continue
         for arg in param.args:
             if isinstance(arg, SpatialArray):
                 data += (arg._data, )
                 if where != [] and where is not None:
                     assert where == arg._where
                 else:
                     where = arg._where.copy()
                 break
         else:
             data += (1.0, )
     return multifield(data, where)
Exemplo n.º 4
0
    def prepare_encode(self, type_map, param_map, param_dict):
        """
        :param type_map: uint32 array of NodeType.ids
        :param param_map: array whose entries are keys in param_dict
        :param param_dict: maps entries from param_map to LBNodeType objects
        """
        uniq_types = list(np.unique(type_map))
        for nt_id in uniq_types:
            self._node_types.add(nt._NODE_TYPES[nt_id])

        # Initialize the node ID map used for remapping.
        for i, node_type in enumerate(uniq_types):
            self._type_id_remap[node_type] = i + 1

        self._bits_type = bit_len(len(uniq_types))
        self._type_map = type_map
        self._param_map = param_map
        self._param_dict = param_dict
        self._encoded_param_map = np.zeros_like(self._type_map)
        self._scratch_map = np.zeros_like(self._type_map)

        param_to_idx = dict()  # Maps entries in seen_params to ids.
        seen_params = set()
        param_items = 0
        self._symbol_map = {}  # Maps param indices to sympy expressions.

        # Refer to subdomain.Subdomain._verify_params for a list of allowed
        # ways of encoding nodes.
        for node_key, node_type in param_dict.iteritems():
            for param in node_type.params.itervalues():
                if util.is_number(param):
                    if param in seen_params:
                        idx = param_to_idx[param]
                    else:
                        seen_params.add(param)
                        self._geo_params.append(param)
                        idx = param_items
                        param_to_idx[param] = idx
                        param_items += 1
                    self._encoded_param_map[param_map == node_key] = idx
                elif type(param) is tuple:
                    if param in seen_params:
                        idx = param_to_idx[param]
                    else:
                        seen_params.add(param)
                        self._geo_params.extend(param)
                        idx = param_items
                        param_to_idx[param] = idx
                        param_items += len(param)
                    self._encoded_param_map[param_map == node_key] = idx
                # Param is a structured numpy array.
                elif isinstance(param, np.ndarray):
                    nodes_idx = np.argwhere(param_map == node_key)

                    uniques = np.unique(param)
                    uniques.flags.writeable = False

                    for value in uniques:
                        if value in seen_params:
                            idx = param_to_idx[value]
                        else:
                            seen_params.add(value)
                            self._geo_params.extend(value)
                            idx = param_items
                            param_to_idx[value] = idx
                            param_items += len(value)

                        idxs = nodes_idx[param == value]
                        if idxs.shape[1] == 3:
                            self._encoded_param_map[idxs[:,0], idxs[:,1],
                                    idxs[:,2]] = idx
                        elif idxs.shape[1] == 2:
                            self._encoded_param_map[idxs[:,0], idxs[:,1]] = idx
                        else:
                            assert False, 'Unsupported dimension: {0}'.format(
                                    idxs.shape[1])

        self._non_symbolic_idxs = param_items

        # Second pass: only process symbolic expressions here.
        for node_key, node_type in param_dict.iteritems():
            for param in node_type.params.itervalues():
                if isinstance(param, nt.DynamicValue):
                    if param in seen_params:
                        idx = param_to_idx[value]
                    else:
                        seen_params.add(param)
                        idx = param_items
                        self._symbol_map[idx] = param
                        param_to_idx[param] = idx
                        param_items += 1
                    self._encoded_param_map[param_map == node_key] = idx

        self._bits_param = bit_len(param_items)

        # Maps node type ID to base offset within the scratch space array.
        self._scratch_space_base = {}
        type_to_node_count = {}
        # Generate unique (within node type) scratch space ids.
        for node_type in self._node_types:
            if node_type.scratch_space_size(self.dim) <= 0:
                continue

            def _selector(idx_list):
                return [slice(i, i+1) for i in idx_list]

            idx = np.argwhere(self._type_map == node_type.id)
            num_nodes = idx.shape[0]
            type_to_node_count[node_type.id] = num_nodes

            for i in xrange(num_nodes):
               self._scratch_map[_selector(idx[i,:])] = i

            self._scratch_space_base[node_type.id] = self.scratch_space_size

            # Accumulate size requirements of specific types into a global
            # size value for the whole scratch buffer.
            self.scratch_space_size += num_nodes * node_type.scratch_space_size(self.dim)

        if type_to_node_count:
            self._bits_scratch = bit_len(max(type_to_node_count.itervalues()))
        else:
            self._bits_scratch = 0
Exemplo n.º 5
0
    def prepare_encode(self, type_map, param_map, param_dict, orientation,
                       have_link_tags):
        """
        :param type_map: uint32 array of NodeType.ids
        :param param_map: array whose entries are keys in param_dict
        :param param_dict: maps entries from param_map to LBNodeType objects
        """
        uniq_types = list(np.unique(type_map))
        for nt_id in uniq_types:
            self._node_types.add(nt._NODE_TYPES[nt_id])

        # Initialize the node ID map used for remapping.
        for i, node_type in enumerate(uniq_types):
            self._type_id_remap[node_type] = i + 1

        self._bits_type = bit_len(len(uniq_types))
        self._type_map = type_map
        self._param_map = param_map
        self._param_dict = param_dict
        self._encoded_param_map = np.zeros_like(self._type_map)
        self._scratch_map = np.zeros_like(self._type_map)

        param_to_idx = dict()  # Maps entries in seen_params to ids.
        seen_params = set()
        param_items = 0

        # Refer to subdomain.Subdomain._verify_params for a list of allowed
        # ways of encoding nodes.
        for node_key, node_type in param_dict.iteritems():
            for param in node_type.params.itervalues():
                if util.is_number(param):
                    if param in seen_params:
                        idx = param_to_idx[param]
                    else:
                        seen_params.add(param)
                        self._geo_params.append(param)
                        idx = param_items
                        param_to_idx[param] = idx
                        param_items += 1
                    self._encoded_param_map[param_map == node_key] = idx
                elif type(param) is tuple:
                    if param in seen_params:
                        idx = param_to_idx[param]
                    else:
                        seen_params.add(param)
                        self._geo_params.extend(param)
                        idx = param_items
                        param_to_idx[param] = idx
                        param_items += len(param)
                    self._encoded_param_map[param_map == node_key] = idx
                # Param is a structured numpy array.
                elif isinstance(param, np.ndarray):
                    nodes_idx = np.argwhere(param_map == node_key)

                    uniques = np.unique(param)
                    uniques.flags.writeable = False

                    for value in uniques:
                        if value in seen_params:
                            idx = param_to_idx[value]
                        else:
                            seen_params.add(value)
                            self._geo_params.extend(value)
                            idx = param_items
                            param_to_idx[value] = idx
                            param_items += len(value)

                        idxs = nodes_idx[param == value]
                        if idxs.shape[1] == 3:
                            self._encoded_param_map[idxs[:,0], idxs[:,1],
                                                    idxs[:,2]] = idx
                        elif idxs.shape[1] == 2:
                            self._encoded_param_map[idxs[:,0], idxs[:,1]] = idx
                        else:
                            assert False, 'Unsupported dimension: {0}'.format(
                                    idxs.shape[1])

        self._non_symbolic_idxs = param_items
        self._symbol_map = {}  # Maps param indices to sympy expressions.

        # Maps timeseries data ID to offset in self._timeseries_data.
        timeseries_offset_map = {}
        timeseries_offset = 0

        # TODO(michalj): Verify that the type of the symbolic expression matches
        # that of the boundary condition (vector vs scalar, etc).
        # Second pass: only process symbolic expressions here.

        for node_key, node_type in param_dict.iteritems():
            for param in node_type.params.itervalues():
                if isinstance(param, nt.DynamicValue):
                    if param in seen_params:
                        idx = param_to_idx[value]
                    else:
                        seen_params.add(param)
                        idx = param_items
                        self._symbol_map[idx] = param
                        param_to_idx[param] = idx
                        param_items += 1

                        for ts in param.get_timeseries():
                            dh = ts.data_hash()
                            if dh in timeseries_offset_map:
                                ts._offset = timeseries_offset_map[dh]
                            else:
                                ts._offset = timeseries_offset
                                timeseries_offset_map[dh] = ts._offset
                                timeseries_offset += ts._data.size
                                self._timeseries_data.extend(ts._data)

                    self._encoded_param_map[param_map == node_key] = idx

        self._bits_param = bit_len(param_items)

        # Maps node type ID to base offset within the scratch space array.
        self._scratch_space_base = {}
        type_to_node_count = {}
        # Generate unique (within node type) scratch space ids.
        for node_type in self._node_types:
            if node_type.scratch_space_size(self.dim) <= 0:
                continue

            def _selector(idx_list):
                return [slice(i, i+1) for i in idx_list]

            idx = np.argwhere(self._type_map == node_type.id)
            num_nodes = idx.shape[0]
            type_to_node_count[node_type.id] = num_nodes

            for i in xrange(num_nodes):
               self._scratch_map[_selector(idx[i,:])] = i

            self._scratch_space_base[node_type.id] = self.scratch_space_size

            # Accumulate size requirements of specific types into a global
            # size value for the whole scratch buffer.
            self.scratch_space_size += num_nodes * node_type.scratch_space_size(self.dim)

        if type_to_node_count:
            self._bits_scratch = bit_len(max(type_to_node_count.itervalues()))
        else:
            self._bits_scratch = 0

        self._have_link_tags = have_link_tags
        if have_link_tags:
            # TODO: Actually drop these bits to save space in the node code.
            # It would be nice to use reduce here instead, but
            # bitwise_and.identity = 1 makes it impossible to use it.
            self._unused_tag_bits = int(np.bitwise_and.accumulate(
                orientation[orientation > 0])[-1])
Exemplo n.º 6
0
    def prepare_encode(self, type_map, param_map, param_dict, orientation,
                       have_link_tags):
        """
        :param type_map: uint32 array of NodeType.ids
        :param param_map: array whose entries are keys in param_dict
        :param param_dict: maps entries from param_map to LBNodeType objects
        """
        uniq_types = list(np.unique(type_map))
        for nt_id in uniq_types:
            self._node_types.add(nt._NODE_TYPES[nt_id])

        # Initialize the node ID map used for remapping.
        for i, node_type in enumerate(uniq_types):
            self._type_id_remap[node_type] = i + 1

        self._bits_type = bit_len(len(uniq_types))
        self._type_map = type_map
        self._param_map = param_map
        self._param_dict = param_dict
        self._encoded_param_map = np.zeros_like(self._type_map)
        self._scratch_map = np.zeros_like(self._type_map)

        param_to_idx = dict()  # Maps entries in seen_params to ids.
        seen_params = set()
        param_items = 0

        # Refer to subdomain.Subdomain._verify_params for a list of allowed
        # ways of encoding nodes.
        for node_key, node_type in param_dict.items():
            for param in node_type.params.values():
                if util.is_number(param):
                    if param in seen_params:
                        idx = param_to_idx[param]
                    else:
                        seen_params.add(param)
                        self._geo_params.append(param)
                        idx = param_items
                        param_to_idx[param] = idx
                        param_items += 1
                    self._encoded_param_map[param_map == node_key] = idx
                elif type(param) is tuple:
                    if param in seen_params:
                        idx = param_to_idx[param]
                    else:
                        seen_params.add(param)
                        self._geo_params.extend(param)
                        idx = param_items
                        param_to_idx[param] = idx
                        param_items += len(param)
                    self._encoded_param_map[param_map == node_key] = idx
                # Param is a structured numpy array.
                elif isinstance(param, np.ndarray):
                    nodes_idx = np.argwhere(param_map == node_key)

                    uniques = np.unique(param)
                    uniques.flags.writeable = False

                    for value in uniques:
                        if value in seen_params:
                            idx = param_to_idx[value]
                        else:
                            seen_params.add(value)
                            self._geo_params.extend(value)
                            idx = param_items
                            param_to_idx[value] = idx
                            param_items += len(value)

                        idxs = nodes_idx[param == value]
                        if idxs.shape[1] == 3:
                            self._encoded_param_map[idxs[:,0], idxs[:,1],
                                                    idxs[:,2]] = idx
                        elif idxs.shape[1] == 2:
                            self._encoded_param_map[idxs[:,0], idxs[:,1]] = idx
                        else:
                            assert False, 'Unsupported dimension: {0}'.format(
                                    idxs.shape[1])
                            
        self._non_symbolic_idxs = param_items        
        self._symbol_map = {}  # Maps param indices to sympy expressions.
        self._symbol_to_geo_map = {}    #Maps array indices 
                                        #to one sympy expression

        self._non_sa_symbolic_map = {}
        self._extended_copy_map = {}
        
        # Maps timeseries data ID to offset in self._timeseries_data.
        timeseries_offset_map = {}
        timeseries_offset = 0
                
        for node_key, node_type in param_dict.items():
            for param in node_type.params.values():                
                if isinstance(param, nt.DynamicValue) and param.need_mf:
                    param_data = param.data
                    nodes_idx = np.argwhere(param_map == node_key)
                    symbol_idx = param_items
                    self._symbol_map[symbol_idx] = param
                    
                    uniques = np.unique(param_data)
                    uniques.flags.writeable = False

                    sym_indexes=()
                    for value in uniques:
                        if (value, param) in seen_params:
                            idx = param_to_idx[(value, param)]
                        else:
                            seen_params.add((value, param))
                            for v in value:
                                self._geo_params.append((v, param))
                            idx = param_items
                            
                            sym_indexes+=(idx,)
                            param_to_idx[(value, param)] = idx
                            param_items += len(value)
                            
                            for ts in param.get_timeseries():
                                dh = ts.data_hash()
                                if dh in timeseries_offset_map:
                                    ts._offset = timeseries_offset_map[dh]
                                else:
                                    ts._offset = timeseries_offset
                                    timeseries_offset_map[dh] = ts._offset
                                    timeseries_offset += ts._data.size
                                    self._timeseries_data.extend(ts._data)

                        idxs = nodes_idx[param_data == value]
                        if idxs.shape[1] == 3:
                            self._encoded_param_map[idxs[:,0], idxs[:,1],
                                                    idxs[:,2]] = idx
                        elif idxs.shape[1] == 2:
                            self._encoded_param_map[idxs[:,0], idxs[:,1]] = idx
                        else:
                            assert False, 'Unsupported dimension: {0}'.format(
                                    idxs.shape[1])
                    self._symbol_to_geo_map[symbol_idx]=sym_indexes 
                


        # TODO(michalj): Verify that the type of the symbolic expression matches
        # that of the boundary condition (vector vs scalar, etc).
        # Second pass: only process symbolic expressions here.

        for node_key, node_type in param_dict.items():                    
            for param in node_type.params.values():
                if isinstance(param, nt.DynamicValue) and not param.need_mf:
                    if param in seen_params:
                        idx = param_to_idx[param]
                    else:
                        seen_params.add(param)
                        idx = param_items
                        self._symbol_map[idx] = param
                        self._non_sa_symbolic_map[idx] = param
                        param_to_idx[param] = idx
                        param_items += 1

                        for ts in param.get_timeseries():
                            dh = ts.data_hash()
                            if dh in timeseries_offset_map:
                                ts._offset = timeseries_offset_map[dh]
                            else:
                                ts._offset = timeseries_offset
                                timeseries_offset_map[dh] = ts._offset
                                timeseries_offset += ts._data.size
                                self._timeseries_data.extend(ts._data)

                    self._encoded_param_map[param_map == node_key] = idx

                    
                    
                elif isinstance(param, ImmutableDenseMatrix):
                    if param in seen_params:
                        idx = param_to_idx[param]
                    else:
                        seen_params.add(param)
                        idx = param_items
                        self._extended_copy_map[idx] = param
                        param_to_idx[param] = idx
                        param_items += 1
                    
                    self._encoded_param_map[param_map == node_key] = idx   

        self._bits_param = bit_len(param_items)
                

        # Maps node type ID to base offset within the scratch space array.
        self._scratch_space_base = {}
        type_to_node_count = {}
        # Generate unique (within node type) scratch space ids.
        for node_type in self._node_types:
            if node_type.scratch_space_size(self.dim) <= 0:
                continue

            def _selector(idx_list):
                return tuple([slice(i, i+1) for i in idx_list])

            idx = np.argwhere(self._type_map == node_type.id)
            num_nodes = idx.shape[0]
            type_to_node_count[node_type.id] = num_nodes

            for i in range(num_nodes):
                self._scratch_map[_selector(idx[i,:])] = i

            self._scratch_space_base[node_type.id] = self.scratch_space_size

            # Accumulate size requirements of specific types into a global
            # size value for the whole scratch buffer.
            self.scratch_space_size += num_nodes * node_type.scratch_space_size(self.dim)

        if type_to_node_count:
            self._bits_scratch = bit_len(max(type_to_node_count.values()))
        else:
            self._bits_scratch = 0

        self._have_link_tags = have_link_tags
        if have_link_tags:
            # TODO: Actually drop these bits to save space in the node code.
            # It would be nice to use reduce here instead, but
            # bitwise_and.identity = 1 makes it impossible to use it.
            self._unused_tag_bits = int(np.bitwise_and.accumulate(
                orientation[orientation > 0])[-1])
Exemplo n.º 7
0
    def prepare_encode(self, type_map, param_map, param_dict):
        """
        :param type_map: uint32 array of NodeType.ids
        :param param_map: array whose entries are keys in param_dict
        :param param_dict: maps entries from param_map to LBNodeType objects
        """
        uniq_types = list(np.unique(type_map))
        for nt_id in uniq_types:
            self._node_types.add(nt._NODE_TYPES[nt_id])

        # Initialize the node ID map used for remapping.
        for i, node_type in enumerate(uniq_types):
            self._type_id_remap[node_type] = i + 1

        self._bits_type = bit_len(len(uniq_types))
        self._type_map = type_map
        self._param_map = param_map
        self._param_dict = param_dict
        self._encoded_param_map = np.zeros_like(self._type_map)
        self._scratch_map = np.zeros_like(self._type_map)

        param_to_idx = dict()  # Maps entries in seen_params to ids.
        seen_params = set()
        param_items = 0
        self._symbol_map = {}  # Maps param indices to sympy expressions.

        # Refer to subdomain.Subdomain._verify_params for a list of allowed
        # ways of encoding nodes.
        for node_key, node_type in param_dict.iteritems():
            for param in node_type.params.itervalues():
                if util.is_number(param):
                    if param in seen_params:
                        idx = param_to_idx[param]
                    else:
                        seen_params.add(param)
                        self._geo_params.append(param)
                        idx = param_items
                        param_to_idx[param] = idx
                        param_items += 1
                    self._encoded_param_map[param_map == node_key] = idx
                elif type(param) is tuple:
                    if param in seen_params:
                        idx = param_to_idx[param]
                    else:
                        seen_params.add(param)
                        self._geo_params.extend(param)
                        idx = param_items
                        param_to_idx[param] = idx
                        param_items += len(param)
                    self._encoded_param_map[param_map == node_key] = idx
                # Param is a structured numpy array.
                elif isinstance(param, np.ndarray):
                    nodes_idx = np.argwhere(param_map == node_key)

                    uniques = np.unique(param)
                    uniques.flags.writeable = False

                    for value in uniques:
                        if value in seen_params:
                            idx = param_to_idx[value]
                        else:
                            seen_params.add(value)
                            self._geo_params.extend(value)
                            idx = param_items
                            param_to_idx[value] = idx
                            param_items += len(value)

                        idxs = nodes_idx[param == value]
                        if idxs.shape[1] == 3:
                            self._encoded_param_map[idxs[:, 0], idxs[:, 1],
                                                    idxs[:, 2]] = idx
                        elif idxs.shape[1] == 2:
                            self._encoded_param_map[idxs[:, 0], idxs[:,
                                                                     1]] = idx
                        else:
                            assert False, 'Unsupported dimension: {0}'.format(
                                idxs.shape[1])

        self._non_symbolic_idxs = param_items

        # Second pass: only process symbolic expressions here.
        for node_key, node_type in param_dict.iteritems():
            for param in node_type.params.itervalues():
                if isinstance(param, nt.DynamicValue):
                    if param in seen_params:
                        idx = param_to_idx[value]
                    else:
                        seen_params.add(param)
                        idx = param_items
                        self._symbol_map[idx] = param
                        param_to_idx[param] = idx
                        param_items += 1
                    self._encoded_param_map[param_map == node_key] = idx

        self._bits_param = bit_len(param_items)

        # Maps node type ID to base offset within the scratch space array.
        self._scratch_space_base = {}
        type_to_node_count = {}
        # Generate unique (within node type) scratch space ids.
        for node_type in self._node_types:
            if node_type.scratch_space_size(self.dim) <= 0:
                continue

            def _selector(idx_list):
                return [slice(i, i + 1) for i in idx_list]

            idx = np.argwhere(self._type_map == node_type.id)
            num_nodes = idx.shape[0]
            type_to_node_count[node_type.id] = num_nodes

            for i in xrange(num_nodes):
                self._scratch_map[_selector(idx[i, :])] = i

            self._scratch_space_base[node_type.id] = self.scratch_space_size

            # Accumulate size requirements of specific types into a global
            # size value for the whole scratch buffer.
            self.scratch_space_size += num_nodes * node_type.scratch_space_size(
                self.dim)

        if type_to_node_count:
            self._bits_scratch = bit_len(max(type_to_node_count.itervalues()))
        else:
            self._bits_scratch = 0