Changeset 2189


Ignore:
Timestamp:
Jan 9, 2006, 4:09:06 PM (19 years ago)
Author:
duncan
Message:

refactoring, has old code commented out

Location:
inundation/fit_interpolate
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • inundation/fit_interpolate/interpolate.py

    r2187 r2189  
    3333                 vertex_coordinates,
    3434                 triangles,
    35                  point_coordinates = None,
     35                 #point_coordinates = None,
    3636                 mesh_origin = None,
    3737                 verbose=False,
     
    6868        from pyvolution.util import ensure_numeric
    6969
     70        # Initialise variabels
     71        self.A_can_be_reused = False
     72        self.point_coordinates = None
     73       
    7074        #Convert input to Numeric arrays
    7175        triangles = ensure_numeric(triangles, Int)
     
    143147
    144148            if verbose and i%((n+10)/10)==0: print 'Doing %d of %d' %(i, n)
     149
    145150            x = point_coordinates[i]
    146 
    147             #Find vertices near x
    148             candidate_vertices = self.root.search(x[0], x[1])
    149             is_more_elements = True
    150 
     151           
    151152            element_found, sigma0, sigma1, sigma2, k = \
    152                 self.search_triangles_of_vertices(candidate_vertices, x)
    153             first_expansion = True
    154             while not element_found and is_more_elements:
    155                 #if verbose: print 'Expanding search'
    156                 if first_expansion == True:
    157                     #self.expanded_quad_searches.append(1)
    158                     first_expansion = False
    159                 #else:
    160                     #end = len(self.expanded_quad_searches) - 1
    161                     #assert end >= 0
    162                     #self.expanded_quad_searches[end] += 1
    163                 candidate_vertices, branch = self.root.expand_search()
    164                 if branch == []:
    165                     # Searching all the verts from the root cell that haven't
    166                     # been searched.  This is the last try
    167                     element_found, sigma0, sigma1, sigma2, k = \
    168                       self.search_triangles_of_vertices(candidate_vertices, x)
    169                     is_more_elements = False
    170                 else:
    171                     element_found, sigma0, sigma1, sigma2, k = \
    172                       self.search_triangles_of_vertices(candidate_vertices, x)
    173 
    174                
     153                           self._search_tree_of_vertices(x)   
    175154            #Update interpolation matrix A if necessary
    176155            if element_found is True:
     
    186165                for j in js:
    187166                    A[i,j] = sigmas[j]
    188                    
    189167            else:
    190                 print 'Could not find triangle for point', x
    191 
    192 
    193 
     168                print 'Could not find triangle for point', x
     169               
    194170        return A
    195171
    196 
    197     def search_triangles_of_vertices(self,
     172    def _search_tree_of_vertices(self, x):
     173        """
     174        Find the triangle (element) that the point x is in.
     175
     176        Return the associated sigma and k values
     177           (and if the element was found) .
     178        """
     179        #Find triangle containing x:
     180        element_found = False
     181
     182        # This will be returned if element_found = False
     183        sigma2 = -10.0
     184        sigma0 = -10.0
     185        sigma1 = -10.0
     186        k = -10.0
     187           
     188        #Find vertices near x
     189        candidate_vertices = self.root.search(x[0], x[1])
     190        is_more_elements = True
     191
     192        element_found, sigma0, sigma1, sigma2, k = \
     193                       self._search_triangles_of_vertices(candidate_vertices, x)
     194        #FIXME Do we need this var?
     195        # Exclude points outside the mesh before removing this.
     196        #first_expansion = True
     197        while not element_found and is_more_elements:
     198            #if verbose: print 'Expanding search'
     199            #if first_expansion == True:
     200            #self.expanded_quad_searches.append(1)
     201            #first_expansion = False
     202            #else:
     203            #end = len(self.expanded_quad_searches) - 1
     204            #assert end >= 0
     205            #self.expanded_quad_searches[end] += 1
     206            candidate_vertices, branch = self.root.expand_search()
     207            if branch == []:
     208                # Searching all the verts from the root cell that haven't
     209                # been searched.  This is the last try
     210                element_found, sigma0, sigma1, sigma2, k = \
     211                      self._search_triangles_of_vertices(candidate_vertices, x)
     212                is_more_elements = False
     213            else:
     214                element_found, sigma0, sigma1, sigma2, k = \
     215                      self._search_triangles_of_vertices(candidate_vertices, x)
     216
     217        return element_found, sigma0, sigma1, sigma2, k
     218
     219    def _search_triangles_of_vertices(self,
    198220                                 candidate_vertices, x):
    199221            #Find triangle containing x:
     
    215237                #for each triangle id (k) which has v as a vertex
    216238                for k, _ in self.mesh.vertexlist[v]:
    217 
    218239                    #Get the three vertex_points of candidate triangle
    219240                    xi0 = self.mesh.get_vertex_coordinate(k, 0)
     
    221242                    xi2 = self.mesh.get_vertex_coordinate(k, 2)
    222243
    223                     #print "PDSG - k", k
    224                     #print "PDSG - xi0", xi0
    225                     #print "PDSG - xi1", xi1
    226                     #print "PDSG - xi2", xi2
    227                     #print "PDSG element %i verts((%f, %f),(%f, %f),(%f, %f))"\
    228                     #   % (k, xi0[0], xi0[1], xi1[0], xi1[1], xi2[0], xi2[1])
    229 
    230244                    #Get the three normals
    231245                    n0 = self.mesh.get_normal(k, 0)
     
    233247                    n2 = self.mesh.get_normal(k, 2)
    234248
    235 
    236249                    #Compute interpolation
    237250                    sigma2 = dot((x-xi0), n2)/dot((xi2-xi0), n2)
    238251                    sigma0 = dot((x-xi1), n0)/dot((xi0-xi1), n0)
    239252                    sigma1 = dot((x-xi2), n1)/dot((xi1-xi2), n1)
    240 
    241                     #print "PDSG - sigma0", sigma0
    242                     #print "PDSG - sigma1", sigma1
    243                     #print "PDSG - sigma2", sigma2
    244253
    245254                    #FIXME: Maybe move out to test or something
     
    264273
    265274
    266     #def get_A(self):
    267      #       return self.A.todense()
    268    
    269     def interpolate(self, f):
    270         """Interpolate mesh data f to points.
     275     # FIXME: What is a good start_blocking_count value?
     276    def interpolate(self, f, point_coordinates = None,
     277                    start_blocking_len = 500000, verbose=False):
     278        """Interpolate mesh data f to determine values, z, at points.
    271279
    272280        f is the data on the mesh vertices.
    273281
    274 
    275282        The mesh values representing a smooth surface are
    276         assumed to be specified in f. This argument could,
    277         for example have been obtained from the method self.fit()
    278 
    279         Pre Condition:
    280           self.A has been initialised
     283        assumed to be specified in f.
    281284
    282285        Inputs:
    283286          f: Vector or array of data at the mesh vertices.
    284           If f is an array, interpolation will be done for each column as
    285           per underlying matrix-matrix multiplication
     287              If f is an array, interpolation will be done for each column as
     288              per underlying matrix-matrix multiplication
     289          point_coordinates: Interpolate mesh data to these positions.
     290          start_blocking_len: If the # of points is more or greater than this,
     291              start blocking
    286292
    287293        Output:
    288           Interpolated values at data points implied in self.A
    289 
    290         """
    291 
     294          Interpolated values at inputted points (z).
     295        """
     296       
     297        # Can I interpolate, based on previous point_coordinates?
     298        if point_coordinates is None:
     299            if self.A_can_be_reused is True and \
     300            len(self.point_coordinates) < start_blocking_len:
     301                z = self._get_point_data_z(f,
     302                                           verbose=verbose)
     303            elif self.point_coordinates is not None:
     304                #     if verbose, give warning
     305                if verbose:
     306                    print 'WARNING: Recalculating A matrix, due to blocking.'
     307                point_coordinates = self.point_coordinates
     308            else:
     309                #There are no good point_coordinates. import sys; sys.exit()
     310                msg = 'ERROR (interpolate.py): No point_coordinates inputted'
     311                raise msg
     312           
     313        if point_coordinates is not None:
     314            self.point_coordinates = point_coordinates
     315            if len(point_coordinates) < start_blocking_len or \
     316                   start_blocking_len == 0:
     317                self.A_can_be_reused = True
     318                z = self.interpolate_block(f, point_coordinates,
     319                                           verbose=verbose)
     320            else:
     321                #Handle blocking
     322                self.A_can_be_reused = False
     323                start=0
     324                z = self.interpolate_block(f, point_coordinates[0:0])
     325                for end in range(start_blocking_len
     326                                 ,len(point_coordinates)
     327                                 ,start_blocking_len):
     328                    t = self.interpolate_block(f, point_coordinates[start:end],
     329                                               verbose=verbose)
     330                    z = concatenate((z,t))
     331                    start = end
     332                end = len(point_coordinates)
     333                t = self.interpolate_block(f, point_coordinates[start:end],
     334                                           verbose=verbose)
     335                z = concatenate((z,t))
     336        return z
     337
     338    def interpolate_block(self, f, point_coordinates = None, verbose=False):
     339        """
     340        Call this if you want to control the blocking or make sure blocking
     341        doesn't occur.
     342
     343        See interpolate for doc info.
     344        """
     345        if point_coordinates is not None:
     346            self.A =self._build_interpolation_matrix_A(point_coordinates,
     347                                                       verbose=verbose)
     348        return self._get_point_data_z(f)
     349
     350    def _get_point_data_z(self, f, verbose=False):
    292351        return self.A * f
     352       
    293353#-------------------------------------------------------------
    294354if __name__ == "__main__":
  • inundation/fit_interpolate/test_interpolate.py

    r2187 r2189  
    239239
    240240
    241 
     241    def test_interpolate_attributes_to_points(self):
     242        v0 = [0.0, 0.0]
     243        v1 = [0.0, 5.0]
     244        v2 = [5.0, 0.0]
     245
     246        vertices = [v0, v1, v2]
     247        triangles = [ [1,0,2] ]   #bac
     248
     249        d0 = [1.0, 1.0]
     250        d1 = [1.0, 2.0]
     251        d2 = [3.0, 1.0]
     252        point_coords = [ d0, d1, d2]
     253
     254        interp = Interpolate(vertices, triangles, point_coords)
     255        f = linear_function(vertices)
     256        z = interp.interpolate(f, point_coords)
     257        answer = linear_function(point_coords)
     258
     259
     260        assert allclose(z, answer)
     261
     262
     263
     264    def test_interpolate_attributes_to_pointsII(self):
     265        a = [-1.0, 0.0]
     266        b = [3.0, 4.0]
     267        c = [4.0, 1.0]
     268        d = [-3.0, 2.0] #3
     269        e = [-1.0, -2.0]
     270        f = [1.0, -2.0] #5
     271
     272        vertices = [a, b, c, d,e,f]
     273        triangles = [[0,1,3], [1,0,2], [0,4,5], [0,5,2]] #abd bac aef afc
     274
     275
     276        point_coords = [[-2.0, 2.0],
     277                        [-1.0, 1.0],
     278                        [0.0, 2.0],
     279                        [1.0, 1.0],
     280                        [2.0, 1.0],
     281                        [0.0, 0.0],
     282                        [1.0, 0.0],
     283                        [0.0, -1.0],
     284                        [-0.2, -0.5],
     285                        [-0.9, -1.5],
     286                        [0.5, -1.9],
     287                        [3.0, 1.0]]
     288
     289        interp = Interpolate(vertices, triangles)
     290        f = linear_function(vertices)
     291        z = interp.interpolate(f, point_coords)
     292        answer = linear_function(point_coords)
     293        #print "z",z
     294        #print "answer",answer
     295        assert allclose(z, answer)
     296
     297    def test_interpolate_attributes_to_pointsIII(self):
     298        """Test linear interpolation of known values at vertices to
     299        new points inside a triangle
     300        """
     301        a = [0.0, 0.0]
     302        b = [0.0, 5.0]
     303        c = [5.0, 0.0]
     304        d = [5.0, 5.0]
     305
     306        vertices = [a, b, c, d]
     307        triangles = [ [1,0,2], [2,3,1] ]   #bac, cdb
     308
     309        #Points within triangle 1
     310        d0 = [1.0, 1.0]
     311        d1 = [1.0, 2.0]
     312        d2 = [3.0, 1.0]
     313
     314        #Point within triangle 2
     315        d3 = [4.0, 3.0]
     316
     317        #Points on common edge
     318        d4 = [2.5, 2.5]
     319        d5 = [4.0, 1.0]
     320
     321        #Point on common vertex
     322        d6 = [0., 5.]
     323       
     324        point_coords = [d0, d1, d2, d3, d4, d5, d6]
     325
     326        interp = Interpolate(vertices, triangles)
     327
     328        #Known values at vertices
     329        #Functions are x+y, x+2y, 2x+y, x-y-5
     330        f = [ [0., 0., 0., -5.],        # (0,0)
     331              [5., 10., 5., -10.],      # (0,5)
     332              [5., 5., 10.0, 0.],       # (5,0)
     333              [10., 15., 15., -5.]]     # (5,5)
     334
     335        z = interp.interpolate(f, point_coords)
     336        answer = [ [2., 3., 3., -5.],   # (1,1)
     337                   [3., 5., 4., -6.],   # (1,2)
     338                   [4., 5., 7., -3.],   # (3,1)
     339                   [7., 10., 11., -4.], # (4,3)
     340                   [5., 7.5, 7.5, -5.], # (2.5, 2.5)
     341                   [5., 6., 9., -2.],   # (4,1)
     342                   [5., 10., 5., -10.]]  # (0,5)
     343
     344        #print "***********"
     345        #print "z",z
     346        #print "answer",answer
     347        #print "***********"
     348
     349        #Should an error message be returned if points are outside
     350        # of the mesh? Not currently. 
     351
     352        assert allclose(z, answer)
     353
     354
     355    def test_interpolate_point_outside_of_mesh(self):
     356        """Test linear interpolation of known values at vertices to
     357        new points inside a triangle
     358        """
     359        a = [0.0, 0.0]
     360        b = [0.0, 5.0]
     361        c = [5.0, 0.0]
     362        d = [5.0, 5.0]
     363
     364        vertices = [a, b, c, d]
     365        triangles = [ [1,0,2], [2,3,1] ]   #bac, cdb
     366
     367        #Far away point
     368        d7 = [-1., -1.]
     369       
     370        point_coords = [ d7]
     371        interp = Interpolate(vertices, triangles)
     372
     373        #Known values at vertices
     374        #Functions are x+y, x+2y, 2x+y, x-y-5
     375        f = [ [0., 0., 0., -5.],        # (0,0)
     376              [5., 10., 5., -10.],      # (0,5)
     377              [5., 5., 10.0, 0.],       # (5,0)
     378              [10., 15., 15., -5.]]     # (5,5)
     379
     380        z = interp.interpolate(f, point_coords)
     381        answer = [ [0., 0., 0., 0.]] # (-1,-1)
     382
     383        #print "***********"
     384        #print "z",z
     385        #print "answer",answer
     386        #print "***********"
     387
     388        #Should an error message be returned if points are outside
     389        # of the mesh? Not currently. 
     390
     391        assert allclose(z, answer)
     392
     393    def test_interpolate_attributes_to_pointsIV(self):
     394        a = [-1.0, 0.0]
     395        b = [3.0, 4.0]
     396        c = [4.0, 1.0]
     397        d = [-3.0, 2.0] #3
     398        e = [-1.0, -2.0]
     399        f = [1.0, -2.0] #5
     400
     401        vertices = [a, b, c, d,e,f]
     402        triangles = [[0,1,3], [1,0,2], [0,4,5], [0,5,2]] #abd bac aef afc
     403
     404
     405        point_coords = [[-2.0, 2.0],
     406                        [-1.0, 1.0],
     407                        [0.0, 2.0],
     408                        [1.0, 1.0],
     409                        [2.0, 1.0],
     410                        [0.0, 0.0],
     411                        [1.0, 0.0],
     412                        [0.0, -1.0],
     413                        [-0.2, -0.5],
     414                        [-0.9, -1.5],
     415                        [0.5, -1.9],
     416                        [3.0, 1.0]]
     417
     418        interp = Interpolate(vertices, triangles)
     419        f = array([linear_function(vertices),2*linear_function(vertices) ])
     420        f = transpose(f)
     421        #print "f",f
     422        z = interp.interpolate(f, point_coords)
     423        answer = [linear_function(point_coords),
     424                  2*linear_function(point_coords) ]
     425        answer = transpose(answer)
     426        #print "z",z
     427        #print "answer",answer
     428        assert allclose(z, answer)
     429
     430
     431    def test_interpolate_blocking(self):
     432        a = [-1.0, 0.0]
     433        b = [3.0, 4.0]
     434        c = [4.0, 1.0]
     435        d = [-3.0, 2.0] #3
     436        e = [-1.0, -2.0]
     437        f = [1.0, -2.0] #5
     438
     439        vertices = [a, b, c, d,e,f]
     440        triangles = [[0,1,3], [1,0,2], [0,4,5], [0,5,2]] #abd bac aef afc
     441
     442
     443        point_coords = [[-2.0, 2.0],
     444                        [-1.0, 1.0],
     445                        [0.0, 2.0],
     446                        [1.0, 1.0],
     447                        [2.0, 1.0],
     448                        [0.0, 0.0],
     449                        [1.0, 0.0],
     450                        [0.0, -1.0],
     451                        [-0.2, -0.5],
     452                        [-0.9, -1.5],
     453                        [0.5, -1.9],
     454                        [3.0, 1.0]]
     455
     456        interp = Interpolate(vertices, triangles)
     457        f = array([linear_function(vertices),2*linear_function(vertices) ])
     458        f = transpose(f)
     459        #print "f",f
     460        for blocking_max in range(len(point_coords)+2):
     461        #if True:
     462         #   blocking_max = 5
     463            z = interp.interpolate(f, point_coords,
     464                                   start_blocking_len=blocking_max)
     465            answer = [linear_function(point_coords),
     466                      2*linear_function(point_coords) ]
     467            answer = transpose(answer)
     468            #print "z",z
     469            #print "answer",answer
     470            assert allclose(z, answer)
     471
     472    def test_interpolate_reuse(self):
     473        a = [-1.0, 0.0]
     474        b = [3.0, 4.0]
     475        c = [4.0, 1.0]
     476        d = [-3.0, 2.0] #3
     477        e = [-1.0, -2.0]
     478        f = [1.0, -2.0] #5
     479
     480        vertices = [a, b, c, d,e,f]
     481        triangles = [[0,1,3], [1,0,2], [0,4,5], [0,5,2]] #abd bac aef afc
     482
     483
     484        point_coords = [[-2.0, 2.0],
     485                        [-1.0, 1.0],
     486                        [0.0, 2.0],
     487                        [1.0, 1.0],
     488                        [2.0, 1.0],
     489                        [0.0, 0.0],
     490                        [1.0, 0.0],
     491                        [0.0, -1.0],
     492                        [-0.2, -0.5],
     493                        [-0.9, -1.5],
     494                        [0.5, -1.9],
     495                        [3.0, 1.0]]
     496
     497        interp = Interpolate(vertices, triangles)
     498        f = array([linear_function(vertices),2*linear_function(vertices) ])
     499        f = transpose(f)
     500        z = interp.interpolate(f, point_coords,
     501                               start_blocking_len=20)
     502        answer = [linear_function(point_coords),
     503                  2*linear_function(point_coords) ]
     504        answer = transpose(answer)
     505        #print "z",z
     506        #print "answer",answer
     507        assert allclose(z, answer)
     508        assert allclose(interp.A_can_be_reused, True)
     509
     510        z = interp.interpolate(f)
     511        assert allclose(z, answer)
     512       
     513        # This causes blocking to occur.
     514        z = interp.interpolate(f, start_blocking_len=10)
     515        assert allclose(z, answer)
     516        assert allclose(interp.A_can_be_reused, False)
     517
     518        #A is recalculated
     519        z = interp.interpolate(f)
     520        assert allclose(z, answer)
     521        assert allclose(interp.A_can_be_reused, True)
     522
     523        interp = Interpolate(vertices, triangles)
     524        #Must raise an exception, no points specified
     525        try:
     526            z = interp.interpolate(f)
     527        except:
     528            pass
     529       
    242530
    243531#-------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.