Changeset 4990
- Timestamp:
- Feb 5, 2008, 5:25:32 PM (17 years ago)
- Location:
- anuga_core/source/anuga/abstract_2d_finite_volumes
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
anuga_core/source/anuga/abstract_2d_finite_volumes/quantity.py
r4962 r4990 1404 1404 extrapolate_from_gradient(self) 1405 1405 1406 def extrapolate_second_order_and_limit(self): 1407 #Call correct module function 1408 #(either from this module or C-extension) 1409 extrapolate_second_order_and_limit(self) 1410 1406 1411 def backup_centroid_values(self): 1407 1412 #Call correct module function -
anuga_core/source/anuga/abstract_2d_finite_volumes/quantity_ext.c
r4978 r4990 16 16 //Shared code snippets 17 17 #include "util_ext.h" 18 //#include "quantity_ext.h" //Obsolete 19 20 18 19 20 //------------------------------------------- 21 // Low level routines (called from wrappers) 22 //------------------------------------------ 21 23 22 24 int _compute_gradients(int N, … … 90 92 return 0; 91 93 } 92 93 94 94 95 … … 135 136 return 0; 136 137 } 138 139 140 int _extrapolate_and_limit_from_gradient(int N,double beta, 141 double* centroids, 142 long* neighbours, 143 double* centroid_values, 144 double* vertex_coordinates, 145 double* vertex_values, 146 double* edge_values, 147 double* x_gradient, 148 double* y_gradient) { 149 150 int i, k, k2, k3, k6; 151 double x, y, x0, y0, x1, y1, x2, y2; 152 long n; 153 double qmin, qmax, qn, qc; 154 double dq, dqa[3], phi, r; 155 156 157 for (k=0; k<N; k++){ 158 k6 = 6*k; 159 k3 = 3*k; 160 k2 = 2*k; 161 162 // Centroid coordinates 163 x = centroids[k2]; y = centroids[k2+1]; 164 165 // vertex coordinates 166 // x0, y0, x1, y1, x2, y2 = X[k,:] 167 x0 = vertex_coordinates[k6 + 0]; 168 y0 = vertex_coordinates[k6 + 1]; 169 x1 = vertex_coordinates[k6 + 2]; 170 y1 = vertex_coordinates[k6 + 3]; 171 x2 = vertex_coordinates[k6 + 4]; 172 y2 = vertex_coordinates[k6 + 5]; 173 174 //Centroid Value 175 qc = centroid_values[k]; 176 177 // Extrapolate to Vertices 178 vertex_values[k3+0] = centroid_values[k] + x_gradient[k]*(x0-x) + y_gradient[k]*(y0-y); 179 vertex_values[k3+1] = centroid_values[k] + x_gradient[k]*(x1-x) + y_gradient[k]*(y1-y); 180 vertex_values[k3+2] = centroid_values[k] + x_gradient[k]*(x2-x) + y_gradient[k]*(y2-y); 181 182 // Extrapolate to Edges (midpoints) 183 edge_values[k3+0] = 0.5*(vertex_values[k3 + 1]+vertex_values[k3 + 2]); 184 edge_values[k3+1] = 0.5*(vertex_values[k3 + 2]+vertex_values[k3 + 0]); 185 edge_values[k3+2] = 0.5*(vertex_values[k3 + 0]+vertex_values[k3 + 1]); 186 187 188 phi = 1.0; 189 190 for (i=0; i<3; i++) { 191 dq = edge_values[k3+i] - qc; //Delta between edge and centroid values 192 dqa[i] = dq; //Save dq for use in updating vertex values 193 194 n = neighbours[k3+i]; 195 if (n >= 0) { 196 qn = centroid_values[n]; //Neighbour's centroid value 197 198 qmin = min(qc, qn); 199 qmax = max(qc, qn); 200 201 202 r = 1.0; 203 204 if (dq > 0.0) r = (qmax - qc)/dq; 205 if (dq < 0.0) r = (qmin - qc)/dq; 206 207 phi = min( min(r*beta, 1.0), phi); 208 } 209 } 210 211 212 //Update gradient, edge and vertex values using phi limiter 213 x_gradient[k] = x_gradient[k]*phi; 214 y_gradient[k] = y_gradient[k]*phi; 215 216 edge_values[k3+0] = qc + phi*dqa[0]; 217 edge_values[k3+1] = qc + phi*dqa[1]; 218 edge_values[k3+2] = qc + phi*dqa[2]; 219 220 221 vertex_values[k3+0] = edge_values[k3+1] + edge_values[k3+2] - edge_values[k3+0]; 222 vertex_values[k3+1] = edge_values[k3+2] + edge_values[k3+0] - edge_values[k3+1]; 223 vertex_values[k3+2] = edge_values[k3+0] + edge_values[k3+1] - edge_values[k3+2]; 224 225 } 226 227 return 0; 228 229 } 230 231 137 232 138 233 … … 542 637 543 638 544 ///////////////////////////////////////////////// 545 // Gateways to Python 639 //----------------------------------------------------- 640 // Python method Wrappers 641 //----------------------------------------------------- 642 546 643 PyObject *update(PyObject *self, PyObject *args) { 547 644 // FIXME (Ole): It would be great to turn this text into a Python DOC string … … 937 1034 Py_DECREF(domain); 938 1035 939 //Allocate space for return vectors a and b (don't DECREF)940 //dimensions[0] = N;941 //a = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE);942 //b = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE);943 944 //FIXME: Odd that I couldn't use normal arrays945 //Allocate space for return vectors a and b (don't DECREF)946 //a = (double*) malloc(N * sizeof(double));947 //if (!a) return NULL;948 //b = (double*) malloc(N * sizeof(double));949 //if (!b) return NULL;950 951 952 /* err = _compute_gradients(N, */953 /* (double*) centroids -> data, */954 /* (double*) centroid_values -> data, */955 /* (long*) number_of_boundaries -> data, */956 /* (long*) surrogate_neighbours -> data, */957 /* (double*) x_gradient -> data, */958 /* (double*) y_gradient -> data); */959 960 /* if (err != 0) { */961 /* PyErr_SetString(PyExc_RuntimeError, "Gradient could not be computed"); */962 /* return NULL; */963 /* } */964 965 1036 err = _extrapolate_from_gradient(N, 966 1037 (double*) centroids -> data, … … 993 1064 994 1065 return Py_BuildValue(""); 1066 } 1067 1068 1069 PyObject *extrapolate_second_order_and_limit(PyObject *self, PyObject *args) { 1070 /* Compute edge values using second order approximation and limit values 1071 so that edge values are limited by the two corresponding centroid values 1072 1073 Python Call: 1074 extrapolate_second_order_and_limit(domain,quantity,beta) 1075 */ 1076 1077 PyObject *quantity, *domain; 1078 1079 PyArrayObject 1080 *domain_centroids, //Coordinates at centroids 1081 *domain_vertex_coordinates, //Coordinates at vertices 1082 *domain_number_of_boundaries, //Number of boundaries for each triangle 1083 *domain_surrogate_neighbours, //True neighbours or - if one missing - self 1084 *domain_neighbours, //True neighbours, or if negative a link to boundary 1085 1086 *quantity_centroid_values, //Values at centroids 1087 *quantity_vertex_values, //Values at vertices 1088 *quantity_edge_values, //Values at edges 1089 *quantity_x_gradient, //x gradient 1090 *quantity_y_gradient; //y gradient 1091 1092 1093 // Local variables 1094 int ntri; 1095 double beta; 1096 int err; 1097 1098 // Convert Python arguments to C 1099 if (!PyArg_ParseTuple(args, "OOd", 1100 &domain, 1101 &quantity, 1102 &beta)) { 1103 PyErr_SetString(PyExc_RuntimeError, 1104 "quantity_ext.c: extrapolate_second_order_and_limit could not parse input"); 1105 return NULL; 1106 } 1107 1108 1109 // Get pertinent variables 1110 domain_centroids = get_consecutive_array(domain, "centroid_coordinates"); 1111 domain_surrogate_neighbours = get_consecutive_array(domain, "surrogate_neighbours"); 1112 domain_number_of_boundaries = get_consecutive_array(domain, "number_of_boundaries"); 1113 domain_vertex_coordinates = get_consecutive_array(domain, "vertex_coordinates"); 1114 domain_neighbours = get_consecutive_array(domain, "neighbours"); 1115 1116 quantity_centroid_values = get_consecutive_array(quantity, "centroid_values"); 1117 quantity_vertex_values = get_consecutive_array(quantity, "vertex_values"); 1118 quantity_edge_values = get_consecutive_array(quantity, "edge_values"); 1119 quantity_x_gradient = get_consecutive_array(quantity, "x_gradient"); 1120 quantity_y_gradient = get_consecutive_array(quantity, "y_gradient"); 1121 1122 ntri = quantity_centroid_values -> dimensions[0]; 1123 1124 1125 1126 err = _compute_gradients(ntri, 1127 (double*) domain_centroids -> data, 1128 (double*) quantity_centroid_values -> data, 1129 (long*) domain_number_of_boundaries -> data, 1130 (long*) domain_surrogate_neighbours -> data, 1131 (double*) quantity_x_gradient -> data, 1132 (double*) quantity_y_gradient -> data); 1133 1134 if (err != 0) { 1135 PyErr_SetString(PyExc_RuntimeError, 1136 "quantity_ext.c: Internal function _compute_gradient failed"); 1137 return NULL; 1138 } 1139 1140 1141 err = _extrapolate_and_limit_from_gradient(ntri, beta, 1142 (double*) domain_centroids -> data, 1143 (long*) domain_neighbours -> data, 1144 (double*) quantity_centroid_values -> data, 1145 (double*) domain_vertex_coordinates -> data, 1146 (double*) quantity_vertex_values -> data, 1147 (double*) quantity_edge_values -> data, 1148 (double*) quantity_x_gradient -> data, 1149 (double*) quantity_y_gradient -> data); 1150 1151 if (err != 0) { 1152 PyErr_SetString(PyExc_RuntimeError, 1153 "quantity_ext.c: Internal function _extrapolate_and_limit_from_gradient failed"); 1154 return NULL; 1155 } 1156 1157 1158 // Release 1159 Py_DECREF(domain_centroids); 1160 Py_DECREF(domain_surrogate_neighbours); 1161 Py_DECREF(domain_number_of_boundaries); 1162 Py_DECREF(domain_vertex_coordinates); 1163 1164 Py_DECREF(quantity_centroid_values); 1165 Py_DECREF(quantity_vertex_values); 1166 Py_DECREF(quantity_edge_values); 1167 Py_DECREF(quantity_x_gradient); 1168 Py_DECREF(quantity_y_gradient); 1169 1170 return Py_BuildValue(""); 995 1171 } 996 1172 … … 1046 1222 Py_DECREF(domain); 1047 1223 1048 //Allocate space for return vectors a and b (don't DECREF)1049 //dimensions[0] = N;1050 //a = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE);1051 //b = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE);1052 1053 //FIXME: Odd that I couldn't use normal arrays1054 //Allocate space for return vectors a and b (don't DECREF)1055 //a = (double*) malloc(N * sizeof(double));1056 //if (!a) return NULL;1057 //b = (double*) malloc(N * sizeof(double));1058 //if (!b) return NULL;1059 1060 1224 1061 1225 err = _compute_gradients(N, … … 1071 1235 return NULL; 1072 1236 } 1073 1074 /* err = _extrapolate(N, */1075 /* (double*) centroids -> data, */1076 /* (double*) centroid_values -> data, */1077 /* (double*) vertex_coordinates -> data, */1078 /* (double*) vertex_values -> data, */1079 /* (double*) edge_values -> data, */1080 /* (double*) x_gradient -> data, */1081 /* (double*) y_gradient -> data); */1082 1083 1084 /* if (err != 0) { */1085 /* PyErr_SetString(PyExc_RuntimeError, */1086 /* "Internal function _extrapolate failed"); */1087 /* return NULL; */1088 /* } */1089 1237 1090 1238 … … 1558 1706 {"extrapolate_from_gradient", extrapolate_from_gradient, 1559 1707 METH_VARARGS, "Print out"}, 1708 {"extrapolate_second_order_and_limit", extrapolate_second_order_and_limit, 1709 METH_VARARGS, "Print out"}, 1560 1710 {"interpolate_from_vertices_to_edges", 1561 1711 interpolate_from_vertices_to_edges,
Note: See TracChangeset
for help on using the changeset viewer.