Changeset 6228


Ignore:
Timestamp:
Jan 22, 2009, 8:59:49 AM (16 years ago)
Author:
rwilson
Message:

Hand-merged Ole's and my changes, 6221 and 6226 respectively.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • anuga_core/source/anuga/abstract_2d_finite_volumes/quantity.py

    r6226 r6228  
    2121from anuga.config import points_file_block_line_size as default_block_line_size
    2222from anuga.config import epsilon
     23from anuga.caching import cache
    2324
    2425import Numeric as num
     
    3334    # @param domain ??
    3435    # @param vertex_values ??
    35     def __init__(self, domain,
    36                        vertex_values=None):
     36    def __init__(self, domain, vertex_values=None):
    3737        from anuga.abstract_2d_finite_volumes.domain import Domain
    3838
    39         msg = 'First argument in Quantity.__init__ '
    40         msg += 'must be of class Domain (or a subclass thereof). '
    41         msg += 'I got %s.' % str(domain.__class__)
     39        msg = ('First argument in Quantity.__init__() must be of class Domain '
     40               '(or a subclass thereof). I got %s.' % str(domain.__class__))
    4241        assert isinstance(domain, Domain), msg
    4342
     
    8584        self.set_beta(1.0)
    8685
    87     #
     86    ############################################################################
    8887    # Methods for operator overloading
    89     #
    90 
    91     ##
    92     # @brief Get length of object.
    93     # @return Return axis length of array.
     88    ############################################################################
     89
    9490    def __len__(self):
    9591        return self.centroid_values.shape[0]
    9692
    97     ##
    98     # @brief Negate all values in this quantity.
    9993    def __neg__(self):
    10094        """Negate all values in this quantity giving meaning to the
     
    106100        return Q
    107101
    108     ##
    109     # @brief Add two quantities.
    110     # @param other The other quantity (to the right).
    111102    def __add__(self, other):
    112103        """Add to self anything that could populate a quantity
     
    124115        return result
    125116
    126     ##
    127     # @brief Add two quantities.
    128     # @param other The other quantity (to the left).
    129117    def __radd__(self, other):
    130118        """Handle cases like 7+Q, where Q is an instance of class Quantity
     
    133121        return self + other
    134122
    135     ##
    136     # @brief Subtract two quantities.
    137     # @param other The other quantity (to the right).
    138123    def __sub__(self, other):
    139124        return self + -other            # Invoke self.__neg__()
    140125
    141     ##
    142     # @brief Multiply two quantities.
    143     # @param other The other quantity (to the right).
    144126    def __mul__(self, other):
    145127        """Multiply self with anything that could populate a quantity
     
    168150        return result
    169151
    170     ##
    171     # @brief Multiply two quantities.
    172     # @param other The other quantity (to the left).
    173152    def __rmul__(self, other):
    174153        """Handle cases like 3*Q, where Q is an instance of class Quantity
     
    177156        return self * other
    178157
    179     ##
    180     # @brief Divide two quantities.
    181     # @param other The other quantity (to the right).
    182158    def __div__(self, other):
    183159        """Divide self with anything that could populate a quantity
     
    209185        return result
    210186
    211     ##
    212     # @brief Divide two quantities.
    213     # @param other The other quantity (to the left).
    214187    def __rdiv__(self, other):
    215188        """Handle cases like 3/Q, where Q is an instance of class Quantity
     
    218191        return self / other
    219192
    220     ##
    221     # @brief Raise a quaintity to some power.
    222     # @param other The power to raise quantity.
    223193    def __pow__(self, other):
    224194        """Raise quantity to (numerical) power
     
    248218
    249219        return result
     220
     221    ############################################################################
     222    # Setters/Getters
     223    ############################################################################
    250224
    251225    ##
     
    464438
    465439            if smooth:
    466                 self.smooth_vertex_values()
     440                self.smooth_vertex_values(use_cache=use_cache,
     441                                          verbose=verbose)
    467442
    468443            return
     
    491466                                              indices, verbose)
    492467            elif type(numeric) in [num.ArrayType, ListType]:
    493                 self.set_values_from_array(numeric, location, indices, verbose)
     468                self.set_values_from_array(numeric, location, indices,
     469                                           use_cache=use_cache, verbose=verbose)
    494470            elif callable(numeric):
    495                 self.set_values_from_function(numeric, location,
    496                                               indices, verbose)
     471                self.set_values_from_function(numeric, location, indices,
     472                                              use_cache=use_cache,
     473                                              verbose=verbose)
    497474            elif isinstance(numeric, Quantity):
    498                 self.set_values_from_quantity(numeric, location,
    499                                               indices, verbose)
     475                self.set_values_from_quantity(numeric, location, indices,
     476                                              verbose=verbose)
    500477            elif isinstance(numeric, Geospatial_data):
    501478                self.set_values_from_geospatial_data(numeric, alpha, location,
     
    510487            msg = 'Argument function must be callable'
    511488            assert callable(function), msg
    512             self.set_values_from_function(function, location, indices, verbose)
     489            self.set_values_from_function(function, location, indices,
     490                                          use_cache=use_cache, verbose=verbose)
    513491        elif geospatial_data is not None:
    514492                self.set_values_from_geospatial_data(geospatial_data, alpha,
     
    539517
    540518
    541     #---------------------------------------------------------------------------
     519    ############################################################################
    542520    # Specific internal functions for setting values based on type
    543     #---------------------------------------------------------------------------
     521    ############################################################################
    544522
    545523    ##
     
    596574    # @param location Where values are to be stored.
    597575    # @param indices Limit update to these indices.
     576    # @param use_cache ??
    598577    # @param verbose True if this method is to be verbose.
    599578    def set_values_from_array(self, values,
    600579                                    location='vertices',
    601580                                    indices=None,
     581                                    use_cache=False,
    602582                                    verbose=False):
    603583        """Set values for quantity
     
    657637                    'Values array must be 1d')
    658638
    659             self.set_vertex_values(values.flat, indices=indices)
     639            self.set_vertex_values(values.flat, indices=indices,
     640                                   use_cache=use_cache, verbose=verbose)
    660641        else:
    661642            # Location vertices
    662643            if len(values.shape) == 1:
    663                 self.set_vertex_values(values, indices=indices)
     644                # This is the common case arising from fitted
     645                # values (e.g. from pts file).
     646                self.set_vertex_values(values, indices=indices,
     647                                       use_cache=use_cache, verbose=verbose)
    664648            elif len(values.shape) == 2:
    665649                # Vertex values are given as a triplet for each triangle
     
    704688    # @param location Where values are to be stored.
    705689    # @param indices ??
     690    # @param use_cache ??
    706691    # @param verbose True if this method is to be verbose.
    707692    def set_values_from_function(self, f,
    708693                                       location='vertices',
    709694                                       indices=None,
     695                                       use_cache=False,
    710696                                       verbose=False):
    711697        """Set values for quantity using specified function
     
    731717
    732718            V = num.take(self.domain.get_centroid_coordinates(), indices)
    733             self.set_values(f(V[:,0], V[:,1]),
    734                             location=location, indices=indices)
     719            x = V[:,0]; y = V[:,1]
     720            if use_cache is True:
     721                res = cache(f, (x, y), verbose=verbose)
     722            else:
     723                res = f(x, y)
     724
     725            self.set_values(res, location=location, indices=indices)
    735726        elif location == 'vertices':
     727            # This is the default branch taken by set_quantity
    736728            M = self.domain.number_of_triangles
    737729            V = self.domain.get_vertex_coordinates()
    738730
    739731            x = V[:,0];
    740             y = V[:,1];
    741             values = f(x, y)
     732            y = V[:,1]
     733            if use_cache is True:
     734                #print 'Caching function'
     735                values = cache(f, (x, y), verbose=verbose)               
     736            else:
     737                if verbose is True:
     738                    print 'Evaluating function in set_values'
     739                values = f(x, y)
    742740
    743741            # FIXME (Ole): This code should replace all the
     
    788786        data_georef = geospatial_data.get_geo_reference()
    789787
     788        from anuga.coordinate_transforms.geo_reference import Geo_reference
     789
    790790        points = ensure_numeric(points, num.Float)
    791791        values = ensure_numeric(values, num.Float)
     
    816816
    817817        # Call underlying method using array values
    818         self.set_values_from_array(vertex_attributes, location,
    819                                    indices, verbose)
     818        self.set_values_from_array(vertex_attributes, location, indices,
     819                                   use_cache=use_cache, verbose=verbose)
    820820
    821821    ##
     
    902902
    903903        # Call underlying method using array values
     904        if verbose:
     905            print 'Applying fitted data to domain'
    904906        self.set_values_from_array(vertex_attributes, location,
    905                                    indices, verbose)
     907                                   indices, use_cache=use_cache,
     908                                   verbose=verbose)
    906909
    907910    ##
     
    12131216    # @param A Array to set values with.
    12141217    # @param indices Set of IDs of elements to work on.
    1215     def set_vertex_values(self, A, indices=None):
     1218    # @param use_cache ??
     1219    # @param verbose??
     1220    def set_vertex_values(self, A,
     1221                                indices=None,
     1222                                use_cache=False,
     1223                                verbose=False):
    12161224        """Set vertex values for all unique vertices based on input array A
    12171225        which has one entry per unique vertex, i.e. one value for each row in
     
    12341242            vertex_list = indices
    12351243
     1244        #FIXME(Ole): This function ought to be faster.
     1245        # We need to get the triangles_and_vertices list
     1246        # from domain in one hit, then cache the computation of the
     1247        # Nx3 array of vertex values that can then be assigned using
     1248        # set_values_from_array.
     1249        #
     1250        # Alternatively, some C code would be handy
     1251        #
     1252        self._set_vertex_values(vertex_list, A)
     1253           
     1254    ##
     1255    # @brief Go through list of unique vertices.
     1256    # @param vertex_list ??
     1257    # @param A ??
     1258    def _set_vertex_values(self, vertex_list, A):
     1259        """Go through list of unique vertices
     1260        This is the common case e.g. when values
     1261        are obtained from a pts file through fitting
     1262        """
     1263
    12361264        # Go through list of unique vertices
    12371265        for i_index, unique_vert_id in enumerate(vertex_list):
     
    12521280    ##
    12531281    # @brief Smooth vertex values.
    1254     def smooth_vertex_values(self):
     1282    def smooth_vertex_values(self, use_cache=False, verbose=False):
    12551283        """Smooths vertex values."""
    12561284
    12571285        A, V = self.get_vertex_values(xy=False, smooth=True)
    1258         self.set_vertex_values(A)
     1286        self.set_vertex_values(A, use_cache=use_cache, verbose=verbose)
    12591287
    12601288    ############################################################################
     
    12671295    # @param smooth True if vertex values are to be smoothed.
    12681296    # @param precision The type of the result values (default float).
    1269     def get_vertex_values(self, xy=True,
    1270                                 smooth=None,
    1271                                 precision=None):
     1297    def get_vertex_values(self, xy=True, smooth=None, precision=None):
    12721298        """Return vertex values like an OBJ format i.e. one value per node.
    12731299
Note: See TracChangeset for help on using the changeset viewer.