Changeset 4978 for anuga_core/source/anuga/advection
- Timestamp:
- Jan 28, 2008, 6:14:47 PM (17 years ago)
- Location:
- anuga_core/source/anuga/advection
- Files:
-
- 1 added
- 3 deleted
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
anuga_core/source/anuga/advection/advection.py
r4975 r4978 66 66 numproc=numproc) 67 67 68 68 import Numeric 69 69 if velocity is None: 70 self.velocity = [1,0]70 self.velocity = Numeric.array([1,0],'d') 71 71 else: 72 self.velocity = velocity72 self.velocity = Numeric.array(velocity,'d') 73 73 74 74 #Only first is implemented for advection … … 108 108 return flux, max_speed 109 109 110 111 110 112 def compute_fluxes(self): 111 112 113 self.compute_fluxes_ext() 114 ## try: 115 ## self.compute_fluxes_ext() 116 ## except: 117 ## self.compute_fluxes_python() 118 113 """Compute all fluxes and the timestep suitable for all volumes 114 in domain. 115 116 Compute total flux for each conserved quantity using "flux_function" 117 118 Fluxes across each edge are scaled by edgelengths and summed up 119 Resulting flux is then scaled by area and stored in 120 domain.explicit_update 121 122 The maximal allowable speed computed by the flux_function 123 for each volume 124 is converted to a timestep that must not be exceeded. The minimum of 125 those is computed as the next overall timestep. 126 127 Post conditions: 128 domain.explicit_update is reset to computed flux values 129 domain.timestep is set to the largest step satisfying all volumes. 130 """ 131 132 import sys 133 from Numeric import zeros, Float 134 from anuga.config import max_timestep 135 136 137 huge_timestep = float(sys.maxint) 138 Stage = self.quantities['stage'] 139 140 """ 141 print "======================================" 142 print "BEFORE compute_fluxes" 143 print "stage_update",Stage.explicit_update 144 print "stage_edge",Stage.edge_values 145 print "stage_bdry",Stage.boundary_values 146 print "neighbours",self.neighbours 147 print "neighbour_edges",self.neighbour_edges 148 print "normals",self.normals 149 print "areas",self.areas 150 print "radii",self.radii 151 print "edgelengths",self.edgelengths 152 print "tri_full_flag",self.tri_full_flag 153 print "huge_timestep",huge_timestep 154 print "max_timestep",max_timestep 155 print "velocity",self.velocity 156 """ 157 158 import advection_ext 159 self.timestep = advection_ext.compute_fluxes(self, Stage, huge_timestep, max_timestep) 160 161 162 163 def evolve(self, 164 yieldstep = None, 165 finaltime = None, 166 duration = None, 167 skip_initial_step = False): 168 169 """Specialisation of basic evolve method from parent class 170 """ 171 172 #Call basic machinery from parent class 173 for t in Generic_domain.evolve(self, 174 yieldstep=yieldstep, 175 finaltime=finaltime, 176 duration=duration, 177 skip_initial_step=skip_initial_step): 178 179 #Pass control on to outer loop for more specific actions 180 yield(t) 181 182 119 183 120 184 … … 207 271 self.timestep = timestep 208 272 209 210 def compute_fluxes_ext(self):211 """Compute all fluxes and the timestep suitable for all volumes212 in domain.213 214 Compute total flux for each conserved quantity using "flux_function"215 216 Fluxes across each edge are scaled by edgelengths and summed up217 Resulting flux is then scaled by area and stored in218 domain.explicit_update219 220 The maximal allowable speed computed by the flux_function221 for each volume222 is converted to a timestep that must not be exceeded. The minimum of223 those is computed as the next overall timestep.224 225 Post conditions:226 domain.explicit_update is reset to computed flux values227 domain.timestep is set to the largest step satisfying all volumes.228 """229 230 import sys231 from Numeric import zeros, Float232 from anuga.config import max_timestep233 234 ntri = len(self)235 236 timestep = max_timestep237 238 #Shortcuts239 Stage = self.quantities['stage']240 241 #Arrays242 neighbours = self.neighbours243 neighbour_edges = self.neighbour_edges244 normals = self.normals245 areas = self.areas246 radii = self.radii247 edgelengths = self.edgelengths248 tri_full_flag = self.tri_full_flag249 250 stage_edge = Stage.edge_values251 stage_bdry = Stage.boundary_values252 stage_update = Stage.explicit_update253 254 huge_timestep = float(sys.maxint)255 256 v = self.velocity257 258 nbdry = len(stage_bdry)259 260 from advection_ext import compute_fluxes261 262 print "stage_update",stage_update263 print "stage_edge",stage_edge264 print "stage_bdry",stage_bdry265 print "neighbours",neighbours266 print "neighbour_edges",neighbour_edges267 print "normals",normals268 print "areas",areas269 print "radii",radii270 print "edgelengths",edgelengths271 print "tri_full_flag",tri_full_flag272 print "huge_timestep",huge_timestep273 print "max_timestep",max_timestep274 print "v",v275 print "ntri",ntri276 print "nbdry",nbdry277 278 279 280 timestep = compute_fluxes(stage_update,stage_edge,stage_bdry,281 neighbours,neighbour_edges,normals,282 areas,radii,edgelengths,283 tri_full_flag,284 huge_timestep,max_timestep,v,ntri,nbdry)285 286 print "stage_update",stage_update287 288 #print 'timestep out2 =',timestep289 290 self.timestep = timestep291 292 293 def evolve(self,294 yieldstep = None,295 finaltime = None,296 duration = None,297 skip_initial_step = False):298 299 """Specialisation of basic evolve method from parent class300 """301 302 #Call basic machinery from parent class303 for t in Generic_domain.evolve(self,304 yieldstep=yieldstep,305 finaltime=finaltime,306 duration=duration,307 skip_initial_step=skip_initial_step):308 309 #Pass control on to outer loop for more specific actions310 yield(t) -
anuga_core/source/anuga/advection/advection_ext.c
r4975 r4978 1 // Python - C extension module for advection.py 2 // 3 // To compile (Python2.X): 4 // use python ../utilities/compile.py 5 // 6 // See the module advection.py 7 // 8 // 9 // Steve Roberts, ANU 2008 10 11 12 #include "Python.h" 13 #include "Numeric/arrayobject.h" 1 14 #include "math.h" 2 15 #include "stdio.h" 3 16 4 void print_double_array(char* name, double* array, int n, int m){ 5 6 int k,i,km; 7 8 printf("%s = [",name); 9 for (k=0; k<n; k++){ 10 km = m*k; 11 printf("["); 12 for (i=0; i<m ; i++){ 13 printf("%g ",array[km+i]); 14 } 15 if (k==(n-1)) 16 printf("]"); 17 else 18 printf("]\n"); 19 } 20 printf("]\n"); 21 } 22 23 void print_int_array(char* name, int* array, int n, int m){ 24 25 int k,i,km; 26 27 printf("%s = [",name); 28 for (k=0; k<n; k++){ 29 km = m*k; 30 printf("["); 31 for (i=0; i<m ; i++){ 32 printf("%i ",array[km+i]); 33 } 34 if (k==(n-1)) 35 printf("]"); 36 else 37 printf("]\n"); 38 } 39 printf("]\n"); 40 } 41 42 43 double compute_fluxes( 44 double* stage_update, 45 double* stage_edge, 46 double* stage_bdry, 47 int* neighbours, 48 int* neighbour_edges, 49 double* normals, 50 double* areas, 51 double* radii, 52 double* edgelengths, 53 int* tri_full_flag, 17 // Shared code snippets 18 #include "util_ext.h" 19 20 21 22 double _compute_fluxes( 23 double* quantity_update, 24 double* quantity_edge, 25 double* quantity_bdry, 26 long* domain_neighbours, 27 long* domain_neighbour_edges, 28 double* domain_normals, 29 double* domain_areas, 30 double* domain_radii, 31 double* domain_edgelengths, 32 long* domain_tri_full_flag, 33 double* domain_velocity, 54 34 double huge_timestep, 55 35 double max_timestep, 56 double* v,57 36 int ntri, 58 37 int nbdry){ 38 39 59 40 //Loop 60 41 … … 72 53 timestep = max_timestep; 73 54 74 75 printf("======================================================\n");76 printf("INSIDE compute_fluxes\n");77 78 79 print_double_array( "stage_update",stage_update, ntri, 1);80 print_double_array( "stage_edge",stage_edge, ntri, 3);81 print_double_array( "stage_bdry",stage_bdry, nbdry, 1);82 print_int_array( "neighbours",neighbours, ntri, 3);83 print_int_array( "neighbour_edges",neighbour_edges, ntri, 3);84 print_double_array( "normals",normals, ntri, 6);85 print_double_array( "areas",areas, ntri, 1);86 print_double_array( "radii",radii, ntri, 1);87 print_double_array( "edgelengths",edgelengths, ntri, 3);88 print_int_array( "tri_full_flag",tri_full_flag, ntri, 1);89 printf("huge_timestep = %g\n",huge_timestep);90 printf("max_timestep = %g\n",max_timestep);91 print_double_array( "v",v, 2, 1);92 printf("ntri = %i\n",ntri);93 printf("nbdry = %i\n",nbdry);94 95 96 55 for (k=0; k<ntri; k++){ 97 56 optimal_timestep = huge_timestep; … … 101 60 k_i = k3+i; 102 61 //Quantities inside volume facing neighbour i 103 ql = stage_edge[k_i];62 ql = quantity_edge[k_i]; 104 63 105 64 106 65 //Quantities at neighbour on nearest face 107 n = neighbours[k_i];66 n = domain_neighbours[k_i]; 108 67 if (n < 0) { 109 68 m = -n-1; //Convert neg flag to index 110 qr = stage_bdry[m];69 qr = quantity_bdry[m]; 111 70 } else { 112 m = neighbour_edges[k_i];71 m = domain_neighbour_edges[k_i]; 113 72 n_m = 3*n+m; 114 qr = stage_edge[n_m];73 qr = quantity_edge[n_m]; 115 74 } 116 75 … … 119 78 for (j=0; j<2; j++){ 120 79 k_i_j = 6*k+2*i+j; 121 normal[j] = normals[k_i_j];80 normal[j] = domain_normals[k_i_j]; 122 81 } 123 82 124 83 125 84 //Flux computation using provided function 126 normal_velocity = v[0]*normal[0] + v[1]*normal[1];85 normal_velocity = domain_velocity[0]*normal[0] + domain_velocity[1]*normal[1]; 127 86 128 87 if (normal_velocity < 0) { … … 133 92 134 93 max_speed = fabs(normal_velocity); 135 flux = flux - edgeflux * edgelengths[k_i];94 flux = flux - edgeflux * domain_edgelengths[k_i]; 136 95 137 96 //Update optimal_timestep 138 if ( tri_full_flag[k] == 1) {97 if (domain_tri_full_flag[k] == 1) { 139 98 if (max_speed != 0.0) { 140 optimal_timestep = (optimal_timestep>radii[k]/max_speed) ? radii[k]/max_speed : optimal_timestep; 99 optimal_timestep = (optimal_timestep>domain_radii[k]/max_speed) ? 100 domain_radii[k]/max_speed : optimal_timestep; 141 101 } 142 102 } … … 146 106 //Normalise by area and store for when all conserved 147 107 //quantities get updated 148 stage_update[k] = flux/areas[k];108 quantity_update[k] = flux/domain_areas[k]; 149 109 150 110 timestep = (timestep>optimal_timestep) ? optimal_timestep : timestep; 151 111 152 112 } 153 154 //printf("timestep out = %g\n",timestep);155 156 157 158 printf("INSIDE compute_fluxes, end \n");159 160 print_double_array( "stage_update",stage_update, ntri, 1);161 162 printf("FINISHED compute_fluxes\n");163 printf("======================================================\n");164 165 113 166 114 return timestep; 167 115 } 168 116 117 118 //----------------------------------------------------- 119 // Python method Wrappers 120 //----------------------------------------------------- 121 122 123 124 PyObject *compute_fluxes(PyObject *self, PyObject *args) { 125 /*Compute all fluxes and the timestep suitable for all volumes 126 in domain. 127 128 Fluxes across each edge are scaled by edgelengths and summed up 129 Resulting flux is then scaled by area and stored in 130 explicit_update for the conserved quantity stage. 131 132 The maximal allowable speed computed for each volume 133 is converted to a timestep that must not be exceeded. The minimum of 134 those is computed as the next overall timestep. 135 136 Python call: 137 timestep = advection_ext.compute_fluxes(domain,quantity,huge_timestep,max_timestep) 138 139 Post conditions: 140 domain.explicit_update is reset to computed flux values 141 domain.timestep is set to the largest step satisfying all volumes. 142 143 */ 144 145 PyObject *domain, *quantity; 146 PyArrayObject 147 * quantity_update, 148 * quantity_edge, 149 * quantity_bdry, 150 * domain_neighbours, 151 * domain_neighbour_edges, 152 * domain_normals, 153 * domain_areas, 154 * domain_radii, 155 * domain_edgelengths, 156 * domain_tri_full_flag, 157 * domain_velocity; 158 159 160 // Local variables 161 int ntri, nbdry; 162 double huge_timestep, max_timestep; 163 double timestep; 164 165 166 // Convert Python arguments to C 167 if (!PyArg_ParseTuple(args, "OOdd", 168 &domain, 169 &quantity, 170 &huge_timestep, 171 &max_timestep)) { 172 PyErr_SetString(PyExc_RuntimeError, "advection_ext.c: compute_fluxes could not parse input"); 173 return NULL; 174 } 175 176 quantity_edge = get_consecutive_array(quantity, "edge_values"); 177 quantity_bdry = get_consecutive_array(quantity, "boundary_values"); 178 quantity_update = get_consecutive_array(quantity, "explicit_update"); 179 domain_neighbours = get_consecutive_array(domain, "neighbours"); 180 domain_neighbour_edges = get_consecutive_array(domain, "neighbour_edges"); 181 domain_normals = get_consecutive_array(domain, "normals"); 182 domain_areas = get_consecutive_array(domain, "areas"); 183 domain_radii = get_consecutive_array(domain, "radii"); 184 domain_edgelengths = get_consecutive_array(domain, "edgelengths"); 185 domain_tri_full_flag = get_consecutive_array(domain, "tri_full_flag"); 186 domain_velocity = get_consecutive_array(domain, "velocity"); 187 188 ntri = quantity_edge -> dimensions[0]; 189 nbdry = quantity_bdry -> dimensions[0]; 190 191 timestep = _compute_fluxes((double*) quantity_update -> data, 192 (double*) quantity_edge -> data, 193 (double*) quantity_bdry -> data, 194 (long*) domain_neighbours -> data, 195 (long*) domain_neighbour_edges -> data, 196 (double*) domain_normals -> data, 197 (double*) domain_areas ->data, 198 (double*) domain_radii -> data, 199 (double*) domain_edgelengths -> data, 200 (long*) domain_tri_full_flag -> data, 201 (double*) domain_velocity -> data, 202 huge_timestep, 203 max_timestep, 204 ntri, 205 nbdry); 206 207 // Release and return 208 Py_DECREF(quantity_update); 209 Py_DECREF(quantity_edge); 210 Py_DECREF(quantity_bdry); 211 Py_DECREF(domain_neighbours); 212 Py_DECREF(domain_neighbour_edges); 213 Py_DECREF(domain_normals); 214 Py_DECREF(domain_areas); 215 Py_DECREF(domain_radii); 216 Py_DECREF(domain_edgelengths); 217 Py_DECREF(domain_tri_full_flag); 218 Py_DECREF(domain_velocity); 219 220 221 return Py_BuildValue("d", timestep); 222 } 223 224 225 226 //------------------------------- 227 // Method table for python module 228 //------------------------------- 229 static struct PyMethodDef MethodTable[] = { 230 /* The cast of the function is necessary since PyCFunction values 231 * only take two PyObject* parameters, and rotate() takes 232 * three. 233 */ 234 235 {"compute_fluxes", compute_fluxes, METH_VARARGS, "Print out"}, 236 {NULL, NULL} 237 }; 238 239 // Module initialisation 240 void initadvection_ext(void){ 241 Py_InitModule("advection_ext", MethodTable); 242 import_array(); // Necessary for handling of NumPY structures 243 } -
anuga_core/source/anuga/advection/test_advection.py
r4972 r4978 60 60 U = -domain.quantities['stage'].explicit_update 61 61 R = -0.5/domain.areas[0] 62 63 print 'U ', U64 print 'R ', R65 66 62 67 63 assert U==R, '%s %s' %(U, R)
Note: See TracChangeset
for help on using the changeset viewer.