Changeset 1508
- Timestamp:
- Jun 9, 2005, 3:37:55 PM (19 years ago)
- Location:
- inundation/ga/storm_surge/pyvolution
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/domain.py
r1506 r1508 21 21 tagged_elements, geo_reference, use_inscribed_circle) 22 22 23 from Numeric import zeros, Float 23 from Numeric import zeros, Float, Int 24 24 from quantity import Quantity, Conserved_quantity 25 25 … … 85 85 self.checkpoint = False 86 86 87 #MH310505 To avoid calculating the flux across each edge twice, keep an integer (boolean) array, 88 #to be used during the flux calculation 89 N=self.number_of_elements 90 self.already_computed_flux = zeros((N, 3), Int) 87 91 88 92 #Public interface to Domain -
inundation/ga/storm_surge/pyvolution/shallow_water.py
r1507 r1508 543 543 Stage.explicit_update, 544 544 Xmom.explicit_update, 545 Ymom.explicit_update) 545 Ymom.explicit_update, 546 domain.already_computed_flux) 546 547 547 548 -
inundation/ga/storm_surge/pyvolution/shallow_water_ext.c
r1507 r1508 848 848 } 849 849 850 851 850 PyObject *compute_fluxes(PyObject *self, PyObject *args) { 852 851 /*Compute all fluxes and the timestep suitable for all volumes … … 883 882 Stage.explicit_update, 884 883 Xmom.explicit_update, 885 Ymom.explicit_update) 884 Ymom.explicit_update, 885 already_computed_flux) 886 886 887 887 … … 905 905 *stage_explicit_update, 906 906 *xmom_explicit_update, 907 *ymom_explicit_update; 907 *ymom_explicit_update, 908 *already_computed_flux;//tracks whether the flux across an edge has already been computed 908 909 909 910 … … 911 912 double timestep, max_speed, epsilon, g; 912 913 double normal[2], ql[3], qr[3], zl, zr; 913 double flux[3],edgeflux[3]; //Work arrays for summing up fluxes914 915 int number_of_elements, k, i, j,m, n;914 double edgeflux[3]; //Work arrays for summing up fluxes 915 916 int number_of_elements, k, i, m, n; 916 917 int ki, nm, ki2; //Index shorthands 918 static long call=1; 917 919 918 920 919 921 // Convert Python arguments to C 920 if (!PyArg_ParseTuple(args, "dddOOOOOOOOOOOOOOOO ",922 if (!PyArg_ParseTuple(args, "dddOOOOOOOOOOOOOOOOO", 921 923 ×tep, 922 924 &epsilon, … … 935 937 &stage_explicit_update, 936 938 &xmom_explicit_update, 937 &ymom_explicit_update)) { 939 &ymom_explicit_update, 940 &already_computed_flux)) { 938 941 PyErr_SetString(PyExc_RuntimeError, "Input arguments failed"); 939 942 return NULL; 940 943 } 941 942 944 number_of_elements = stage_edge_values -> dimensions[0]; 943 944 945 call++;//a static local variable to which already_computed_flux is compared 946 //set explicit_update to zero for all conserved_quantities. 947 //This assumes compute_fluxes called before forcing terms 945 948 for (k=0; k<number_of_elements; k++) { 946 947 //Reset work array 948 for (j=0; j<3; j++) flux[j] = 0.0; 949 950 //Loop through neighbours and compute edge flux for each 949 ((double *) stage_explicit_update -> data)[k]=0.0; 950 ((double *) xmom_explicit_update -> data)[k]=0.0; 951 ((double *) ymom_explicit_update -> data)[k]=0.0; 952 } 953 //Loop through neighbours and compute edge flux for each 954 for (k=0; k<number_of_elements; k++) { 951 955 for (i=0; i<3; i++) { 952 956 ki = k*3+i; 957 if (((long *) already_computed_flux->data)[ki]==call)//we've already computed the flux across this edge 958 continue; 953 959 ql[0] = ((double *) stage_edge_values -> data)[ki]; 954 960 ql[1] = ((double *) xmom_edge_values -> data)[ki]; 955 961 ql[2] = ((double *) ymom_edge_values -> data)[ki]; 956 962 zl = ((double *) bed_edge_values -> data)[ki]; 957 963 958 964 //Quantities at neighbour on nearest face 959 965 n = ((long *) neighbours -> data)[ki]; … … 966 972 } else { 967 973 m = ((long *) neighbour_edges -> data)[ki]; 968 969 974 nm = n*3+m; 970 975 qr[0] = ((double *) stage_edge_values -> data)[nm]; … … 973 978 zr = ((double *) bed_edge_values -> data)[nm]; 974 979 } 975 976 //printf("%d %d [%d] (%d, %d): %.2f %.2f %.2f\n", k, i, ki, n, m,977 // ql[0], ql[1], ql[2]);978 979 980 980 // Outward pointing normal vector 981 981 // normal = domain.normals[k, 2*i:2*i+2] … … 983 983 normal[0] = ((double *) normals -> data)[ki2]; 984 984 normal[1] = ((double *) normals -> data)[ki2+1]; 985 986 985 //Edge flux computation 987 986 flux_function(ql, qr, zl, zr, … … 989 988 epsilon, g, 990 989 edgeflux, &max_speed); 991 992 993 //flux -= edgeflux * edgelengths[k,i] 994 for (j=0; j<3; j++) { 995 flux[j] -= edgeflux[j]*((double *) edgelengths -> data)[ki]; 990 //update triangle k 991 ((long *) already_computed_flux->data)[ki]=call; 992 ((double *) stage_explicit_update -> data)[k] -= edgeflux[0]*((double *) edgelengths -> data)[ki]; 993 ((double *) xmom_explicit_update -> data)[k] -= edgeflux[1]*((double *) edgelengths -> data)[ki]; 994 ((double *) ymom_explicit_update -> data)[k] -= edgeflux[2]*((double *) edgelengths -> data)[ki]; 995 //update the neighbour n 996 if (n>=0){ 997 ((long *) already_computed_flux->data)[nm]=call; 998 ((double *) stage_explicit_update -> data)[n] += edgeflux[0]*((double *) edgelengths -> data)[nm]; 999 ((double *) xmom_explicit_update -> data)[n] += edgeflux[1]*((double *) edgelengths -> data)[nm]; 1000 ((double *) ymom_explicit_update -> data)[n] += edgeflux[2]*((double *) edgelengths -> data)[nm]; 996 1001 } 997 998 //Update timestep 999 //timestep = min(timestep, domain.radii[k]/max_speed) 1000 //FIXME: SR Add parameter for CFL condition 1001 if (max_speed > epsilon) { 1002 timestep = min(timestep, ((double *) radii -> data)[k]/max_speed); 1003 } 1002 ///for (j=0; j<3; j++) { 1003 ///flux[j] -= edgeflux[j]*((double *) edgelengths -> data)[ki]; 1004 ///} 1005 //Update timestep 1006 //timestep = min(timestep, domain.radii[k]/max_speed) 1007 //FIXME: SR Add parameter for CFL condition 1008 if (max_speed > epsilon) { 1009 timestep = min(timestep, ((double *) radii -> data)[k]/max_speed); 1010 //maxspeed in flux_function is calculated as max(|u+a|,|u-a|) 1011 if (n>=0) 1012 timestep = min(timestep, ((double *) radii -> data)[n]/max_speed); 1013 } 1004 1014 } // end for i 1005 1006 1015 //Normalise by area and store for when all conserved 1007 1016 //quantities get updated 1008 // flux /= areas[k] 1009 for (j=0; j<3; j++) { 1010 flux[j] /= ((double *) areas -> data)[k]; 1011 } 1012 1013 ((double *) stage_explicit_update -> data)[k] = flux[0]; 1014 ((double *) xmom_explicit_update -> data)[k] = flux[1]; 1015 ((double *) ymom_explicit_update -> data)[k] = flux[2]; 1016 1017 ((double *) stage_explicit_update -> data)[k] /= ((double *) areas -> data)[k]; 1018 ((double *) xmom_explicit_update -> data)[k] /= ((double *) areas -> data)[k]; 1019 ((double *) ymom_explicit_update -> data)[k] /= ((double *) areas -> data)[k]; 1017 1020 } //end for k 1018 1019 1021 return Py_BuildValue("d", timestep); 1020 1022 } 1021 1022 1023 1023 1024 1024 PyObject *protect(PyObject *self, PyObject *args) {
Note: See TracChangeset
for help on using the changeset viewer.