#include "Python.h" #include "Numeric/arrayobject.h" #include "math.h" #include const double pi = 3.14159265358979; // Shared code snippets #include "util_ext.h" /* double max(double a, double b) { */ /* double z; */ /* z=(a>b)?a:b; */ /* return z;} */ /* double min(double a, double b) { */ /* double z; */ /* z=(a 0.0) s_min = 0.0; // Flux formulas flux_left[0] = u_left*h_left; flux_left[1] = u_left*uh_left + 0.5*g*h_left*h_left; flux_right[0] = u_right*h_right; flux_right[1] = u_right*uh_right + 0.5*g*h_right*h_right; // Flux computation denom = s_max-s_min; if (denom < epsilon) { for (i=0; i<2; i++) edgeflux[i] = 0.0; *max_speed = 0.0; } else { edgeflux[0] = s_max*flux_left[0] - s_min*flux_right[0]; edgeflux[0] += s_max*s_min*(qr[0]-ql[0]); edgeflux[0] /= denom; edgeflux[1] = s_max*flux_left[1] - s_min*flux_right[1]; edgeflux[1] += s_max*s_min*(qr[1]-ql[1]); edgeflux[1] /= denom; edgeflux[1] *= normals; // Maximal wavespeed *max_speed = max(fabs(s_max), fabs(s_min)); } return 0; } // Computational function for flux computation double _compute_fluxes_ext(double timestep, double epsilon, double g, long* neighbours, long* neighbour_vertices, double* normals, double* areas, double* stage_edge_values, double* xmom_edge_values, double* bed_edge_values, double* stage_boundary_values, double* xmom_boundary_values, double* stage_explicit_update, double* xmom_explicit_update, int number_of_elements, double* max_speed_array) { double flux[2], ql[2], qr[2], edgeflux[2]; double zl, zr, max_speed, normal; int k, i, ki, n, m, nm=0; for (k=0; k epsilon) { // Original CFL calculation timestep = min(timestep, 0.5*areas[k]/max_speed); //Here, CFL=1.0 is assumed. ????????????????????????????????????????????? if (n>=0) { timestep = min(timestep, 0.5*areas[n]/max_speed); //Here, CFL=1.0 is assumed. ????????????????????????????????????????????? } } } // End edge i (and neighbour n) flux[0] /= areas[k]; stage_explicit_update[k] = flux[0]; flux[1] /= areas[k]; xmom_explicit_update[k] = flux[1]; //Keep track of maximal speeds max_speed_array[k]=max_speed; } return timestep; } //========================================================================= // Python Glue //========================================================================= PyObject *compute_fluxes_ext(PyObject *self, PyObject *args) { PyArrayObject *neighbours, *neighbour_vertices, *normals, *areas, *stage_edge_values, *xmom_edge_values, *bed_edge_values, *stage_boundary_values, *xmom_boundary_values, *stage_explicit_update, *xmom_explicit_update, *max_speed_array; double timestep, epsilon, g; int number_of_elements; // Convert Python arguments to C if (!PyArg_ParseTuple(args, "dddOOOOOOOOOOOiO", ×tep, &epsilon, &g, &neighbours, &neighbour_vertices, &normals, &areas, &stage_edge_values, &xmom_edge_values, &bed_edge_values, &stage_boundary_values, &xmom_boundary_values, &stage_explicit_update, &xmom_explicit_update, &number_of_elements, &max_speed_array)) { PyErr_SetString(PyExc_RuntimeError, "comp_flux_ext.c: compute_fluxes_ext could not parse input"); return NULL; } // Call underlying flux computation routine and update // the explicit update arrays timestep = _compute_fluxes_ext(timestep, epsilon, g, (long*) neighbours -> data, (long*) neighbour_vertices -> data, (double*) normals -> data, (double*) areas -> data, (double*) stage_edge_values -> data, (double*) xmom_edge_values -> data, (double*) bed_edge_values -> data, (double*) stage_boundary_values -> data, (double*) xmom_boundary_values -> data, (double*) stage_explicit_update -> data, (double*) xmom_explicit_update -> data, number_of_elements, (double*) max_speed_array -> data); // Return updated flux timestep return Py_BuildValue("d", timestep); } PyObject *compute_fluxes_ext_short(PyObject *self, PyObject *args) { PyObject *domain, *stage, *xmom, *bed; PyArrayObject *neighbours, *neighbour_vertices, *normals, *areas, *stage_vertex_values, *xmom_vertex_values, *bed_vertex_values, *stage_boundary_values, *xmom_boundary_values, *stage_explicit_update, *xmom_explicit_update, *max_speed_array; double timestep, epsilon, g; int number_of_elements; // Convert Python arguments to C if (!PyArg_ParseTuple(args, "dOOOO", ×tep, &domain, &stage, &xmom, &bed)) { PyErr_SetString(PyExc_RuntimeError, "comp_flux_ext.c: compute_fluxes_ext_short could not parse input"); return NULL; } epsilon = get_python_double(domain,"epsilon"); g = get_python_double(domain,"g"); neighbours = get_consecutive_array(domain, "neighbours"); neighbour_vertices= get_consecutive_array(domain, "neighbour_vertices"); normals = get_consecutive_array(domain, "normals"); areas = get_consecutive_array(domain, "areas"); max_speed_array = get_consecutive_array(domain, "max_speed_array"); stage_vertex_values = get_consecutive_array(stage, "vertex_values"); xmom_vertex_values = get_consecutive_array(xmom, "vertex_values"); bed_vertex_values = get_consecutive_array(bed, "vertex_values"); stage_boundary_values = get_consecutive_array(stage, "boundary_values"); xmom_boundary_values = get_consecutive_array(xmom, "boundary_values"); stage_explicit_update = get_consecutive_array(stage, "explicit_update"); xmom_explicit_update = get_consecutive_array(xmom, "explicit_update"); number_of_elements = stage_vertex_values -> dimensions[0]; // Call underlying flux computation routine and update // the explicit update arrays timestep = _compute_fluxes_ext(timestep, epsilon, g, (long*) neighbours -> data, (long*) neighbour_vertices -> data, (double*) normals -> data, (double*) areas -> data, (double*) stage_vertex_values -> data, (double*) xmom_vertex_values -> data, (double*) bed_vertex_values -> data, (double*) stage_boundary_values -> data, (double*) xmom_boundary_values -> data, (double*) stage_explicit_update -> data, (double*) xmom_explicit_update -> data, number_of_elements, (double*) max_speed_array -> data); Py_DECREF(neighbours); Py_DECREF(neighbour_vertices); Py_DECREF(normals); Py_DECREF(areas); Py_DECREF(stage_vertex_values); Py_DECREF(xmom_vertex_values); Py_DECREF(bed_vertex_values); Py_DECREF(stage_boundary_values); Py_DECREF(xmom_boundary_values); Py_DECREF(stage_explicit_update); Py_DECREF(xmom_explicit_update); Py_DECREF(max_speed_array); // Return updated flux timestep return Py_BuildValue("d", timestep); } //------------------------------- // Method table for python module //------------------------------- static struct PyMethodDef MethodTable[] = { {"compute_fluxes_ext", compute_fluxes_ext, METH_VARARGS, "Print out"}, {"compute_fluxes_ext_short", compute_fluxes_ext_short, METH_VARARGS, "Print out"}, {NULL, NULL} }; // Module initialisation void initcomp_flux_ext(void){ Py_InitModule("comp_flux_ext", MethodTable); import_array(); }