Changeset 2684


Ignore:
Timestamp:
Apr 10, 2006, 3:15:05 PM (17 years ago)
Author:
duncan
Message:

Moving methods around, comments, a new test (to use when interpolate_function can handle discontinuous meshes)

Location:
inundation/fit_interpolate
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • inundation/fit_interpolate/interpolate.py

    r2660 r2684  
    1313
    1414TO DO
    15 * remove points outside the mesh ?(in interpolate_block)?
    1615* geo-ref (in interpolate_block)
    17 * add functional interpolate interface - in mesh and points, out interp data
    1816"""
    1917
     
    6866
    6967        """
    70 
    71         # why no alpha in parameter list?
    72        
    7368        # Initialise variabels
    7469        self._A_can_be_reused = False
     
    9186        # points, geo-ref and triangles, rather than just points and geo-ref
    9287        # this info will usually be coming from a domain instance.
     88       
    9389        if mesh_origin is None:
    9490            geo = None
     
    104100       
    105101       
    106     def _build_interpolation_matrix_A(self,
    107                                      point_coordinates,
    108                                      verbose = False):
    109         """Build n x m interpolation matrix, where
    110         n is the number of data points and
    111         m is the number of basis functions phi_k (one per vertex)
    112 
    113         This algorithm uses a quad tree data structure for fast binning
    114         of data points
    115         origin is a 3-tuple consisting of UTM zone, easting and northing.
    116         If specified coordinates are assumed to be relative to this origin.
    117 
    118         This one will override any data_origin that may be specified in
    119         instance interpolation
    120 
    121         Preconditions
    122         Point_coordindates and mesh vertices have the same origin.
    123         """
    124 
    125 
    126        
    127         #Convert point_coordinates to Numeric arrays, in case it was a list.
    128         point_coordinates = ensure_numeric(point_coordinates, Float)
    129        
    130         if verbose: print 'Getting indices inside mesh boundary'
    131         self.inside_poly_indices, self.outside_poly_indices  = \
    132                      in_and_outside_polygon(point_coordinates,
    133                                             self.mesh.get_boundary_polygon(),
    134                                             closed = True, verbose = verbose)
    135        
    136         #Build n x m interpolation matrix
    137         m = self.mesh.coordinates.shape[0] #Nbr of basis functions (1/vertex)
    138         n = point_coordinates.shape[0]     #Nbr of data points
    139 
    140         if verbose: print 'Number of datapoints: %d' %n
    141         if verbose: print 'Number of basis functions: %d' %m
    142 
    143         A = Sparse(n,m)
    144 
    145         #Compute matrix elements for points inside the mesh
    146         for i in self.inside_poly_indices:
    147             #For each data_coordinate point
    148             if verbose and i%((n+10)/10)==0: print 'Doing %d of %d' %(i, n)
    149             x = point_coordinates[i]
    150             element_found, sigma0, sigma1, sigma2, k = \
    151                            search_tree_of_vertices(self.root, self.mesh, x)
    152             #Update interpolation matrix A if necessary
    153             if element_found is True:
    154                 #Assign values to matrix A
    155 
    156                 j0 = self.mesh.triangles[k,0] #Global vertex id for sigma0
    157                 j1 = self.mesh.triangles[k,1] #Global vertex id for sigma1
    158                 j2 = self.mesh.triangles[k,2] #Global vertex id for sigma2
    159 
    160                 sigmas = {j0:sigma0, j1:sigma1, j2:sigma2}
    161                 js     = [j0,j1,j2]
    162 
    163                 for j in js:
    164                     A[i,j] = sigmas[j]
    165             else:
    166                 msg = 'Could not find triangle for point', x
    167                 raise Exception(msg)
    168         return A
    169 
    170102
    171103     # FIXME: What is a good start_blocking_len value?
     
    278210
    279211
     212    def _build_interpolation_matrix_A(self,
     213                                     point_coordinates,
     214                                     verbose = False):
     215        """Build n x m interpolation matrix, where
     216        n is the number of data points and
     217        m is the number of basis functions phi_k (one per vertex)
     218
     219        This algorithm uses a quad tree data structure for fast binning
     220        of data points
     221        origin is a 3-tuple consisting of UTM zone, easting and northing.
     222        If specified coordinates are assumed to be relative to this origin.
     223
     224        This one will override any data_origin that may be specified in
     225        instance interpolation
     226
     227        Preconditions
     228        Point_coordindates and mesh vertices have the same origin.
     229        """
     230
     231
     232       
     233        #Convert point_coordinates to Numeric arrays, in case it was a list.
     234        point_coordinates = ensure_numeric(point_coordinates, Float)
     235       
     236        if verbose: print 'Getting indices inside mesh boundary'
     237        #print "self.mesh.get_boundary_polygon()",self.mesh.get_boundary_polygon()
     238        self.inside_poly_indices, self.outside_poly_indices  = \
     239                     in_and_outside_polygon(point_coordinates,
     240                                            self.mesh.get_boundary_polygon(),
     241                                            closed = True, verbose = verbose)
     242        #print "self.inside_poly_indices",self.inside_poly_indices
     243        #print "self.outside_poly_indices",self.outside_poly_indices
     244        #Build n x m interpolation matrix
     245        m = self.mesh.coordinates.shape[0] #Nbr of basis functions (1/vertex)
     246        n = point_coordinates.shape[0]     #Nbr of data points
     247
     248        if verbose: print 'Number of datapoints: %d' %n
     249        if verbose: print 'Number of basis functions: %d' %m
     250
     251        A = Sparse(n,m)
     252
     253        #Compute matrix elements for points inside the mesh
     254        for i in self.inside_poly_indices:
     255            #For each data_coordinate point
     256            if verbose and i%((n+10)/10)==0: print 'Doing %d of %d' %(i, n)
     257            x = point_coordinates[i]
     258            element_found, sigma0, sigma1, sigma2, k = \
     259                           search_tree_of_vertices(self.root, self.mesh, x)
     260            #Update interpolation matrix A if necessary
     261            if element_found is True:
     262                #Assign values to matrix A
     263
     264                j0 = self.mesh.triangles[k,0] #Global vertex id for sigma0
     265                j1 = self.mesh.triangles[k,1] #Global vertex id for sigma1
     266                j2 = self.mesh.triangles[k,2] #Global vertex id for sigma2
     267
     268                sigmas = {j0:sigma0, j1:sigma1, j2:sigma2}
     269                js     = [j0,j1,j2]
     270
     271                for j in js:
     272                    A[i,j] = sigmas[j]
     273            else:
     274                msg = 'Could not find triangle for point', x
     275                raise Exception(msg)
     276        return A
     277
    280278class Interpolation_function:
    281279    """Interpolation_interface - creates callable object f(t, id) or f(t,x,y)
     
    499497        #Compute interpolated values
    500498        q = zeros(len(self.quantity_names), Float)
    501 
     499        #print "self.precomputed_values", self.precomputed_values
    502500        for i, name in enumerate(self.quantity_names):
    503501            Q = self.precomputed_values[name]
  • inundation/fit_interpolate/test_interpolate.py

    r2660 r2684  
    798798
    799799
     800    def fix_test_interpolation_precompute_points(self):
     801        # looking at a discrete mesh
     802        #
     803   
     804        #Three timesteps
     805        time = [0.0, 60.0]   
     806
     807        #Setup mesh used to represent fitted function
     808        points = [[ 15., -20.],
     809                  [ 15.,  10.],
     810                  [  0., -20.],
     811                  [  0.,  10.],
     812                  [  0., -20.],
     813                  [ 15.,  10.]]
     814       
     815        triangles = [[0, 1, 2],
     816                     [3, 4, 5]]
     817
     818        #New datapoints where interpolated values are sought
     819        interpolation_points = [[ 1.,  0.], [0.,1.]]
     820
     821        #One quantity
     822        Q = zeros( (2,6), Float )
     823
     824        #Linear in time and space
     825        for i, t in enumerate(time):
     826            Q[i, :] = t*linear_function(points)
     827        #print "Q", Q
     828
     829
     830       
     831        interp = Interpolate(points, triangles)
     832        f = array([linear_function(points),2*linear_function(points) ])
     833        f = transpose(f)
     834        #print "f",f
     835        z = interp.interpolate(f, interpolation_points)
     836        answer = [linear_function(interpolation_points),
     837                  2*linear_function(interpolation_points) ]
     838        answer = transpose(answer)
     839        print "z",z
     840        print "answer",answer
     841        assert allclose(z, answer)
     842
     843
     844        #Check interpolation of one quantity using interpolaton points)
     845        I = Interpolation_function(time, Q,
     846                                   vertex_coordinates = points,
     847                                   triangles = triangles,
     848                                   interpolation_points = interpolation_points,
     849                                   verbose = False)
     850        print "I.precomputed_values", I.precomputed_values
     851       
     852        self.failUnless( I.precomputed_values['Attribute'][1] == 60.0,
     853                        ' failed')
     854       
    800855    def test_interpolation_function_outside_point(self):
    801856        # Test spatio-temporal interpolation
     
    911966
    912967    suite = unittest.makeSuite(Test_Interpolate,'test')
    913     #suite = unittest.makeSuite(Test_Interpolate,'test_points_outside_the_polygon')
     968    #suite = unittest.makeSuite(Test_Interpolate,'test_interpolation_precompute_points')
    914969    runner = unittest.TextTestRunner(verbosity=1)
    915970    runner.run(suite)
Note: See TracChangeset for help on using the changeset viewer.