source: inundation/ga/storm_surge/pyvolution/quantity_ext.c @ 248

Last change on this file since 248 was 248, checked in by ole, 21 years ago
File size: 4.0 KB
Line 
1// Python - C extension for quantity module.
2//
3// To compile (Python2.3):
4//  gcc -c util_ext.c -I/usr/include/python2.3 -o util_ext.o -Wall -O
5//  gcc -shared util_ext.o  -o util_ext.so     
6//
7// See the module quantity.py
8//
9//
10// Ole Nielsen, GA 2004
11       
12#include "Python.h"
13#include "Numeric/arrayobject.h"
14#include "math.h"
15
16
17//FIXME: Should live in util_ext.c
18double max(double x, double y) { 
19  //Return maximum of two doubles
20 
21  if (x > y) return x;
22  else return y;
23}
24
25double min(double x, double y) { 
26  //Return minimum of two doubles
27 
28  if (x < y) return x;
29  else return y;
30}
31
32
33void _limit(int N, double beta, double* qc, double* qv, double* qmin, double* qmax) { 
34
35  int k, i, ki;
36  double dq, phi, r;
37 
38  for (k=0; k<N; k++) {
39 
40    //Find the gradient limiter (phi) across vertices 
41    phi = 1.0;
42    for (i=0; i<3; i++) {   
43      ki = k*3+i;
44      r = 1.0;
45     
46      dq = qv[ki] - qc[k];    //Delta between vertex and centroid values
47   
48      if (dq > 0.0) r = (qmax[k] - qc[k])/dq;
49      if (dq < 0.0) r = (qmin[k] - qc[k])/dq;     
50 
51      phi = min( min(r*beta, 1.0), phi);   
52    }
53    //Then update using phi limiter
54    for (i=0; i<3; i++) {   
55      qv[ki] = qc[k] + phi*(qv[ki] - qc[k]); //FIXME: Could precompute dq (3 elements)
56    }
57  }
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
92PyObject *limit(PyObject *self, PyObject *args) {
93 
94  PyObject *quantity;
95 
96  PyObject *Tmp;
97 
98  PyArrayObject
99    *qv, //Conserved quantities at vertices
100    *qc, //Conserved quantities at centroids
101    *neighbours;
102   
103  int k, i, n, N;
104  double beta; //Safety factor
105  double *qmin, *qmax, qn;
106 
107  // Convert Python arguments to C 
108  if (!PyArg_ParseTuple(args, "O", &quantity)) 
109    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 
117  qc = (PyArrayObject*) PyObject_GetAttrString(quantity, "centroid_values"); 
118  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);           
123  N = qc -> dimensions[0];
124
125 
126  //Find min and max of this and neighbour's centroid values
127  qmin = malloc(N * sizeof(double));
128  qmax = malloc(N * sizeof(double)); 
129  for (k=0; k<N; k++) {
130    qmax[k] = qmin[k] = ((double*) qc -> data)[k];
131    for (i=0; i<3; i++) {
132      n = ((int*) neighbours -> data)[k*3+i];
133      if (n >= 0) {
134        qn = ((double*) qc -> data)[n]; //Neighbour's centroid value
135         
136        qmin[k] = min(qmin[k], qn);
137        qmax[k] = max(qmax[k], qn);
138      }
139    }
140  }
141 
142  // Call underlying routine
143  //_limit(N, beta, (double*) qc -> data, (double*) qv -> data, qmin, qmax);
144         
145  free(qmin);
146  free(qmax); 
147  return Py_BuildValue(""); 
148}
149
150
151
152// Method table for python module
153static struct PyMethodDef MethodTable[] = {
154  {"limit", limit, METH_VARARGS, "Print out"},   
155  {NULL, NULL, 0, NULL}   /* sentinel */
156};
157
158// Module initialisation   
159void initquantity_ext(void){
160  Py_InitModule("quantity_ext", MethodTable);
161 
162  import_array();     //Necessary for handling of NumPY structures 
163}
164
Note: See TracBrowser for help on using the repository browser.