Changeset 260 for inundation/ga


Ignore:
Timestamp:
Sep 1, 2004, 3:31:13 AM (20 years ago)
Author:
ole
Message:

Cleaned up compute_gradients. Prepared for c extension

Location:
inundation/ga/storm_surge/pyvolution
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • inundation/ga/storm_surge/pyvolution/quantity.py

    r259 r260  
    255255
    256256    def compute_gradients(self):
    257         """Compute gradients of triangle surfaces defined by centroids of
    258         neighbouring volumes.
    259         If one face is on the boundary, use own centroid as neighbour centroid.
    260         If two or more are on the boundary, fall back to first order scheme.
    261        
    262         Also return minimum and maximum of conserved quantities
    263         """
    264 
    265        
    266         from Numeric import array, zeros, Float
    267         from util import gradient
    268 
    269         N = self.centroid_values.shape[0]
    270 
    271         a = zeros(N, Float)
    272         b = zeros(N, Float)
    273        
    274         for k in range(N):
    275        
    276             number_of_boundaries = self.domain.number_of_boundaries[k]
    277 
    278             if number_of_boundaries == 3:                 
    279                 #We have zero neighbouring volumes -
    280                 #Fall back to first order scheme
    281                 pass
    282            
    283             elif number_of_boundaries == 2:
    284                 #Special case where we have only one neighbouring volume.
    285 
    286                 #Find index of the one neighbour
    287                 for k0 in self.domain.neighbours[k,:]:
    288                     if k0 >= 0:
    289                         break
    290 
    291                 assert k0 != k
    292                 assert k0 >= 0
    293 
    294                 k1 = k  #Self
    295 
    296                 #Get data
    297                 q0 = self.centroid_values[k0]
    298                 q1 = self.centroid_values[k1]
    299 
    300                 x0, y0 = self.domain.centroids[k0] #V0 centroid
    301                 x1, y1 = self.domain.centroids[k1] #V1 centroid       
    302 
    303                 #Gradient
    304                 det = x0*y1 - x1*y0
    305                 if det != 0.0:
    306                     a[k] = (y1*q0 - y0*q1)/det
    307                     b[k] = (x0*q1 - x1*q0)/det
    308 
    309             else:
    310                 #One or zero missing neighbours
    311                 #In case of one boundary - own centroid
    312                 #has been inserted as a surrogate for the one
    313                 #missing neighbour in neighbour_surrogates
    314 
    315                 #Get data       
    316                 k0 = self.domain.surrogate_neighbours[k,0]
    317                 k1 = self.domain.surrogate_neighbours[k,1]
    318                 k2 = self.domain.surrogate_neighbours[k,2]
    319 
    320                 q0 = self.centroid_values[k0]
    321                 q1 = self.centroid_values[k1]
    322                 q2 = self.centroid_values[k2]                   
    323 
    324                 x0, y0 = self.domain.centroids[k0] #V0 centroid
    325                 x1, y1 = self.domain.centroids[k1] #V1 centroid
    326                 x2, y2 = self.domain.centroids[k2] #V2 centroid
    327 
    328                 #Gradient
    329                 a[k], b[k] = gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2)
    330        
    331         return a, b
    332        
     257        #Call correct module function
     258        #(either from this module or C-extension)
     259        return compute_gradients(self)
     260           
    333261
    334262    def limit(self):
     
    365293    a, b = self.compute_gradients()
    366294
    367     V = self.domain.get_vertex_coordinates()
     295    X = self.domain.get_vertex_coordinates()
    368296    qc = self.centroid_values
    369297    qv = self.vertex_values
     
    375303       
    376304        #vertex coordinates
    377         x0, y0, x1, y1, x2, y2 = V[k,:]
     305        x0, y0, x1, y1, x2, y2 = X[k,:]
    378306       
    379307        #Extrapolate
     
    382310        qv[k,2] = qc[k] + a[k]*(x2-x) + b[k]*(y2-y)           
    383311
    384            
     312
     313def compute_gradients(quantity):                   
     314    """Compute gradients of triangle surfaces defined by centroids of
     315    neighbouring volumes.
     316    If one edge is on the boundary, use own centroid as neighbour centroid.
     317    If two or more are on the boundary, fall back to first order scheme.
     318    """
     319
     320    from Numeric import zeros, Float
     321    from util import gradient
     322   
     323    centroids = quantity.domain.centroids
     324    surrogate_neighbours = quantity.domain.surrogate_neighbours   
     325    centroid_values = quantity.centroid_values   
     326    number_of_boundaries = quantity.domain.number_of_boundaries     
     327   
     328    N = centroid_values.shape[0]
     329
     330    a = zeros(N, Float)
     331    b = zeros(N, Float)
     332   
     333    for k in range(N):
     334        if number_of_boundaries[k] < 2:
     335            #Two or three true neighbours
     336
     337            #Get indices of neighbours (or self when used as surrogate)     
     338            k0, k1, k2 = surrogate_neighbours[k,:]
     339
     340            q0 = centroid_values[k0]
     341            q1 = centroid_values[k1]
     342            q2 = centroid_values[k2]                   
     343
     344            x0, y0 = centroids[k0] #V0 centroid
     345            x1, y1 = centroids[k1] #V1 centroid
     346            x2, y2 = centroids[k2] #V2 centroid
     347
     348            #Gradient
     349            a[k], b[k] = gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2)
     350       
     351        elif number_of_boundaries[k] == 2:
     352            #One true neighbour
     353
     354            #Get index of the one neighbour
     355            for k0 in surrogate_neighbours[k,:]:
     356                if k0 != k: break
     357            assert k0 != k
     358
     359            k1 = k  #self
     360
     361            #Get data
     362            q0 = centroid_values[k0]
     363            q1 = centroid_values[k1]
     364
     365            x0, y0 = centroids[k0] #V0 centroid
     366            x1, y1 = centroids[k1] #V1 centroid       
     367
     368            #Gradient
     369            det = x0*y1 - x1*y0
     370            if det != 0.0:
     371                a[k] = (y1*q0 - y0*q1)/det
     372                b[k] = (x0*q1 - x1*q0)/det
     373
     374        else:
     375            #No true neighbours -       
     376            #Fall back to first order scheme
     377            pass
     378       
     379   
     380    return a, b
     381       
     382                   
    385383
    386384def limit(quantity):       
     
    452450    #Replace python version with c implementations
    453451       
    454     from quantity_ext import limit #, extrapolate_second_order       
     452    from quantity_ext import limit #, compute_gradients #, extrapolate_second_order       
  • inundation/ga/storm_surge/pyvolution/quantity_ext.c

    r258 r260  
    2020/////////////////////////////////////////////////
    2121// Gateways to Python
     22
     23
     24
     25
     26
     27/*
     28
     29def compute_gradients(quantity):                   
     30    """Compute gradients of triangle surfaces defined by centroids of
     31    neighbouring volumes.
     32    If one edge is on the boundary, use own centroid as neighbour centroid.
     33    If two or more are on the boundary, fall back to first order scheme.
     34    """
     35
     36    from Numeric import zeros, Float
     37    from util import gradient
     38   
     39    centroids = quantity.domain.centroids
     40    surrogate_neighbours = quantity.domain.surrogate_neighbours   
     41    centroid_values = quantity.centroid_values   
     42    number_of_boundaries = quantity.domain.number_of_boundaries     
     43   
     44    N = centroid_values.shape[0]
     45
     46    a = zeros(N, Float)
     47    b = zeros(N, Float)
     48   
     49    for k in range(N):
     50        if number_of_boundaries[k] < 2:
     51            #Two or three true neighbours
     52
     53            #Get indices of neighbours (or self when used as surrogate)     
     54            k0, k1, k2 = surrogate_neighbours[k,:]
     55
     56            q0 = centroid_values[k0]
     57            q1 = centroid_values[k1]
     58            q2 = centroid_values[k2]                   
     59
     60            x0, y0 = centroids[k0] #V0 centroid
     61            x1, y1 = centroids[k1] #V1 centroid
     62            x2, y2 = centroids[k2] #V2 centroid
     63
     64            #Gradient
     65            a[k], b[k] = gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2)
     66       
     67        elif number_of_boundaries[k] == 2:
     68            #One true neighbour
     69
     70            #Get index of the one neighbour
     71            for k0 in surrogate_neighbours[k,:]:
     72                if k0 != k: break
     73            assert k0 != k
     74
     75            k1 = k  #self
     76
     77            #Get data
     78            q0 = centroid_values[k0]
     79            q1 = centroid_values[k1]
     80
     81            x0, y0 = centroids[k0] #V0 centroid
     82            x1, y1 = centroids[k1] #V1 centroid       
     83
     84            #Gradient
     85            det = x0*y1 - x1*y0
     86            if det != 0.0:
     87                a[k] = (y1*q0 - y0*q1)/det
     88                b[k] = (x0*q1 - x1*q0)/det
     89
     90        else:
     91            #No true neighbours -       
     92            #Fall back to first order scheme
     93            pass
     94       
     95   
     96    return a, b
     97       
     98*/
     99
     100
     101
     102
     103
     104
     105
     106
     107
     108
    22109
    23110/*
  • inundation/ga/storm_surge/pyvolution/shallow_water.py

    r259 r260  
    936936    #Replace python version with c implementations
    937937   
    938     pass
    939938    from shallow_water_ext import rotate
    940939    compute_fluxes = compute_fluxes_c
  • inundation/ga/storm_surge/pyvolution/shallow_water_ext.c

    r259 r260  
    302302  _rotate((double *) r -> data, n1, n2);
    303303
    304 
     304  //Release numeric arrays
    305305  Py_DECREF(q);   
    306306  Py_DECREF(normal);
Note: See TracChangeset for help on using the changeset viewer.