Changeset 261 for inundation/ga/storm_surge
- Timestamp:
- Sep 1, 2004, 4:16:18 AM (20 years ago)
- Location:
- inundation/ga/storm_surge/pyvolution
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/quantity.py
r260 r261 338 338 k0, k1, k2 = surrogate_neighbours[k,:] 339 339 340 #Get data 340 341 q0 = centroid_values[k0] 341 342 q1 = centroid_values[k1] … … 450 451 #Replace python version with c implementations 451 452 452 from quantity_ext import limit #, compute_gradients #, extrapolate_second_order453 from quantity_ext import limit, compute_gradients #, extrapolate_second_order -
inundation/ga/storm_surge/pyvolution/quantity_ext.c
r260 r261 18 18 #include "quantity_ext.h" 19 19 20 21 22 int _compute_gradients(int N, 23 double* centroids, 24 double* centroid_values, 25 int* number_of_boundaries, 26 int* surrogate_neighbours, 27 double* a, 28 double* b) { 29 30 int i, k, k0, k1, k2, index3; 31 double x0, x1, x2, y0, y1, y2, q0, q1, q2, det; 32 33 34 for (k=0; k<N; k++) { 35 index3 = 3*k; 36 37 if (number_of_boundaries[k] < 2) { 38 //Two or three true neighbours 39 40 //Get indices of neighbours (or self when used as surrogate) 41 //k0, k1, k2 = surrogate_neighbours[k,:] 42 43 k0 = surrogate_neighbours[index3 + 0]; 44 k1 = surrogate_neighbours[index3 + 1]; 45 k2 = surrogate_neighbours[index3 + 2]; 46 if (k0 == k1 || k1 == k2) return -1; 47 48 //Get data 49 q0 = centroid_values[k0]; 50 q1 = centroid_values[k1]; 51 q2 = centroid_values[k2]; 52 53 x0 = centroids[k0*2]; y0 = centroids[k0*2+1]; 54 x1 = centroids[k1*2]; y1 = centroids[k1*2+1]; 55 x2 = centroids[k2*2]; y2 = centroids[k2*2+1]; 56 57 //Gradient 58 _gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2, &a[k], &b[k]); 59 60 } else if (number_of_boundaries[k] == 2) { 61 //One true neighbour 62 63 //#Get index of the one neighbour 64 i=0; k0 = k; 65 while (i<3 && k0==k) { 66 k0 = surrogate_neighbours[index3 + i]; 67 i++; 68 } 69 if (k0 == k) return -1; 70 71 k1 = k; //self 72 73 //Get data 74 q0 = centroid_values[k0]; 75 q1 = centroid_values[k1]; 76 77 x0 = centroids[k0*2]; y0 = centroids[k0*2+1]; 78 x1 = centroids[k1*2]; y1 = centroids[k1*2+1]; 79 80 //Gradient 81 det = x0*y1 - x1*y0; 82 if (det != 0.0) { 83 a[k] = (y1*q0 - y0*q1)/det; 84 b[k] = (x0*q1 - x1*q0)/det; 85 } 86 } 87 // else: 88 // #No true neighbours - 89 // #Fall back to first order scheme 90 // pass 91 } 92 return 0; 93 } 94 95 96 97 20 98 ///////////////////////////////////////////////// 21 99 // Gateways to Python … … 23 101 24 102 25 26 27 /* 28 29 def 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 103 PyObject *compute_gradients(PyObject *self, PyObject *args) { 104 105 PyObject *quantity, *domain; 106 PyArrayObject 107 *centroids, //Coordinates at centroids 108 *centroid_values, //Values at centroids 109 *number_of_boundaries, //Number of boundaries for each triangle 110 *surrogate_neighbours, //True neighbours or - if one missing - self 111 *a, *b; //Return values 112 113 int dimensions[1], N, err; 114 115 // Convert Python arguments to C 116 if (!PyArg_ParseTuple(args, "O", &quantity)) 117 return NULL; 118 119 domain = PyObject_GetAttrString(quantity, "domain"); 120 if (!domain) 121 return NULL; 122 123 //Get pertinent variables 124 centroids = (PyArrayObject*) PyObject_GetAttrString(domain, "centroids"); 125 if (!centroids) return NULL; 126 127 centroid_values = (PyArrayObject*) 128 PyObject_GetAttrString(quantity, "centroid_values"); 129 if (!centroid_values) return NULL; 130 131 surrogate_neighbours = (PyArrayObject*) 132 PyObject_GetAttrString(domain, "surrogate_neighbours"); 133 if (!surrogate_neighbours) return NULL; 134 135 number_of_boundaries = (PyArrayObject*) 136 PyObject_GetAttrString(domain, "number_of_boundaries"); 137 if (!number_of_boundaries) return NULL; 138 139 N = centroid_values -> dimensions[0]; 140 141 //Release 142 Py_DECREF(domain); 143 144 //Allocate space for return vectors a and b (don't DECREF) 145 dimensions[0] = N; 146 a = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE); 147 b = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE); 148 149 150 151 err = _compute_gradients(N, 152 (double*) centroids -> data, 153 (double*) centroid_values -> data, 154 (int*) number_of_boundaries -> data, 155 (int*) surrogate_neighbours -> data, 156 (double*) a -> data, 157 (double*) b -> data); 158 159 if (err != 0) { 160 PyErr_SetString(PyExc_RuntimeError, "Gradient could not be computed"); 161 return NULL; 162 } 163 164 165 //Return values 166 return Py_BuildValue("OO", PyArray_Return(a), PyArray_Return(b)); 167 } 108 168 109 169 110 170 /* 111 171 PyObject *extrapolate_second_order(PyObject *self, PyObject *args) { 172 173 174 175 PyObject *compute_gradients(PyObject *self, PyObject *args) { 176 177 PyObject *quantity, *domain; 178 PyArrayObject 179 *centroids, //Coordinates at centroids 180 *centroid_values, //Values at centroids 181 *number_of_boundaries, //Number of boundaries for each triangle 182 *surrogate_neighbours, //True neighbours or - if one missing - self 183 *a, *b; //Return values 184 185 int dimensions[1], N, err; 186 187 // Convert Python arguments to C 188 if (!PyArg_ParseTuple(args, "O", &quantity)) 189 return NULL; 190 191 domain = PyObject_GetAttrString(quantity, "domain"); 192 if (!domain) 193 return NULL; 194 195 //Get pertinent variables 196 centroids = (PyArrayObject*) PyObject_GetAttrString(domain, "centroids"); 197 if (!centroids) return NULL; 198 199 centroid_values = (PyArrayObject*) 200 PyObject_GetAttrString(quantity, "centroid_values"); 201 if (!centroid_values) return NULL; 202 203 surrogate_neighbours = (PyArrayObject*) 204 PyObject_GetAttrString(domain, "surrogate_neighbours"); 205 if (!surrogate_neighbours) return NULL; 206 207 number_of_boundaries = (PyArrayObject*) 208 PyObject_GetAttrString(domain, "number_of_boundaries"); 209 if (!number_of_boundaries) return NULL; 210 211 N = centroid_values -> dimensions[0]; 212 213 //Release 214 Py_DECREF(domain); 215 216 //Allocate space for return vectors a and b (don't DECREF) 217 dimensions[0] = N; 218 a = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE); 219 b = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE); 220 221 222 223 err = _compute_gradients(N, 224 (double*) centroids -> data, 225 (double*) centroid_values -> data, 226 (int*) number_of_boundaries -> data, 227 (int*) surrogate_neighbours -> data, 228 (double*) a -> data, 229 (double*) b -> data); 230 231 if (err != 0) { 232 PyErr_SetString(PyExc_RuntimeError, "Gradient could not be computed"); 233 return NULL; 234 } 235 112 236 113 237 PyObject *quantity, *domain, *Tmp; … … 234 358 static struct PyMethodDef MethodTable[] = { 235 359 {"limit", limit, METH_VARARGS, "Print out"}, 360 {"compute_gradients", compute_gradients, METH_VARARGS, "Print out"}, 236 361 {NULL, NULL, 0, NULL} /* sentinel */ 237 362 };
Note: See TracChangeset
for help on using the changeset viewer.