Changeset 255


Ignore:
Timestamp:
Aug 31, 2004, 11:47:24 AM (21 years ago)
Author:
ole
Message:
 
Location:
inundation/ga/storm_surge/pyvolution
Files:
2 edited

Legend:

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

    r245 r255  
    352352           
    353353    def extrapolate_second_order(self):
    354         """Extrapolate conserved quantities from centroid to
    355         vertices for each volume using
    356         second order scheme.
    357         """
    358        
    359         a, b = self.compute_gradients()
    360 
    361         V = self.domain.get_vertex_coordinates()
    362         qc = self.centroid_values
    363         qv = self.vertex_values
    364        
    365         #Check each triangle
    366         for k in range(self.domain.number_of_elements):
    367             #Centroid coordinates           
    368             x, y = self.domain.centroids[k]
    369 
    370             #vertex coordinates
    371             x0, y0, x1, y1, x2, y2 = V[k,:]
    372 
    373             #Extrapolate
    374             qv[k,0] = qc[k] + a[k]*(x0-x) + b[k]*(y0-y)
    375             qv[k,1] = qc[k] + a[k]*(x1-x) + b[k]*(y1-y)
    376             qv[k,2] = qc[k] + a[k]*(x2-x) + b[k]*(y2-y)           
     354        #Call correct module function
     355        #(either from this module or C-extension)
     356        extrapolate_second_order(self)
     357
     358
     359def extrapolate_second_order(self):       
     360    """Extrapolate conserved quantities from centroid to
     361    vertices for each volume using
     362    second order scheme.
     363    """
     364       
     365    a, b = self.compute_gradients()
     366
     367    V = self.domain.get_vertex_coordinates()
     368    qc = self.centroid_values
     369    qv = self.vertex_values
     370   
     371    #Check each triangle
     372    for k in range(self.domain.number_of_elements):
     373        #Centroid coordinates           
     374        x, y = self.domain.centroids[k]
     375       
     376        #vertex coordinates
     377        x0, y0, x1, y1, x2, y2 = V[k,:]
     378       
     379        #Extrapolate
     380        qv[k,0] = qc[k] + a[k]*(x0-x) + b[k]*(y0-y)
     381        qv[k,1] = qc[k] + a[k]*(x1-x) + b[k]*(y1-y)
     382        qv[k,2] = qc[k] + a[k]*(x2-x) + b[k]*(y2-y)           
    377383
    378384           
     
    446452    #Replace python version with c implementations
    447453
    448     pass
    449     #from quantity_ext import limit
    450 
     454    from quantity_ext import limit #, extrapolate_second_order       
  • inundation/ga/storm_surge/pyvolution/quantity_ext.c

    r248 r255  
    3131
    3232
    33 void _limit(int N, double beta, double* qc, double* qv, double* qmin, double* qmax) {
    34 
    35   int k, i, ki;
    36   double dq, phi, r;
     33void _limit(int N, double beta, double* qc, double* qv,
     34            double* qmin, double* qmax) {
     35
     36  int k, i, k3;
     37  double dq, dqa[3], phi, r;
    3738 
    3839  for (k=0; k<N; k++) {
    39  
     40    k3 = k*3;
     41   
    4042    //Find the gradient limiter (phi) across vertices 
    4143    phi = 1.0;
    4244    for (i=0; i<3; i++) {   
    43       ki = k*3+i;
    4445      r = 1.0;
    4546     
    46       dq = qv[ki] - qc[k];    //Delta between vertex and centroid values
    47    
     47      dq = qv[k3+i] - qc[k];    //Delta between vertex and centroid values
     48      dqa[i] = dq;              //Save dq for use in the next loop
     49     
    4850      if (dq > 0.0) r = (qmax[k] - qc[k])/dq;
    4951      if (dq < 0.0) r = (qmin[k] - qc[k])/dq;     
    5052 
     53 
    5154      phi = min( min(r*beta, 1.0), phi);   
    5255    }
     56   
    5357    //Then update using phi limiter
    5458    for (i=0; i<3; i++) {   
    55       qv[ki] = qc[k] + phi*(qv[ki] - qc[k]); //FIXME: Could precompute dq (3 elements)
     59      qv[k3+i] = qc[k] + phi*dqa[i];
    5660    }
    5761  }
    58 
    59      
    60   /*           
    61     #Diffences between centroids and maxima/minima
    62     dqmax = qmax - qc
    63     dqmin = qmin - qc
    64        
    65     #Deltas between vertex and centroid values
    66     dq = zeros(qv.shape, Float)
    67     for i in range(3):
    68         dq[:,i] = qv[:,i] - qc
    69 
    70     #Phi limiter   
    71     for k in range(N):
    72        
    73         #Find the gradient limiter (phi) across vertices
    74         phi = 1.0
    75         for i in range(3):
    76             r = 1.0
    77             if (dq[k,i] > 0): r = dqmax[k]/dq[k,i]
    78             if (dq[k,i] < 0): r = dqmin[k]/dq[k,i]
    79            
    80             phi = min( min(r*beta, 1), phi )   
    81 
    82         #Then update using phi limiter
    83         for i in range(3):           
    84             qv[k,i] = qc[k] + phi*dq[k,i]
    85            
    86   */
    87  
    88 }
    89 
    90 // Gateway to Python
    91 //FIXME: DOES NOT WORK YET
    92 PyObject *limit(PyObject *self, PyObject *args) {
    93  
    94   PyObject *quantity;
    95  
    96   PyObject *Tmp;
    97  
     62}
     63
     64/////////////////////////////////////////////////
     65// Gateways to Python
     66
     67/*
     68PyObject *extrapolate_second_order(PyObject *self, PyObject *args) {
     69
     70  PyObject *quantity, *domain, *Tmp;
    9871  PyArrayObject
    9972    *qv, //Conserved quantities at vertices
     
    10174    *neighbours;
    10275   
    103   int k, i, n, N;
     76  int k, i, n, N, k3;
    10477  double beta; //Safety factor
    10578  double *qmin, *qmax, qn;
     
    10881  if (!PyArg_ParseTuple(args, "O", &quantity))
    10982    return NULL;
    110  
    111   //Get safety factor beta
    112   Tmp = PyObject_GetAttrString(quantity, "beta");
    113   beta = PyFloat_AsDouble(Tmp)
    114   Py_DECREF(Tmp);        
    115  
    116  
     83
     84  domain = PyObject_GetAttrString(quantity, "domain");     
     85  if (!domain)
     86    return NULL
     87   
     88  neighbours = (PyArrayObject*) PyObject_GetAttrString(domain, "neighbours");
     89
    11790  qc = (PyArrayObject*) PyObject_GetAttrString(quantity, "centroid_values");
    11891  qv = (PyArrayObject*) PyObject_GetAttrString(quantity, "vertex_values");   
    119  
    120   Tmp = PyObject_GetAttrString(quantity, "domain");     
    121   neighbours = (PyArrayObject*) PyObject_GetAttrString(Tmp, "neighbours");     
    122   Py_DECREF(Tmp);           
    12392  N = qc -> dimensions[0];
    124 
    125  
     93*/
     94  /*
     95def extrapolate_second_order(self):       
     96    """Extrapolate conserved quantities from centroid to
     97    vertices for each volume using
     98    second order scheme.
     99    """
     100       
     101    a, b = self.compute_gradients()
     102
     103    V = self.domain.get_vertex_coordinates()
     104    qc = self.centroid_values
     105    qv = self.vertex_values
     106   
     107    #Check each triangle
     108    for k in range(self.domain.number_of_elements):
     109        #Centroid coordinates           
     110        x, y = self.domain.centroids[k]
     111       
     112        #vertex coordinates
     113        x0, y0, x1, y1, x2, y2 = V[k,:]
     114       
     115        #Extrapolate
     116        qv[k,0] = qc[k] + a[k]*(x0-x) + b[k]*(y0-y)
     117        qv[k,1] = qc[k] + a[k]*(x1-x) + b[k]*(y1-y)
     118        qv[k,2] = qc[k] + a[k]*(x2-x) + b[k]*(y2-y)           
     119  */
     120//}   
     121
     122
     123
     124PyObject *limit(PyObject *self, PyObject *args) {
     125 
     126  PyObject *quantity, *domain, *Tmp;
     127  PyArrayObject
     128    *qv, //Conserved quantities at vertices
     129    *qc, //Conserved quantities at centroids
     130    *neighbours;
     131   
     132  int k, i, n, N, k3;
     133  double beta; //Safety factor
     134  double *qmin, *qmax, qn;
     135 
     136  // Convert Python arguments to C 
     137  if (!PyArg_ParseTuple(args, "O", &quantity))
     138    return NULL;
     139
     140  domain = PyObject_GetAttrString(quantity, "domain");     
     141  if (!domain)
     142    return NULL; 
     143   
     144  neighbours = (PyArrayObject*) PyObject_GetAttrString(domain, "neighbours");
     145
     146  //Get safety factor beta
     147  Tmp = PyObject_GetAttrString(domain, "beta");
     148  if (!Tmp)
     149    return NULL;
     150     
     151  beta = PyFloat_AsDouble(Tmp); 
     152 
     153  Py_DECREF(Tmp);   
     154  Py_DECREF(domain);     
     155
     156  qc = (PyArrayObject*) PyObject_GetAttrString(quantity, "centroid_values");
     157  qv = (PyArrayObject*) PyObject_GetAttrString(quantity, "vertex_values");   
     158  N = qc -> dimensions[0];
     159   
    126160  //Find min and max of this and neighbour's centroid values
    127161  qmin = malloc(N * sizeof(double));
    128162  qmax = malloc(N * sizeof(double)); 
    129163  for (k=0; k<N; k++) {
    130     qmax[k] = qmin[k] = ((double*) qc -> data)[k];
     164    k3=k*3;
     165   
     166    qmin[k] = ((double*) qc -> data)[k];
     167    qmax[k] = qmin[k];
     168   
    131169    for (i=0; i<3; i++) {
    132       n = ((int*) neighbours -> data)[k*3+i];
     170      n = ((int*) neighbours -> data)[k3+i];
    133171      if (n >= 0) {
    134172        qn = ((double*) qc -> data)[n]; //Neighbour's centroid value
     
    141179 
    142180  // Call underlying routine
    143   //_limit(N, beta, (double*) qc -> data, (double*) qv -> data, qmin, qmax);
     181  _limit(N, beta, (double*) qc -> data, (double*) qv -> data, qmin, qmax);
    144182         
    145183  free(qmin);
Note: See TracChangeset for help on using the changeset viewer.