source: inundation/ga/storm_surge/pyvolution/util_ext.h @ 1120

Last change on this file since 1120 was 907, checked in by ole, 20 years ago

Addressed problem with artificial momentum generated by discontinuous water depths in the presence of steep slopes.
Now very shallow water is limited with a separate h-limiter controlled by beta_h
(see config.py) for details.

File size: 2.8 KB
Line 
1// Python - C extension for finite_volumes util 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 util.py
8//
9//
10// Ole Nielsen, GA 2004
11       
12#include "Python.h"     
13#include "Numeric/arrayobject.h"
14#include "math.h"
15
16
17double max(double x, double y) { 
18  //Return maximum of two doubles
19 
20  if (x > y) return x;
21  else return y;
22}
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
33int _gradient(double x0, double y0, 
34              double x1, double y1, 
35              double x2, double y2, 
36              double q0, double q1, double q2, 
37              double *a, double *b) {
38
39  double det;
40 
41  det = (y2-y0)*(x1-x0) - (y1-y0)*(x2-x0);
42
43  *a = (y2-y0)*(q1-q0) - (y1-y0)*(q2-q0);
44  *a /= det;
45
46  *b = (x1-x0)*(q2-q0) - (x2-x0)*(q1-q0);
47  *b /= det;
48
49  return 0;
50}
51
52
53void _limit(int N, double beta, double* qc, double* qv, 
54            double* qmin, double* qmax) { 
55
56  //N are the number of elements
57  int k, i, k3;
58  double dq, dqa[3], phi, r;
59 
60  //printf("INSIDE\n");
61  for (k=0; k<N; k++) {
62    k3 = k*3;
63   
64    //Find the gradient limiter (phi) across vertices 
65    phi = 1.0;
66    for (i=0; i<3; i++) {   
67      r = 1.0;
68     
69      dq = qv[k3+i] - qc[k];    //Delta between vertex and centroid values
70      dqa[i] = dq;              //Save dq for use in the next loop
71     
72      if (dq > 0.0) r = (qmax[k] - qc[k])/dq;
73      if (dq < 0.0) r = (qmin[k] - qc[k])/dq;     
74 
75 
76      phi = min( min(r*beta, 1.0), phi);   
77    }
78   
79    //Then update using phi limiter
80    for (i=0; i<3; i++) {   
81      qv[k3+i] = qc[k] + phi*dqa[i];
82    }
83  }
84}
85
86
87void print_numeric_array(PyArrayObject *x) { 
88  int i, j;
89  for (i=0; i<x->dimensions[0]; i++) { 
90    for (j=0; j<x->dimensions[1]; j++) {
91      printf("%f ", *(double*) (x->data + i*x->strides[0] + j*x->strides[1]));
92    }
93    printf("\n"); 
94  }
95  printf("\n");   
96}
97
98void print_numeric_vector(PyArrayObject *x) { 
99  int i;
100  for (i=0; i<x->dimensions[0]; i++) {
101    printf("%f ", *(double*) (x->data + i*x->strides[0])); 
102  }
103  printf("\n"); 
104}
105
106PyArrayObject *get_consecutive_array(PyObject *O, char *name) {
107  PyArrayObject *A, *B;
108 
109
110  //Get array object from attribute
111 
112  /*
113  //FIXME: THE TEST DOESN't WORK
114  printf("Err = %d\n", PyObject_HasAttrString(O, name));
115  if (PyObject_HasAttrString(O, name) == 1) {
116    B = (PyArrayObject*) PyObject_GetAttrString(O, name);
117    if (!B) return NULL;
118  } else {
119    return NULL;
120    }
121  */
122   
123  B = (PyArrayObject*) PyObject_GetAttrString(O, name);
124  if (!B) return NULL;     
125 
126  //Convert to consecutive array
127  A = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*) B, B -> descr -> type, 0, 0);
128 
129  Py_DECREF(B); //FIXME: Is this really needed??
130 
131  if (!A) return NULL;
132  return A;
133}
134
Note: See TracBrowser for help on using the repository browser.