Changeset 255
- Timestamp:
- Aug 31, 2004, 11:47:24 AM (21 years ago)
- Location:
- inundation/ga/storm_surge/pyvolution
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/quantity.py
r245 r255 352 352 353 353 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 359 def 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) 377 383 378 384 … … 446 452 #Replace python version with c implementations 447 453 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 31 31 32 32 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; 33 void _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; 37 38 38 39 for (k=0; k<N; k++) { 39 40 k3 = k*3; 41 40 42 //Find the gradient limiter (phi) across vertices 41 43 phi = 1.0; 42 44 for (i=0; i<3; i++) { 43 ki = k*3+i;44 45 r = 1.0; 45 46 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 48 50 if (dq > 0.0) r = (qmax[k] - qc[k])/dq; 49 51 if (dq < 0.0) r = (qmin[k] - qc[k])/dq; 50 52 53 51 54 phi = min( min(r*beta, 1.0), phi); 52 55 } 56 53 57 //Then update using phi limiter 54 58 for (i=0; i<3; i++) { 55 qv[k i] = qc[k] + phi*(qv[ki] - qc[k]); //FIXME: Could precompute dq (3 elements)59 qv[k3+i] = qc[k] + phi*dqa[i]; 56 60 } 57 61 } 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 /* 68 PyObject *extrapolate_second_order(PyObject *self, PyObject *args) { 69 70 PyObject *quantity, *domain, *Tmp; 98 71 PyArrayObject 99 72 *qv, //Conserved quantities at vertices … … 101 74 *neighbours; 102 75 103 int k, i, n, N ;76 int k, i, n, N, k3; 104 77 double beta; //Safety factor 105 78 double *qmin, *qmax, qn; … … 108 81 if (!PyArg_ParseTuple(args, "O", &quantity)) 109 82 return NULL; 110 111 //Get safety factor beta112 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 117 90 qc = (PyArrayObject*) PyObject_GetAttrString(quantity, "centroid_values"); 118 91 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 92 N = qc -> dimensions[0]; 124 125 93 */ 94 /* 95 def 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 124 PyObject *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 126 160 //Find min and max of this and neighbour's centroid values 127 161 qmin = malloc(N * sizeof(double)); 128 162 qmax = malloc(N * sizeof(double)); 129 163 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 131 169 for (i=0; i<3; i++) { 132 n = ((int*) neighbours -> data)[k *3+i];170 n = ((int*) neighbours -> data)[k3+i]; 133 171 if (n >= 0) { 134 172 qn = ((double*) qc -> data)[n]; //Neighbour's centroid value … … 141 179 142 180 // 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); 144 182 145 183 free(qmin);
Note: See TracChangeset
for help on using the changeset viewer.