Ignore:
Timestamp:
Sep 1, 2004, 5:26:59 AM (20 years ago)
Author:
ole
Message:

extrapolate 2 order - c implementation

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

Legend:

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

    r258 r262  
    8181        #Allocate space for geometric quantities
    8282        self.centroids = zeros((N, 2), Float)
     83        #FIXME: Should be renamed to centroid_coordinates
     84       
    8385        self.areas = zeros(N, Float)
    8486        self.radii = zeros(N, Float)
  • inundation/ga/storm_surge/pyvolution/quantity.py

    r261 r262  
    451451    #Replace python version with c implementations
    452452       
    453     from quantity_ext import limit, compute_gradients #, extrapolate_second_order       
     453    from quantity_ext import limit, compute_gradients,\
     454    extrapolate_second_order       
  • inundation/ga/storm_surge/pyvolution/quantity_ext.c

    r261 r262  
    9494
    9595
    96 
    97 
     96int _extrapolate(int N,
     97                 double* centroids,
     98                 double* centroid_values,               
     99                 double* vertex_coordinates,
     100                 double* vertex_values,
     101                 double* a,
     102                 double* b) {
     103 
     104  int k, k2, k3, k6;
     105  double x, y, x0, y0, x1, y1, x2, y2;
     106                     
     107  for (k=0; k<N; k++) {
     108    k6 = 6*k;
     109    k3 = 3*k;   
     110    k2 = 2*k;
     111       
     112    //Centroid coordinates           
     113    x = centroids[k2]; y = centroids[k2+1];
     114
     115    //vertex coordinates
     116    //x0, y0, x1, y1, x2, y2 = X[k,:]
     117    x0 = vertex_coordinates[k6 + 0];
     118    y0 = vertex_coordinates[k6 + 1];   
     119    x1 = vertex_coordinates[k6 + 2];
     120    y1 = vertex_coordinates[k6 + 3];       
     121    x2 = vertex_coordinates[k6 + 4];
     122    y2 = vertex_coordinates[k6 + 5];           
     123
     124    //Extrapolate
     125    vertex_values[k3+0] = centroid_values[k] + a[k]*(x0-x) + b[k]*(y0-y);
     126    vertex_values[k3+1] = centroid_values[k] + a[k]*(x1-x) + b[k]*(y1-y);
     127    vertex_values[k3+2] = centroid_values[k] + a[k]*(x2-x) + b[k]*(y2-y);
     128   
     129    /*
     130    printf("V %f, %f, %f\n", vertex_values[k3+0],
     131           vertex_values[k3+1],
     132           vertex_values[k3+2]);
     133    */
     134           
     135    //printf("k=%d, a=%f, b=%f\n", k, a[k], b[k]);
     136   
     137           
     138    //printf("C %f, %f, %f\n", centroid_values[k],
     139    //     centroid_values[k],
     140    //     centroid_values[k]);           
     141           
     142    //printf("X %f, %f, %f, %f, %f, %f\n", x0, y0, x1, y1, x2, y2);
     143  }
     144  return 0;
     145}
     146
     147
     148 
    98149/////////////////////////////////////////////////
    99150// Gateways to Python
    100 
    101 
    102 
    103151PyObject *compute_gradients(PyObject *self, PyObject *args) {
    104152 
    105   PyObject *quantity, *domain;
     153  PyObject *quantity, *domain, *R;
    106154  PyArrayObject
    107155    *centroids,            //Coordinates at centroids
     
    162210  }
    163211                     
    164  
    165 //Return values
    166   return Py_BuildValue("OO", PyArray_Return(a), PyArray_Return(b));
     212  //Release                 
     213  Py_DECREF(centroids);   
     214  Py_DECREF(centroid_values);   
     215  Py_DECREF(number_of_boundaries);
     216  Py_DECREF(surrogate_neighbours);           
     217         
     218  //Build result, release and return
     219  R = Py_BuildValue("OO", PyArray_Return(a), PyArray_Return(b));
     220  Py_DECREF(a);     
     221  Py_DECREF(b);       
     222  return R;
    167223}
    168224
    169225
    170 /*
     226
    171227PyObject *extrapolate_second_order(PyObject *self, PyObject *args) {
    172 
    173 
    174 
    175 PyObject *compute_gradients(PyObject *self, PyObject *args) {
    176228 
    177229  PyObject *quantity, *domain;
     
    179231    *centroids,            //Coordinates at centroids
    180232    *centroid_values,      //Values at centroids   
     233    *vertex_coordinates,   //Coordinates at vertices           
     234    *vertex_values,        //Values at vertices       
    181235    *number_of_boundaries, //Number of boundaries for each triangle
    182236    *surrogate_neighbours, //True neighbours or - if one missing - self
    183     *a, *b;                //Return values
     237    *a, *b;                //Gradients
    184238   
    185   int dimensions[1], N, err;
     239  //int N, err;
     240  int dimensions[1], N, err; 
     241  //double *a, *b;  //Gradients
    186242 
    187243  // Convert Python arguments to C 
     
    208264    PyObject_GetAttrString(domain, "number_of_boundaries");           
    209265  if (!number_of_boundaries) return NULL;           
     266 
     267  vertex_coordinates = (PyArrayObject*)
     268    PyObject_GetAttrString(domain, "vertex_coordinates");           
     269  if (!vertex_coordinates) return NULL;             
     270 
     271  vertex_values = (PyArrayObject*)
     272    PyObject_GetAttrString(quantity, "vertex_values");           
     273  if (!vertex_values) return NULL;               
    210274 
    211275  N = centroid_values -> dimensions[0];
     
    218282  a = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE);
    219283  b = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE); 
    220        
     284
     285  //FIXME: Odd that I couldn't use normal arrays         
     286  //Allocate space for return vectors a and b (don't DECREF)
     287  //a = (double*) malloc(N * sizeof(double));
     288  //if (!a) return NULL; 
     289  //b = (double*) malloc(N * sizeof(double)); 
     290  //if (!b) return NULL;
    221291
    222292 
     
    227297                           (int*) surrogate_neighbours -> data,
    228298                           (double*) a -> data,
    229                            (double*) b -> data);     
     299                           (double*) b -> data);
    230300                           
    231301  if (err != 0) {
     
    233303    return NULL;
    234304  }
    235 
    236 
    237   PyObject *quantity, *domain, *Tmp;
    238   PyArrayObject
    239     *qv, //Conserved quantities at vertices
    240     *qc, //Conserved quantities at centroids
    241     *neighbours;
    242    
    243   int k, i, n, N, k3;
    244   double beta; //Safety factor
    245   double *qmin, *qmax, qn;
    246  
    247   // Convert Python arguments to C 
    248   if (!PyArg_ParseTuple(args, "O", &quantity))
    249     return NULL;
    250 
    251   domain = PyObject_GetAttrString(quantity, "domain");     
    252   if (!domain)
    253     return NULL; 
    254    
    255   neighbours = (PyArrayObject*) PyObject_GetAttrString(domain, "neighbours");
    256 
    257   qc = (PyArrayObject*) PyObject_GetAttrString(quantity, "centroid_values");
    258   qv = (PyArrayObject*) PyObject_GetAttrString(quantity, "vertex_values");   
    259   N = qc -> dimensions[0];
    260 */
    261   /*
    262 def extrapolate_second_order(self):       
    263     """Extrapolate conserved quantities from centroid to
    264     vertices for each volume using
    265     second order scheme.
    266     """
    267        
    268     a, b = self.compute_gradients()
    269 
    270     V = self.domain.get_vertex_coordinates()
    271     qc = self.centroid_values
    272     qv = self.vertex_values
    273    
    274     #Check each triangle
    275     for k in range(self.domain.number_of_elements):
    276         #Centroid coordinates           
    277         x, y = self.domain.centroids[k]
    278        
    279         #vertex coordinates
    280         x0, y0, x1, y1, x2, y2 = V[k,:]
    281        
    282         #Extrapolate
    283         qv[k,0] = qc[k] + a[k]*(x0-x) + b[k]*(y0-y)
    284         qv[k,1] = qc[k] + a[k]*(x1-x) + b[k]*(y1-y)
    285         qv[k,2] = qc[k] + a[k]*(x2-x) + b[k]*(y2-y)           
    286   */
    287 //}   
     305 
     306  err = _extrapolate(N,
     307                     (double*) centroids -> data,
     308                     (double*) centroid_values -> data,             
     309                     (double*) vertex_coordinates -> data,
     310                     (double*) vertex_values -> data,
     311                     (double*) a -> data,
     312                     (double*) b -> data);                   
     313  //a, b);
     314                     
     315                     
     316  if (err != 0) {
     317    PyErr_SetString(PyExc_RuntimeError,
     318                    "Internal function _extrapolate failed");
     319    return NULL;
     320  }                 
     321               
     322 
     323
     324  //Release 
     325  Py_DECREF(centroids);   
     326  Py_DECREF(centroid_values);   
     327  Py_DECREF(number_of_boundaries);
     328  Py_DECREF(surrogate_neighbours);
     329  Py_DECREF(vertex_coordinates);                   
     330  Py_DECREF(vertex_values);                 
     331  Py_DECREF(a);                   
     332  Py_DECREF(b);                     
     333  //free(a);     
     334  //free(b);       
     335 
     336  return Py_BuildValue("");   
     337}   
    288338
    289339
     
    359409  {"limit", limit, METH_VARARGS, "Print out"},   
    360410  {"compute_gradients", compute_gradients, METH_VARARGS, "Print out"},     
     411  {"extrapolate_second_order", extrapolate_second_order,
     412   METH_VARARGS, "Print out"},       
    361413  {NULL, NULL, 0, NULL}   /* sentinel */
    362414};
  • inundation/ga/storm_surge/pyvolution/test_quantity.py

    r261 r262  
    194194        quantity.set_values([2.0, 4.0, 8.0, 2.0],
    195195                            location = 'centroids')
    196        
     196
     197
     198
    197199        #Gradients
    198200        a, b = quantity.compute_gradients()
    199 
    200201
    201202        #gradient bewteen t0 and t1 is undefined as det==0
     
    209210
    210211        quantity.extrapolate_second_order()
    211        
     212
     213        #print quantity.vertex_values
    212214        assert allclose(quantity.vertex_values, [[2., 2.,  2.],
    213215                                                 [0., 6.,  6.],
     
    215217                                                 [0., 0.,  6.]])
    216218
    217 
    218 
     219               
    219220    def test_second_order_extrapolation2(self):
    220221        quantity = Conserved_quantity(self.mesh4)       
Note: See TracChangeset for help on using the changeset viewer.