Ignore:
Timestamp:
Aug 24, 2005, 12:34:00 PM (19 years ago)
Author:
ole
Message:

Refactored quantity.set_values

File:
1 edited

Legend:

Unmodified
Added
Removed
  • inundation/pyvolution/quantity.py

    r1751 r1752  
    8282
    8383    #New leaner interface to setting values
    84     def set_values_new(self,
     84    def set_values(self,
    8585                   numeric = None,  #List, numeric array or constant
    8686                   quantity = None, #Another quantity
     
    8989                   filename = None, attribute_name = None, #Input from file
    9090                   alpha = None,
    91                    location = None,                   
     91                   location = 'vertices',                   
    9292                   indices = None,
    9393                   verbose = None):
     
    169169              'must be present.'
    170170        L = [numeric, quantity, function, points, filename]
     171
    171172        assert L.count(None) == len(L)-1, msg
    172173
     
    216217        else:
    217218            raise 'This can\'t happen :-)'
     219
     220
     221        #Update all locations in triangles
     222        if location == 'vertices' or location == 'unique vertices':
     223            #Intialise centroid and edge_values
     224            self.interpolate()
     225
     226        if location == 'centroids':
     227            #Extrapolate 1st order - to capture notion of area being specified
     228            self.extrapolate_first_order()
     229
    218230               
    219231
     232    #Specific functions for setting values
     233    def set_values_from_constant(self, X,
     234                                 location, indices, verbose):
     235        """Set quantity values from specified constant X
     236        """
     237
     238
     239        if location == 'centroids':
     240            if (indices ==  None):
     241                self.centroid_values[:] = X
     242            else:
     243                #Brute force
     244                for i in indices:
     245                    self.centroid_values[i,:] = X
     246
     247        elif location == 'edges':
     248            if (indices ==  None):
     249                self.edge_values[:] = X
     250            else:
     251                #Brute force
     252                for i in indices:
     253                    self.edge_values[i,:] = X
     254
     255        elif location == 'unique vertices':
     256            if (indices ==  None):
     257                self.edge_values[:] = X
     258            else:
     259
     260                #Go through list of unique vertices
     261                for unique_vert_id in indices:
     262                    triangles = self.domain.vertexlist[unique_vert_id]
     263
     264                    #In case there are unused points
     265                    if triangles is None: continue
     266
     267                    #Go through all triangle, vertex pairs
     268                    #and set corresponding vertex value
     269                    for triangle_id, vertex_id in triangles:
     270                        self.vertex_values[triangle_id, vertex_id] = X
     271
     272                    #Intialise centroid and edge_values
     273                    self.interpolate()
     274        else:
     275            if (indices ==  None):
     276                self.vertex_values[:] = X
     277            else:
     278                #Brute force
     279                for i_vertex in indices:
     280                    self.vertex_values[i_vertex,:] = X
     281
    220282   
    221     #Specific functions for setting values
    222     def set_values_from_function(self, function,
     283
     284   
     285
     286
     287    def set_values_from_array(self, values,
     288                              location, indices, verbose):
     289        """Set values for quantity
     290
     291        values: Numeric array
     292        location: Where values are to be stored.
     293        Permissible options are: vertices, edges, centroid, unique vertices
     294        Default is "vertices"
     295
     296        indices - if this action is carried out on a subset of
     297        elements or unique vertices
     298        The element/unique vertex indices are specified here.
     299
     300        In case of location == 'centroid' the dimension values must
     301        be a list of a Numerical array of length N, N being the number
     302        of elements.
     303
     304        Otherwise it must be of dimension Nx3
     305
     306        The values will be stored in elements following their
     307        internal ordering.
     308
     309        If selected location is vertices, values for centroid and edges
     310        will be assigned interpolated values.
     311        In any other case, only values for the specified locations
     312        will be assigned and the others will be left undefined.
     313        """
     314
     315        from Numeric import array, Float, Int, allclose
     316
     317        values = array(values).astype(Float)
     318
     319        if indices is not None:
     320            indices = array(indices).astype(Int)
     321            msg = 'Number of values must match number of indices'
     322            assert values.shape[0] == indices.shape[0], msg
     323
     324        N = self.centroid_values.shape[0]
     325
     326        if location == 'centroids':
     327            assert len(values.shape) == 1, 'Values array must be 1d'
     328
     329            if indices is None:
     330                msg = 'Number of values must match number of elements'
     331                assert values.shape[0] == N, msg
     332
     333                self.centroid_values = values
     334            else:
     335                msg = 'Number of values must match number of indices'
     336                assert values.shape[0] == indices.shape[0], msg
     337
     338                #Brute force
     339                for i in range(len(indices)):
     340                    self.centroid_values[indices[i]] = values[i]
     341
     342        elif location == 'edges':
     343            assert len(values.shape) == 2, 'Values array must be 2d'
     344
     345            msg = 'Number of values must match number of elements'
     346            assert values.shape[0] == N, msg
     347
     348            msg = 'Array must be N x 3'
     349            assert values.shape[1] == 3, msg
     350
     351            self.edge_values = values
     352
     353        elif location == 'unique vertices':
     354            assert len(values.shape) == 1 or allclose(values.shape[1:], 1),\
     355                   'Values array must be 1d'
     356
     357            self.set_vertex_values(values.flat, indices = indices)
     358        else:
     359            if len(values.shape) == 1:
     360                self.set_vertex_values(values, indices = indices)
     361                #if indices == None:
     362                    #Values are being specified once for each unique vertex
     363                #    msg = 'Number of values must match number of vertices'
     364                #    assert values.shape[0] == self.domain.coordinates.shape[0], msg
     365                 #   self.set_vertex_values(values)
     366                #else:
     367                #    for element_index, value in map(None, indices, values):
     368                #        self.vertex_values[element_index, :] = value
     369
     370            elif len(values.shape) == 2:
     371                #Vertex values are given as a triplet for each triangle
     372
     373                msg = 'Array must be N x 3'
     374                assert values.shape[1] == 3, msg
     375
     376                if indices == None:
     377                    self.vertex_values = values
     378                else:
     379                    for element_index, value in map(None, indices, values):
     380                        self.vertex_values[element_index] = value
     381            else:
     382                msg = 'Values array must be 1d or 2d'
     383                raise msg
     384
     385    def set_values_from_quantity(self, q,
     386                                 location, indices, verbose):
     387        """Set quantity values from specified quantity instance q
     388        """
     389
     390
     391        raise 'not yet implemented'
     392
     393    def set_values_from_function(self, f,
    223394                                 location, indices, verbose):
    224395        """Set values for quantity using specified function
     
    241412        else:
    242413            is_subset = True
     414           
    243415        if location == 'centroids':
    244             P = take(self.domain.centroid_coordinates,indices)
     416            P = take(self.domain.centroid_coordinates, indices)
    245417            if is_subset:
    246                 self.set_values(f(P[:,0], P[:,1]), location, indices = indices)
     418                self.set_values(f(P[:,0], P[:,1]),
     419                                location = location,
     420                                indices = indices)
    247421            else:
    248                 self.set_values(f(P[:,0], P[:,1]), location)
     422                self.set_values(f(P[:,0], P[:,1]), location = location)
    249423        elif location == 'vertices':
    250424            P = self.domain.vertex_coordinates
     
    259433        else:
    260434            raise 'Not implemented: %s' %location
    261 
    262 
    263     def set_array_values(self, values, location='vertices', indices = None):
    264         """Set values for quantity
    265 
    266         values: Numeric array
    267         location: Where values are to be stored.
    268         Permissible options are: vertices, edges, centroid, unique vertices
    269         Default is "vertices"
    270 
    271         indices - if this action is carried out on a subset of
    272         elements or unique vertices
    273         The element/unique vertex indices are specified here.
    274 
    275         In case of location == 'centroid' the dimension values must
    276         be a list of a Numerical array of length N, N being the number
    277         of elements.
    278 
    279         Otherwise it must be of dimension Nx3
    280 
    281         The values will be stored in elements following their
    282         internal ordering.
    283 
    284         If selected location is vertices, values for centroid and edges
    285         will be assigned interpolated values.
    286         In any other case, only values for the specified locations
    287         will be assigned and the others will be left undefined.
    288         """
    289 
    290         from Numeric import array, Float, Int, allclose
    291 
    292         values = array(values).astype(Float)
    293 
    294         if (indices <> None):
    295             indices = array(indices).astype(Int)
    296             msg = 'Number of values must match number of indices'
    297             assert values.shape[0] == indices.shape[0], msg
    298 
    299         N = self.centroid_values.shape[0]
    300 
    301         if location == 'centroids':
    302             assert len(values.shape) == 1, 'Values array must be 1d'
    303 
    304             if indices == None:
    305                 msg = 'Number of values must match number of elements'
    306                 assert values.shape[0] == N, msg
    307 
    308                 self.centroid_values = values
    309             else:
    310                 msg = 'Number of values must match number of indices'
    311                 assert values.shape[0] == indices.shape[0], msg
    312 
    313                 #Brute force
    314                 for i in range(len(indices)):
    315                     self.centroid_values[indices[i]] = values[i]
    316 
    317         elif location == 'edges':
    318             assert len(values.shape) == 2, 'Values array must be 2d'
    319 
    320             msg = 'Number of values must match number of elements'
    321             assert values.shape[0] == N, msg
    322 
    323             msg = 'Array must be N x 3'
    324             assert values.shape[1] == 3, msg
    325 
    326             self.edge_values = values
    327 
    328         elif location == 'unique vertices':
    329             assert len(values.shape) == 1 or allclose(values.shape[1:], 1),\
    330                    'Values array must be 1d'
    331 
    332             self.set_vertex_values(values.flat, indices = indices)
    333         else:
    334             if len(values.shape) == 1:
    335                 self.set_vertex_values(values, indices = indices)
    336                 #if indices == None:
    337                     #Values are being specified once for each unique vertex
    338                 #    msg = 'Number of values must match number of vertices'
    339                 #    assert values.shape[0] == self.domain.coordinates.shape[0], msg
    340                  #   self.set_vertex_values(values)
    341                 #else:
    342                 #    for element_index, value in map(None, indices, values):
    343                 #        self.vertex_values[element_index, :] = value
    344 
    345             elif len(values.shape) == 2:
    346                 #Vertex values are given as a triplet for each triangle
    347 
    348                 msg = 'Array must be N x 3'
    349                 assert values.shape[1] == 3, msg
    350 
    351                 if indices == None:
    352                     self.vertex_values = values
    353                 else:
    354                     for element_index, value in map(None, indices, values):
    355                         self.vertex_values[element_index] = value
    356             else:
    357                 msg = 'Values array must be 1d or 2d'
    358                 raise msg
    359435
    360436
     
    438514        self.set_values_from_points(points, z, alpha,
    439515                                    location, indices, verbose)
    440 
    441 
    442 
    443 
    444 
    445     #Old interface to setting values
    446     def set_values(self, X,
    447                    location='vertices',
    448                    indices = None):
    449         """Set values for quantity
    450 
    451         X: Compatible list, Numeric array (see below), constant or function
    452         location: Where values are to be stored.
    453                   Permissible options are: vertices, edges, centroids
    454                   Default is "vertices"
    455 
    456         In case of location == 'centroids' the dimension values must
    457         be a list of a Numerical array of length N, N being the number
    458         of elements. Otherwise it must be of dimension Nx3
    459 
    460         The values will be stored in elements following their
    461         internal ordering.
    462 
    463         If values are described a function, it will be evaluated at
    464         specified points
    465 
    466         If indexex is not 'unique vertices' Indices is the set of element ids
    467         that the operation applies to.
    468         If indexex is 'unique vertices' Indices is the set of vertex ids
    469         that the operation applies to.
    470 
    471         If selected location is 'vertices', values for centroid and edges
    472         will be assigned interpolated values.
    473         In any other case, only values for the specified locations
    474         will be assigned and the others will be left undefined.
    475 
    476         """
    477 
    478         if location not in ['vertices', 'centroids', 'edges',
    479                             'unique vertices']:
    480             msg = 'Invalid location: %s' %location
    481             raise msg
    482 
    483 
    484         if X is None:
    485             msg = 'Given values are None'
    486             raise msg
    487 
    488         import types, Numeric
    489         assert type(indices) in [types.ListType, types.NoneType,
    490                                  Numeric.ArrayType],\
    491                                  'Indices must be a list or None'
    492 
    493 
    494         if callable(X):
    495             #Use function specific method
    496             self.set_function_values(X, location, indices = indices)
    497         elif type(X) in [types.FloatType, types.IntType, types.LongType]:
    498             if location == 'centroids':
    499                 if (indices ==  None):
    500                     self.centroid_values[:] = X
    501                 else:
    502                     #Brute force
    503                     for i in indices:
    504                         self.centroid_values[i,:] = X
    505 
    506             elif location == 'edges':
    507                 if (indices ==  None):
    508                     self.edge_values[:] = X
    509                 else:
    510                     #Brute force
    511                     for i in indices:
    512                         self.edge_values[i,:] = X
    513 
    514             elif location == 'unique vertices':
    515                 if (indices ==  None):
    516                     self.edge_values[:] = X
    517                 else:
    518 
    519                     #Go through list of unique vertices
    520                     for unique_vert_id in indices:
    521                         triangles = self.domain.vertexlist[unique_vert_id]
    522 
    523                         #In case there are unused points
    524                         if triangles is None: continue
    525 
    526                         #Go through all triangle, vertex pairs
    527                         #and set corresponding vertex value
    528                         for triangle_id, vertex_id in triangles:
    529                             self.vertex_values[triangle_id, vertex_id] = X
    530 
    531                         #Intialise centroid and edge_values
    532                         self.interpolate()
    533             else:
    534                 if (indices ==  None):
    535                     self.vertex_values[:] = X
    536                 else:
    537                     #Brute force
    538                     for i_vertex in indices:
    539                         self.vertex_values[i_vertex,:] = X
    540 
    541         elif type(X) in [Numeric.ArrayType, types.ListType]:
    542             #Use array specific method
    543             self.set_array_values(X, location, indices = indices)
    544         elif type(X) == types.StringType:
    545             #Assume X is a filename
    546             self.set_values_from_file(X) #FIXME: More parameters
    547 
    548 
    549         if location == 'vertices' or location == 'unique vertices':
    550             #Intialise centroid and edge_values
    551             self.interpolate()
    552 
    553         if location == 'centroids':
    554             #Extrapolate 1st order - to capture notion of area being specified
    555             self.extrapolate_first_order()
    556516
    557517
     
    621581
    622582
    623     def set_function_values(self, f, location='vertices', indices = None):
    624         """Set values for quantity using specified function
    625 
    626         f: x, y -> z Function where x, y and z are arrays
    627         location: Where values are to be stored.
    628                   Permissible options are: vertices, centroid
    629                   Default is "vertices"
    630         """
    631 
    632         #FIXME: Should check that function returns something sensible and
    633         #raise a meaningfol exception if it returns None for example
    634 
    635         from Numeric import take
    636 
    637         if (indices ==  None):
    638             indices = range(len(self))
    639             is_subset = False
    640         else:
    641             is_subset = True
    642         if location == 'centroids':
    643             P = take(self.domain.centroid_coordinates,indices)
    644             if is_subset:
    645                 self.set_values(f(P[:,0], P[:,1]), location, indices = indices)
    646             else:
    647                 self.set_values(f(P[:,0], P[:,1]), location)
    648         elif location == 'vertices':
    649             P = self.domain.vertex_coordinates
    650             if is_subset:
    651                 #Brute force
    652                 for e in indices:
    653                     for i in range(3):
    654                         self.vertex_values[e,i] = f(P[e,2*i], P[e,2*i+1])
    655             else:
    656                 for i in range(3):
    657                     self.vertex_values[:,i] = f(P[:,2*i], P[:,2*i+1])
    658         else:
    659             raise 'Not implemented: %s' %location
    660 
    661 
    662     def set_array_values(self, values, location='vertices', indices = None):
    663         """Set values for quantity
    664 
    665         values: Numeric array
    666         location: Where values are to be stored.
    667         Permissible options are: vertices, edges, centroid, unique vertices
    668         Default is "vertices"
    669 
    670         indices - if this action is carried out on a subset of
    671         elements or unique vertices
    672         The element/unique vertex indices are specified here.
    673 
    674         In case of location == 'centroid' the dimension values must
    675         be a list of a Numerical array of length N, N being the number
    676         of elements.
    677 
    678         Otherwise it must be of dimension Nx3
    679 
    680         The values will be stored in elements following their
    681         internal ordering.
    682 
    683         If selected location is vertices, values for centroid and edges
    684         will be assigned interpolated values.
    685         In any other case, only values for the specified locations
    686         will be assigned and the others will be left undefined.
    687         """
    688 
    689         from Numeric import array, Float, Int, allclose
    690 
    691         values = array(values).astype(Float)
    692 
    693         if (indices <> None):
    694             indices = array(indices).astype(Int)
    695             msg = 'Number of values must match number of indices'
    696             assert values.shape[0] == indices.shape[0], msg
    697 
    698         N = self.centroid_values.shape[0]
    699 
    700         if location == 'centroids':
    701             assert len(values.shape) == 1, 'Values array must be 1d'
    702 
    703             if indices == None:
    704                 msg = 'Number of values must match number of elements'
    705                 assert values.shape[0] == N, msg
    706 
    707                 self.centroid_values = values
    708             else:
    709                 msg = 'Number of values must match number of indices'
    710                 assert values.shape[0] == indices.shape[0], msg
    711 
    712                 #Brute force
    713                 for i in range(len(indices)):
    714                     self.centroid_values[indices[i]] = values[i]
    715 
    716         elif location == 'edges':
    717             assert len(values.shape) == 2, 'Values array must be 2d'
    718 
    719             msg = 'Number of values must match number of elements'
    720             assert values.shape[0] == N, msg
    721 
    722             msg = 'Array must be N x 3'
    723             assert values.shape[1] == 3, msg
    724 
    725             self.edge_values = values
    726 
    727         elif location == 'unique vertices':
    728             assert len(values.shape) == 1 or allclose(values.shape[1:], 1),\
    729                    'Values array must be 1d'
    730 
    731             self.set_vertex_values(values.flat, indices = indices)
    732         else:
    733             if len(values.shape) == 1:
    734                 self.set_vertex_values(values, indices = indices)
    735                 #if indices == None:
    736                     #Values are being specified once for each unique vertex
    737                 #    msg = 'Number of values must match number of vertices'
    738                 #    assert values.shape[0] == self.domain.coordinates.shape[0], msg
    739                  #   self.set_vertex_values(values)
    740                 #else:
    741                 #    for element_index, value in map(None, indices, values):
    742                 #        self.vertex_values[element_index, :] = value
    743 
    744             elif len(values.shape) == 2:
    745                 #Vertex values are given as a triplet for each triangle
    746 
    747                 msg = 'Array must be N x 3'
    748                 assert values.shape[1] == 3, msg
    749 
    750                 if indices == None:
    751                     self.vertex_values = values
    752                 else:
    753                     for element_index, value in map(None, indices, values):
    754                         self.vertex_values[element_index] = value
    755             else:
    756                 msg = 'Values array must be 1d or 2d'
    757                 raise msg
    758 
    759 
    760 
    761 
    762 
    763 
    764 
    765     # FIXME have a get_vertex_values as well, so the 'stage' quantity can be
    766     # set, based on the elevation
     583
    767584    def set_vertex_values(self, A, indices = None):
    768585        """Set vertex values for all unique vertices based on input array A
     
    773590        indices is the list of vertex_id's that will be set.
    774591
    775         Note: Functions not allowed
     592        This function is used by set_values_from_array
    776593        """
    777594
     
    804621        #Intialise centroid and edge_values
    805622        self.interpolate()
     623
    806624
    807625    def smooth_vertex_values(self, value_array='field_values',
Note: See TracChangeset for help on using the changeset viewer.