Changeset 1509


Ignore:
Timestamp:
Jun 9, 2005, 4:09:13 PM (19 years ago)
Author:
matthew
Message:

The new method h_limiter_sw is an alternative to h_limiter that does not use malloc and free. It is defined as a PyObject?* method in shallow_water_ext.c. In shallow_water.py, we import h_limiter_sw as h_limiter so that the rest of the python code effectively uses h_limiter_sw instead of h_limiter.

For run_profile.py, with N=128, the previous version of h_limiter consumed 5.48 seconds, averaged over three runs. Importing h_limiter_sw as h_limiter, h_limiter now consumes 4.42 seconds.

Location:
inundation/ga/storm_surge/pyvolution
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • inundation/ga/storm_surge/pyvolution/shallow_water.py

    r1508 r1509  
    775775
    776776    #Call C-extension
    777     from shallow_water_ext import h_limiter
     777    from shallow_water_ext import h_limiter_sw as h_limiter
    778778    hvbar = h_limiter(domain, hc, hv)
    779779
  • inundation/ga/storm_surge/pyvolution/shallow_water_ext.c

    r1508 r1509  
    11781178}
    11791179
    1180 
    1181 
     1180PyObject *h_limiter_sw(PyObject *self, PyObject *args) {
     1181  //a faster version of h_limiter above
     1182  PyObject *domain, *Tmp;
     1183  PyArrayObject
     1184    *hv, *hc, //Depth at vertices and centroids
     1185    *hvbar,   //Limited depth at vertices (return values)
     1186    *neighbours;
     1187
     1188  int k, i, N, k3,k0,k1,k2;
     1189  int dimensions[2];
     1190  double beta_h; //Safety factor (see config.py)
     1191  double hmin, hmax, dh[3];
     1192  // Convert Python arguments to C
     1193  if (!PyArg_ParseTuple(args, "OOO", &domain, &hc, &hv))
     1194    return NULL;
     1195  neighbours = get_consecutive_array(domain, "neighbours");
     1196 
     1197  //Get safety factor beta_h
     1198  Tmp = PyObject_GetAttrString(domain, "beta_h");
     1199  if (!Tmp)
     1200    return NULL;
     1201  beta_h = PyFloat_AsDouble(Tmp);
     1202
     1203  Py_DECREF(Tmp);
     1204
     1205  N = hc -> dimensions[0];
     1206
     1207  //Create hvbar
     1208  dimensions[0] = N;
     1209  dimensions[1] = 3;
     1210  hvbar = (PyArrayObject *) PyArray_FromDims(2, dimensions, PyArray_DOUBLE);
     1211  for (k=0;k<N;k++){
     1212    k3=k*3;
     1213    //get the ids of the neighbours
     1214    k0 = ((long*) neighbours -> data)[k3];
     1215    k1 = ((long*) neighbours -> data)[k3+1];
     1216    k2 = ((long*) neighbours -> data)[k3+2];
     1217    //set hvbar provisionally
     1218    for (i=0;i<3;i++){
     1219      ((double*) hvbar -> data)[k3+i] = ((double*) hv -> data)[k3+i];
     1220      dh[i]=((double*) hvbar -> data)[k3+i]-((double*) hc -> data)[k];
     1221    }
     1222    hmin=((double*) hc -> data)[k];
     1223    hmax=hmin;
     1224    if (k0>=0){
     1225      hmin=min(hmin,((double*) hc -> data)[k0]);
     1226      hmax=max(hmax,((double*) hc -> data)[k0]);
     1227    }
     1228    if (k1>=0){
     1229      hmin=min(hmin,((double*) hc -> data)[k1]);
     1230      hmax=max(hmax,((double*) hc -> data)[k1]);
     1231    }
     1232    if (k2>=0){
     1233      hmin=min(hmin,((double*) hc -> data)[k2]);
     1234      hmax=max(hmax,((double*) hc -> data)[k2]);
     1235    }
     1236    hmin-=((double*) hc -> data)[k];
     1237    hmax-=((double*) hc -> data)[k];
     1238    limit_gradient(dh,hmin,hmax,beta_h);
     1239    for (i=0;i<3;i++)
     1240      ((double*) hvbar -> data)[k3+i] = ((double*) hc -> data)[k]+dh[i];
     1241  }
     1242  return PyArray_Return(hvbar);
     1243}
    11821244
    11831245PyObject *assign_windfield_values(PyObject *self, PyObject *args) {
     
    12371299   METH_VARARGS, "Print out"},
    12381300  {"h_limiter", h_limiter,
     1301   METH_VARARGS, "Print out"},
     1302  {"h_limiter_sw", h_limiter_sw,
    12391303   METH_VARARGS, "Print out"},
    12401304  {"protect", protect, METH_VARARGS | METH_KEYWORDS, "Print out"},
Note: See TracChangeset for help on using the changeset viewer.