Cython: quantity_ext.pyx

Generated by Cython 0.29.28

Yellow lines hint at Python interaction.
Click on a line that starts with a "`+`" to see the C code that Cython generated for it.

Raw output: quantity_ext.c

    +001: #cython: wraparound=False, boundscheck=False, cdivision=True, profile=False, nonecheck=False, overflowcheck=False, cdivision_warnings=False, unraisable_tracebacks=False

      __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

     002: import cython

     003:

     004: # import both numpy and the Cython declarations for numpy

    +005: import numpy as np

      __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 5, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

     006: cimport numpy as np

     007:

     008: ctypedef long keyint

     009:

     010: # declare the interface to the C code

     011: cdef extern from "quantity.c":

     012:   int _compute_gradients(keyint N, double* centroids, double* centroid_values, long* number_of_boundaries, long* surrogate_neighbours, double* a, double* b)

     013:   int _compute_local_gradients(keyint N, double* vertex_coordinates, double* vertex_values, double* a, double* b)

     014:   int _extrapolate_from_gradient(keyint N, double* centroids, double* centroid_values, double* vertex_coordinates, double* vertex_values, double* edge_values, double* a, double* b)

     015:   int _extrapolate_and_limit_from_gradient(keyint N, double beta, double* centroids, long* neighbours, double* centroid_values, double* vertex_coordinates, double* vertex_values, double* edge_values, double* phi, double* x_gradient, double* y_gradient)

     016:   int _limit_vertices_by_all_neighbours(keyint N, double beta, double* centroid_values, double* vertex_values, double* edge_values, long* neighbours, double* x_gradient, double* y_gradient)

     017:   int _limit_edges_by_all_neighbours(keyint N, double beta, double* centroid_values, double* vertex_values, double* edge_values, long* neighbours, double* x_gradient, double* y_gradient)

     018:   int _limit_edges_by_neighbour(keyint N, double beta, double* centroid_values, double* vertex_values, double* edge_values, long* neighbours)

     019:   int _limit_gradient_by_neighbour(keyint N, double beta, double* centroid_values, double* vertex_values, double* edge_values, double* x_gradient, double* y_gradient, long* neighbours)

     020:   int _bound_vertices_below_by_constant(keyint N, double bound, double* centroid_values, double* vertex_values, double* edge_values, double* x_gradient, double* y_gradient)

     021:   int _bound_vertices_below_by_quantity(keyint N, double* bound_vertex_values, double* centroid_values, double* vertex_values, double* edge_values, double* x_gradient, double* y_gradient)

     022:   int _interpolate(keyint N, double* vertex_values, double* edge_values, double* centroid_values)

     023:   int _interpolate_from_vertices_to_edges(keyint N, double* vertex_values, double* edge_values)

     024:   int _interpolate_from_edges_to_vertices(keyint N, double* vertex_values, double* edge_values)

     025:   int _backup_centroid_values(keyint N, double* centroid_values, double* centroid_backup_values)

     026:   int _saxpy_centroid_values(keyint N, double a, double b, double* centroid_values, double* centroid_backup_values)

     027:   int _update(keyint N, double timestep, double* centroid_values, double* explicit_update, double* semi_implicit_update)

     028:   int _average_vertex_values(keyint N, long* vertex_value_indices, long* number_of_triangles_per_node, double* vertex_values, double* A)

     029:   int _average_centroid_values(keyint N, long* vertex_value_indices, long* number_of_triangles_per_node, double* centroid_values, double* A)

     030:   int _set_vertex_values_c(keyint num_verts, long* vertices, long* node_index, long* number_of_triangles_per_node, long* vertex_value_indices, double* vertex_values, double* A)

     031:   int _min_and_max_centroid_values(keyint N, double* qc, double* qv, long* neighbours, double* qmin, double* qmax)

     032:

     033: cdef extern from "util_ext.h":

     034:   void _limit_old(int N, double beta, double* qc, double* qv, double* qmin, double* qmax)

     035:

     036:

    +037: def update(object quantity, double timestep):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_1update(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static char __pyx_doc_5anuga_26abstract_2d_finite_volumes_12quantity_ext_update[] = "Update centroid values based on values stored in\n    explicit_update and semi_implicit_update as well as given timestep\n\n    Function implementing forcing terms must take on argument\n    which is the domain and they must update either explicit\n    or implicit updates, e,g,:\n\n    def gravity(domain):\n        ....\n        domain.quantities['xmomentum'].explicit_update = ...\n        domain.quantities['ymomentum'].explicit_update = ...\n\n\n\n    Explicit terms must have the form\n\n        G(q, t)\n\n    and explicit scheme is\n\n       q^{(n+1}) = q^{(n)} + delta_t G(q^{n}, n delta_t)\n\n\n    Semi implicit forcing terms are assumed to have the form\n\n       G(q, t) = H(q, t) q\n\n    and the semi implicit scheme will then be\n\n      q^{(n+1}) = q^{(n)} + delta_t H(q^{n}, n delta_t) q^{(n+1})";
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_1update = {"update", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_1update, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5anuga_26abstract_2d_finite_volumes_12quantity_ext_update};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_1update(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
      PyObject *__pyx_v_quantity = 0;
      double __pyx_v_timestep;
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("update (wrapper)", 0);
      {
        static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_quantity,&__pyx_n_s_timestep,0};
        PyObject* values[2] = {0,0};
        if (unlikely(__pyx_kwds)) {
          Py_ssize_t kw_args;
          const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
          switch (pos_args) {
            case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
            CYTHON_FALLTHROUGH;
            case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
            CYTHON_FALLTHROUGH;
            case  0: break;
            default: goto __pyx_L5_argtuple_error;
          }
          kw_args = PyDict_Size(__pyx_kwds);
          switch (pos_args) {
            case  0:
            if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_quantity)) != 0)) kw_args--;
            else goto __pyx_L5_argtuple_error;
            CYTHON_FALLTHROUGH;
            case  1:
            if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_timestep)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("update", 1, 2, 2, 1); __PYX_ERR(0, 37, __pyx_L3_error)
            }
          }
          if (unlikely(kw_args > 0)) {
            if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "update") < 0)) __PYX_ERR(0, 37, __pyx_L3_error)
          }
        } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
          goto __pyx_L5_argtuple_error;
        } else {
          values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
          values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        }
        __pyx_v_quantity = values[0];
        __pyx_v_timestep = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_timestep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 37, __pyx_L3_error)
      }
      goto __pyx_L4_argument_unpacking_done;
      __pyx_L5_argtuple_error:;
      __Pyx_RaiseArgtupleInvalid("update", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 37, __pyx_L3_error)
      __pyx_L3_error:;
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.update", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __Pyx_RefNannyFinishContext();
      return NULL;
      __pyx_L4_argument_unpacking_done:;
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_update(__pyx_self, __pyx_v_quantity, __pyx_v_timestep);
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_update(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity, double __pyx_v_timestep) {
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_explicit_update = 0;
      PyArrayObject *__pyx_v_semi_implicit_update = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_explicit_update;
      __Pyx_Buffer __pyx_pybuffer_explicit_update;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_semi_implicit_update;
      __Pyx_Buffer __pyx_pybuffer_semi_implicit_update;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("update", 0);
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_explicit_update.pybuffer.buf = NULL;
      __pyx_pybuffer_explicit_update.refcount = 0;
      __pyx_pybuffernd_explicit_update.data = NULL;
      __pyx_pybuffernd_explicit_update.rcbuffer = &__pyx_pybuffer_explicit_update;
      __pyx_pybuffer_semi_implicit_update.pybuffer.buf = NULL;
      __pyx_pybuffer_semi_implicit_update.refcount = 0;
      __pyx_pybuffernd_semi_implicit_update.data = NULL;
      __pyx_pybuffernd_semi_implicit_update.rcbuffer = &__pyx_pybuffer_semi_implicit_update;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_explicit_update.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_semi_implicit_update.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.update", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_explicit_update.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_semi_implicit_update.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_explicit_update);
      __Pyx_XDECREF((PyObject *)__pyx_v_semi_implicit_update);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__3 = PyTuple_Pack(7, __pyx_n_s_quantity, __pyx_n_s_timestep, __pyx_n_s_centroid_values, __pyx_n_s_explicit_update, __pyx_n_s_semi_implicit_update, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 37, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__3);
      __Pyx_GIVEREF(__pyx_tuple__3);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_1update, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 37, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_update, __pyx_t_1) < 0) __PYX_ERR(0, 37, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__4 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__3, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_update, 37, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__4)) __PYX_ERR(0, 37, __pyx_L1_error)

     038:   """Update centroid values based on values stored in

     039:     explicit_update and semi_implicit_update as well as given timestep

     040:

     041:     Function implementing forcing terms must take on argument

     042:     which is the domain and they must update either explicit

     043:     or implicit updates, e,g,:

     044:

     045:     def gravity(domain):

     046:         ....

     047:         domain.quantities['xmomentum'].explicit_update = ...

     048:         domain.quantities['ymomentum'].explicit_update = ...

     049:

     050:

     051:

     052:     Explicit terms must have the form

     053:

     054:         G(q, t)

     055:

     056:     and explicit scheme is

     057:

     058:        q^{(n+1}) = q^{(n)} + delta_t G(q^{n}, n delta_t)

     059:

     060:

     061:     Semi implicit forcing terms are assumed to have the form

     062:

     063:        G(q, t) = H(q, t) q

     064:

     065:     and the semi implicit scheme will then be

     066:

     067:       q^{(n+1}) = q^{(n)} + delta_t H(q^{n}, n delta_t) q^{(n+1})"""

     068:

     069:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     070:   cdef np.ndarray[double, ndim=1, mode="c"] explicit_update

     071:   cdef np.ndarray[double, ndim=1, mode="c"] semi_implicit_update

     072:

     073:   cdef keyint N

     074:   cdef int err

     075:

    +076:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 76, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 76, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 76, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +077:   explicit_update = quantity.explicit_update

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_explicit_update); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 77, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_explicit_update.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_explicit_update.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_explicit_update.rcbuffer->pybuffer, (PyObject*)__pyx_v_explicit_update, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_explicit_update.diminfo[0].strides = __pyx_pybuffernd_explicit_update.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_explicit_update.diminfo[0].shape = __pyx_pybuffernd_explicit_update.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 77, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_explicit_update = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +078:   semi_implicit_update = quantity.semi_implicit_update

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_semi_implicit_update); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 78, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_semi_implicit_update.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_semi_implicit_update.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_semi_implicit_update.rcbuffer->pybuffer, (PyObject*)__pyx_v_semi_implicit_update, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_semi_implicit_update.diminfo[0].strides = __pyx_pybuffernd_semi_implicit_update.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_semi_implicit_update.diminfo[0].shape = __pyx_pybuffernd_semi_implicit_update.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 78, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_semi_implicit_update = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     079:

    +080:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     081:

    +082:   err = _update(N, timestep, &centroid_values[0], &explicit_update[0], &semi_implicit_update[0])

      __pyx_t_9 = 0;
      __pyx_t_10 = 0;
      __pyx_t_11 = 0;
      __pyx_v_err = _update(__pyx_v_N, __pyx_v_timestep, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_explicit_update.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_explicit_update.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_semi_implicit_update.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_semi_implicit_update.diminfo[0].strides))));

     083:

    +084:   assert err == 0, "quantity_ext.c: update, division by zero in semi implicit update - call Stephen :)"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_quantity_ext_c_update_division_b);
          __PYX_ERR(0, 84, __pyx_L1_error)
        }
      }
      #endif

     085:

     086:

    +087: def backup_centroid_values(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_3backup_centroid_values(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_3backup_centroid_values = {"backup_centroid_values", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_3backup_centroid_values, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_3backup_centroid_values(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("backup_centroid_values (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_2backup_centroid_values(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_2backup_centroid_values(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_centroid_backup_values = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      CYTHON_UNUSED int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_backup_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_backup_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("backup_centroid_values", 0);
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_centroid_backup_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_backup_values.refcount = 0;
      __pyx_pybuffernd_centroid_backup_values.data = NULL;
      __pyx_pybuffernd_centroid_backup_values.rcbuffer = &__pyx_pybuffer_centroid_backup_values;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.backup_centroid_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_backup_values);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__5 = PyTuple_Pack(5, __pyx_n_s_quantity, __pyx_n_s_centroid_values, __pyx_n_s_centroid_backup_values, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 87, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__5);
      __Pyx_GIVEREF(__pyx_tuple__5);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_3backup_centroid_values, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_backup_centroid_values, __pyx_t_1) < 0) __PYX_ERR(0, 87, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__6 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__5, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_backup_centroid_values, 87, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__6)) __PYX_ERR(0, 87, __pyx_L1_error)

     088:

     089:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     090:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_backup_values

     091:

     092:   cdef keyint N

     093:   cdef int err

     094:

    +095:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 95, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 95, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 95, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +096:   centroid_backup_values = quantity.centroid_backup_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_backup_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 96, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 96, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_backup_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_centroid_backup_values.diminfo[0].strides = __pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_backup_values.diminfo[0].shape = __pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 96, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_centroid_backup_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     097:

    +098:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     099:

    +100:   err = _backup_centroid_values(N, &centroid_values[0], &centroid_backup_values[0])

      __pyx_t_8 = 0;
      __pyx_t_9 = 0;
      __pyx_v_err = _backup_centroid_values(__pyx_v_N, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_centroid_backup_values.diminfo[0].strides))));

     101:

    +102: def saxpy_centroid_values(object quantity, double a, double b):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_5saxpy_centroid_values(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_5saxpy_centroid_values = {"saxpy_centroid_values", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_5saxpy_centroid_values, METH_VARARGS|METH_KEYWORDS, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_5saxpy_centroid_values(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
      PyObject *__pyx_v_quantity = 0;
      double __pyx_v_a;
      double __pyx_v_b;
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("saxpy_centroid_values (wrapper)", 0);
      {
        static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_quantity,&__pyx_n_s_a,&__pyx_n_s_b,0};
        PyObject* values[3] = {0,0,0};
        if (unlikely(__pyx_kwds)) {
          Py_ssize_t kw_args;
          const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
          switch (pos_args) {
            case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
            CYTHON_FALLTHROUGH;
            case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
            CYTHON_FALLTHROUGH;
            case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
            CYTHON_FALLTHROUGH;
            case  0: break;
            default: goto __pyx_L5_argtuple_error;
          }
          kw_args = PyDict_Size(__pyx_kwds);
          switch (pos_args) {
            case  0:
            if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_quantity)) != 0)) kw_args--;
            else goto __pyx_L5_argtuple_error;
            CYTHON_FALLTHROUGH;
            case  1:
            if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_a)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("saxpy_centroid_values", 1, 3, 3, 1); __PYX_ERR(0, 102, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  2:
            if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_b)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("saxpy_centroid_values", 1, 3, 3, 2); __PYX_ERR(0, 102, __pyx_L3_error)
            }
          }
          if (unlikely(kw_args > 0)) {
            if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "saxpy_centroid_values") < 0)) __PYX_ERR(0, 102, __pyx_L3_error)
          }
        } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
          goto __pyx_L5_argtuple_error;
        } else {
          values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
          values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
          values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        }
        __pyx_v_quantity = values[0];
        __pyx_v_a = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_a == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 102, __pyx_L3_error)
        __pyx_v_b = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_b == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 102, __pyx_L3_error)
      }
      goto __pyx_L4_argument_unpacking_done;
      __pyx_L5_argtuple_error:;
      __Pyx_RaiseArgtupleInvalid("saxpy_centroid_values", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 102, __pyx_L3_error)
      __pyx_L3_error:;
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.saxpy_centroid_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __Pyx_RefNannyFinishContext();
      return NULL;
      __pyx_L4_argument_unpacking_done:;
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_4saxpy_centroid_values(__pyx_self, __pyx_v_quantity, __pyx_v_a, __pyx_v_b);
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_4saxpy_centroid_values(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity, double __pyx_v_a, double __pyx_v_b) {
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_centroid_backup_values = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      CYTHON_UNUSED int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_backup_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_backup_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("saxpy_centroid_values", 0);
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_centroid_backup_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_backup_values.refcount = 0;
      __pyx_pybuffernd_centroid_backup_values.data = NULL;
      __pyx_pybuffernd_centroid_backup_values.rcbuffer = &__pyx_pybuffer_centroid_backup_values;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.saxpy_centroid_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_backup_values);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__7 = PyTuple_Pack(7, __pyx_n_s_quantity, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_centroid_values, __pyx_n_s_centroid_backup_values, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 102, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__7);
      __Pyx_GIVEREF(__pyx_tuple__7);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_5saxpy_centroid_values, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_saxpy_centroid_values, __pyx_t_1) < 0) __PYX_ERR(0, 102, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(3, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__7, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_saxpy_centroid_values, 102, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) __PYX_ERR(0, 102, __pyx_L1_error)

     103:

     104:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     105:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_backup_values

     106:

     107:   cdef keyint N

     108:   cdef int err

     109:

    +110:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 110, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 110, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 110, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +111:   centroid_backup_values = quantity.centroid_backup_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_backup_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 111, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 111, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_backup_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_centroid_backup_values.diminfo[0].strides = __pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_backup_values.diminfo[0].shape = __pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 111, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_centroid_backup_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     112:

    +113:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     114:

    +115:   err = _saxpy_centroid_values(N, a, b, &centroid_values[0], &centroid_backup_values[0])

      __pyx_t_8 = 0;
      __pyx_t_9 = 0;
      __pyx_v_err = _saxpy_centroid_values(__pyx_v_N, __pyx_v_a, __pyx_v_b, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_backup_values.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_centroid_backup_values.diminfo[0].strides))));

     116:

     117:

    +118: def set_vertex_values_c(object quantity, np.ndarray[long, ndim=1, mode="c"] vertices not None, np.ndarray[double, ndim=1, mode="c"] A not None):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_7set_vertex_values_c(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_7set_vertex_values_c = {"set_vertex_values_c", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_7set_vertex_values_c, METH_VARARGS|METH_KEYWORDS, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_7set_vertex_values_c(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
      PyObject *__pyx_v_quantity = 0;
      PyArrayObject *__pyx_v_vertices = 0;
      PyArrayObject *__pyx_v_A = 0;
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("set_vertex_values_c (wrapper)", 0);
      {
        static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_quantity,&__pyx_n_s_vertices,&__pyx_n_s_A,0};
        PyObject* values[3] = {0,0,0};
        if (unlikely(__pyx_kwds)) {
          Py_ssize_t kw_args;
          const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
          switch (pos_args) {
            case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
            CYTHON_FALLTHROUGH;
            case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
            CYTHON_FALLTHROUGH;
            case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
            CYTHON_FALLTHROUGH;
            case  0: break;
            default: goto __pyx_L5_argtuple_error;
          }
          kw_args = PyDict_Size(__pyx_kwds);
          switch (pos_args) {
            case  0:
            if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_quantity)) != 0)) kw_args--;
            else goto __pyx_L5_argtuple_error;
            CYTHON_FALLTHROUGH;
            case  1:
            if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_vertices)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("set_vertex_values_c", 1, 3, 3, 1); __PYX_ERR(0, 118, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  2:
            if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("set_vertex_values_c", 1, 3, 3, 2); __PYX_ERR(0, 118, __pyx_L3_error)
            }
          }
          if (unlikely(kw_args > 0)) {
            if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_vertex_values_c") < 0)) __PYX_ERR(0, 118, __pyx_L3_error)
          }
        } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
          goto __pyx_L5_argtuple_error;
        } else {
          values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
          values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
          values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        }
        __pyx_v_quantity = values[0];
        __pyx_v_vertices = ((PyArrayObject *)values[1]);
        __pyx_v_A = ((PyArrayObject *)values[2]);
      }
      goto __pyx_L4_argument_unpacking_done;
      __pyx_L5_argtuple_error:;
      __Pyx_RaiseArgtupleInvalid("set_vertex_values_c", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 118, __pyx_L3_error)
      __pyx_L3_error:;
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.set_vertex_values_c", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __Pyx_RefNannyFinishContext();
      return NULL;
      __pyx_L4_argument_unpacking_done:;
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertices), __pyx_ptype_5numpy_ndarray, 0, "vertices", 0))) __PYX_ERR(0, 118, __pyx_L1_error)
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_A), __pyx_ptype_5numpy_ndarray, 0, "A", 0))) __PYX_ERR(0, 118, __pyx_L1_error)
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_6set_vertex_values_c(__pyx_self, __pyx_v_quantity, __pyx_v_vertices, __pyx_v_A);
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      goto __pyx_L0;
      __pyx_L1_error:;
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_6set_vertex_values_c(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_A) {
      PyObject *__pyx_v_domain = 0;
      PyObject *__pyx_v_mesh = 0;
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_node_index = 0;
      PyArrayObject *__pyx_v_number_of_triangles_per_node = 0;
      PyArrayObject *__pyx_v_vertex_value_indices = 0;
      CYTHON_UNUSED int __pyx_v_err;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_num_verts;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_A;
      __Pyx_Buffer __pyx_pybuffer_A;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_node_index;
      __Pyx_Buffer __pyx_pybuffer_node_index;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_number_of_triangles_per_node;
      __Pyx_Buffer __pyx_pybuffer_number_of_triangles_per_node;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_value_indices;
      __Pyx_Buffer __pyx_pybuffer_vertex_value_indices;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertices;
      __Pyx_Buffer __pyx_pybuffer_vertices;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("set_vertex_values_c", 0);
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_node_index.pybuffer.buf = NULL;
      __pyx_pybuffer_node_index.refcount = 0;
      __pyx_pybuffernd_node_index.data = NULL;
      __pyx_pybuffernd_node_index.rcbuffer = &__pyx_pybuffer_node_index;
      __pyx_pybuffer_number_of_triangles_per_node.pybuffer.buf = NULL;
      __pyx_pybuffer_number_of_triangles_per_node.refcount = 0;
      __pyx_pybuffernd_number_of_triangles_per_node.data = NULL;
      __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer = &__pyx_pybuffer_number_of_triangles_per_node;
      __pyx_pybuffer_vertex_value_indices.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_value_indices.refcount = 0;
      __pyx_pybuffernd_vertex_value_indices.data = NULL;
      __pyx_pybuffernd_vertex_value_indices.rcbuffer = &__pyx_pybuffer_vertex_value_indices;
      __pyx_pybuffer_vertices.pybuffer.buf = NULL;
      __pyx_pybuffer_vertices.refcount = 0;
      __pyx_pybuffernd_vertices.data = NULL;
      __pyx_pybuffernd_vertices.rcbuffer = &__pyx_pybuffer_vertices;
      __pyx_pybuffer_A.pybuffer.buf = NULL;
      __pyx_pybuffer_A.refcount = 0;
      __pyx_pybuffernd_A.data = NULL;
      __pyx_pybuffernd_A.rcbuffer = &__pyx_pybuffer_A;
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertices, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 118, __pyx_L1_error)
      }
      __pyx_pybuffernd_vertices.diminfo[0].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertices.diminfo[0].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[0];
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_A.rcbuffer->pybuffer, (PyObject*)__pyx_v_A, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 118, __pyx_L1_error)
      }
      __pyx_pybuffernd_A.diminfo[0].strides = __pyx_pybuffernd_A.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_A.diminfo[0].shape = __pyx_pybuffernd_A.rcbuffer->pybuffer.shape[0];
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_A.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_node_index.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.set_vertex_values_c", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_A.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_node_index.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF(__pyx_v_mesh);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_node_index);
      __Pyx_XDECREF((PyObject *)__pyx_v_number_of_triangles_per_node);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_value_indices);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__9 = PyTuple_Pack(12, __pyx_n_s_quantity, __pyx_n_s_vertices, __pyx_n_s_A, __pyx_n_s_domain, __pyx_n_s_mesh, __pyx_n_s_vertex_values, __pyx_n_s_node_index, __pyx_n_s_number_of_triangles_per_node, __pyx_n_s_vertex_value_indices, __pyx_n_s_N, __pyx_n_s_err, __pyx_n_s_num_verts); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 118, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__9);
      __Pyx_GIVEREF(__pyx_tuple__9);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_7set_vertex_values_c, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 118, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_set_vertex_values_c, __pyx_t_1) < 0) __PYX_ERR(0, 118, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__10 = (PyObject*)__Pyx_PyCode_New(3, 0, 12, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__9, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_set_vertex_values_c, 118, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__10)) __PYX_ERR(0, 118, __pyx_L1_error)

     119:

     120:   cdef object domain

     121:   cdef object mesh

     122:

     123:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     124:   cdef np.ndarray[long, ndim=1, mode="c"] node_index

     125:   cdef np.ndarray[long, ndim=1, mode="c"] number_of_triangles_per_node

     126:   cdef np.ndarray[long, ndim=1, mode="c"] vertex_value_indices

     127:

     128:   cdef keyint N

     129:   cdef int err

     130:   cdef keyint num_verts

     131:

    +132:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 132, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

    +133:   mesh = domain.mesh

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_mesh); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 133, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_mesh = __pyx_t_1;
      __pyx_t_1 = 0;

     134:

    +135:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 135, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 135, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 135, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +136:   node_index = mesh.node_index

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_mesh, __pyx_n_s_node_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 136, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_node_index.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_node_index.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_node_index.rcbuffer->pybuffer, (PyObject*)__pyx_v_node_index, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_node_index.diminfo[0].strides = __pyx_pybuffernd_node_index.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_node_index.diminfo[0].shape = __pyx_pybuffernd_node_index.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 136, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_node_index = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +137:   number_of_triangles_per_node = mesh.number_of_triangles_per_node

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_mesh, __pyx_n_s_number_of_triangles_per_node); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 137, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 137, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer, (PyObject*)__pyx_v_number_of_triangles_per_node, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_number_of_triangles_per_node.diminfo[0].strides = __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_number_of_triangles_per_node.diminfo[0].shape = __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 137, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_number_of_triangles_per_node = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +138:   vertex_value_indices = mesh.vertex_value_indices

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_mesh, __pyx_n_s_vertex_value_indices); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 138, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 138, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_value_indices, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_vertex_value_indices.diminfo[0].strides = __pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_value_indices.diminfo[0].shape = __pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 138, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_vertex_value_indices = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     139:

    +140:   num_verts = vertices.shape[0]

      __pyx_v_num_verts = (__pyx_v_vertices->dimensions[0]);

     141:

    +142:   err = _set_vertex_values_c(num_verts, &vertices[0], &node_index[0], &number_of_triangles_per_node[0], &vertex_value_indices[0], &vertex_values[0,0], &A[0])

      __pyx_t_10 = 0;
      __pyx_t_11 = 0;
      __pyx_t_12 = 0;
      __pyx_t_13 = 0;
      __pyx_t_14 = 0;
      __pyx_t_15 = 0;
      __pyx_t_16 = 0;
      __pyx_v_err = _set_vertex_values_c(__pyx_v_num_verts, (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_vertices.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_vertices.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_node_index.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_node_index.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_number_of_triangles_per_node.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_vertex_value_indices.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_A.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_A.diminfo[0].strides))));

     143:

     144:

    +145: def interpolate(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_9interpolate(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_9interpolate = {"interpolate", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_9interpolate, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_9interpolate(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("interpolate (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_8interpolate(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_8interpolate(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_edge_values = 0;
      PyArrayObject *__pyx_v_centroid_values = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("interpolate", 0);
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.interpolate", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__11 = PyTuple_Pack(6, __pyx_n_s_quantity, __pyx_n_s_vertex_values, __pyx_n_s_edge_values, __pyx_n_s_centroid_values, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(0, 145, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__11);
      __Pyx_GIVEREF(__pyx_tuple__11);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_9interpolate, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 145, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_interpolate, __pyx_t_1) < 0) __PYX_ERR(0, 145, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__12 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_interpolate, 145, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__12)) __PYX_ERR(0, 145, __pyx_L1_error)

     146:

     147:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     148:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     149:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     150:

     151:   cdef keyint N

     152:   cdef int err

     153:

    +154:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 154, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 154, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 154, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +155:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 155, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 155, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 155, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +156:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 156, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 156, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 156, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     157:

    +158:   N = vertex_values.shape[0]

      __pyx_v_N = (__pyx_v_vertex_values->dimensions[0]);

     159:

    +160:   err = _interpolate(N, &vertex_values[0,0], &edge_values[0,0], &centroid_values[0])

      __pyx_t_9 = 0;
      __pyx_t_10 = 0;
      __pyx_t_11 = 0;
      __pyx_t_12 = 0;
      __pyx_t_13 = 0;
      __pyx_v_err = _interpolate(__pyx_v_N, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_10, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_edge_values.diminfo[0].strides, __pyx_t_12, __pyx_pybuffernd_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_centroid_values.diminfo[0].strides))));

     161:

    +162:   assert err == 0, "Interpolate could not be computed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Interpolate_could_not_be_compute);
          __PYX_ERR(0, 162, __pyx_L1_error)
        }
      }
      #endif

     163:

    +164: def interpolate_from_vertices_to_edges(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_11interpolate_from_vertices_to_edges(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_11interpolate_from_vertices_to_edges = {"interpolate_from_vertices_to_edges", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_11interpolate_from_vertices_to_edges, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_11interpolate_from_vertices_to_edges(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("interpolate_from_vertices_to_edges (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_10interpolate_from_vertices_to_edges(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_10interpolate_from_vertices_to_edges(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_edge_values = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("interpolate_from_vertices_to_edges", 0);
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.interpolate_from_vertices_to_edges", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__13 = PyTuple_Pack(5, __pyx_n_s_quantity, __pyx_n_s_vertex_values, __pyx_n_s_edge_values, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 164, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__13);
      __Pyx_GIVEREF(__pyx_tuple__13);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_11interpolate_from_vertices_to_edges, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 164, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_interpolate_from_vertices_to_edg, __pyx_t_1) < 0) __PYX_ERR(0, 164, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_interpolate_from_vertices_to_edg, 164, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) __PYX_ERR(0, 164, __pyx_L1_error)

     165:

     166:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     167:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     168:

     169:   cdef keyint N

     170:   cdef int err

     171:

    +172:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 172, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 172, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 172, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +173:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 173, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 173, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 173, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     174:

    +175:   N = vertex_values.shape[0]

      __pyx_v_N = (__pyx_v_vertex_values->dimensions[0]);

     176:

    +177:   err = _interpolate_from_vertices_to_edges(N, &vertex_values[0,0], &edge_values[0,0])

      __pyx_t_8 = 0;
      __pyx_t_9 = 0;
      __pyx_t_10 = 0;
      __pyx_t_11 = 0;
      __pyx_v_err = _interpolate_from_vertices_to_edges(__pyx_v_N, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_9, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_edge_values.diminfo[0].strides, __pyx_t_11, __pyx_pybuffernd_edge_values.diminfo[1].strides))));

     178:

    +179:   assert err == 0, "Interpolate could not be computed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Interpolate_could_not_be_compute);
          __PYX_ERR(0, 179, __pyx_L1_error)
        }
      }
      #endif

     180:

    +181: def interpolate_from_edges_to_vertices(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_13interpolate_from_edges_to_vertices(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_13interpolate_from_edges_to_vertices = {"interpolate_from_edges_to_vertices", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_13interpolate_from_edges_to_vertices, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_13interpolate_from_edges_to_vertices(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("interpolate_from_edges_to_vertices (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_12interpolate_from_edges_to_vertices(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_12interpolate_from_edges_to_vertices(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_edge_values = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("interpolate_from_edges_to_vertices", 0);
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.interpolate_from_edges_to_vertices", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__15 = PyTuple_Pack(5, __pyx_n_s_quantity, __pyx_n_s_vertex_values, __pyx_n_s_edge_values, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(0, 181, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__15);
      __Pyx_GIVEREF(__pyx_tuple__15);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_13interpolate_from_edges_to_vertices, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 181, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_interpolate_from_edges_to_vertic, __pyx_t_1) < 0) __PYX_ERR(0, 181, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__16 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__15, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_interpolate_from_edges_to_vertic, 181, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__16)) __PYX_ERR(0, 181, __pyx_L1_error)

     182:

     183:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     184:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     185:

     186:   cdef keyint N

     187:   cdef int err

     188:

    +189:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 189, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 189, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 189, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +190:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 190, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 190, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 190, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     191:

    +192:   N = vertex_values.shape[0]

      __pyx_v_N = (__pyx_v_vertex_values->dimensions[0]);

     193:

    +194:   err = _interpolate_from_edges_to_vertices(N, &vertex_values[0,0], &edge_values[0,0])

      __pyx_t_8 = 0;
      __pyx_t_9 = 0;
      __pyx_t_10 = 0;
      __pyx_t_11 = 0;
      __pyx_v_err = _interpolate_from_edges_to_vertices(__pyx_v_N, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_9, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_edge_values.diminfo[0].strides, __pyx_t_11, __pyx_pybuffernd_edge_values.diminfo[1].strides))));

     195:

    +196:   assert err == 0, "Interpolate could not be computed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Interpolate_could_not_be_compute);
          __PYX_ERR(0, 196, __pyx_L1_error)
        }
      }
      #endif

     197:

    +198: def average_vertex_values(np.ndarray[long, ndim=1, mode="c"] vertex_value_indices not None, np.ndarray[long, ndim=1, mode="c"] number_of_triangles_per_node not None, np.ndarray[double, ndim=2, mode="c"] vertex_values not None, np.ndarray[double, ndim=1, mode="c"] A not None):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_15average_vertex_values(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_15average_vertex_values = {"average_vertex_values", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_15average_vertex_values, METH_VARARGS|METH_KEYWORDS, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_15average_vertex_values(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
      PyArrayObject *__pyx_v_vertex_value_indices = 0;
      PyArrayObject *__pyx_v_number_of_triangles_per_node = 0;
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_A = 0;
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("average_vertex_values (wrapper)", 0);
      {
        static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_vertex_value_indices,&__pyx_n_s_number_of_triangles_per_node,&__pyx_n_s_vertex_values,&__pyx_n_s_A,0};
        PyObject* values[4] = {0,0,0,0};
        if (unlikely(__pyx_kwds)) {
          Py_ssize_t kw_args;
          const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
          switch (pos_args) {
            case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
            CYTHON_FALLTHROUGH;
            case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
            CYTHON_FALLTHROUGH;
            case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
            CYTHON_FALLTHROUGH;
            case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
            CYTHON_FALLTHROUGH;
            case  0: break;
            default: goto __pyx_L5_argtuple_error;
          }
          kw_args = PyDict_Size(__pyx_kwds);
          switch (pos_args) {
            case  0:
            if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_vertex_value_indices)) != 0)) kw_args--;
            else goto __pyx_L5_argtuple_error;
            CYTHON_FALLTHROUGH;
            case  1:
            if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_number_of_triangles_per_node)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("average_vertex_values", 1, 4, 4, 1); __PYX_ERR(0, 198, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  2:
            if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_vertex_values)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("average_vertex_values", 1, 4, 4, 2); __PYX_ERR(0, 198, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  3:
            if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("average_vertex_values", 1, 4, 4, 3); __PYX_ERR(0, 198, __pyx_L3_error)
            }
          }
          if (unlikely(kw_args > 0)) {
            if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "average_vertex_values") < 0)) __PYX_ERR(0, 198, __pyx_L3_error)
          }
        } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
          goto __pyx_L5_argtuple_error;
        } else {
          values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
          values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
          values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
          values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        }
        __pyx_v_vertex_value_indices = ((PyArrayObject *)values[0]);
        __pyx_v_number_of_triangles_per_node = ((PyArrayObject *)values[1]);
        __pyx_v_vertex_values = ((PyArrayObject *)values[2]);
        __pyx_v_A = ((PyArrayObject *)values[3]);
      }
      goto __pyx_L4_argument_unpacking_done;
      __pyx_L5_argtuple_error:;
      __Pyx_RaiseArgtupleInvalid("average_vertex_values", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 198, __pyx_L3_error)
      __pyx_L3_error:;
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.average_vertex_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __Pyx_RefNannyFinishContext();
      return NULL;
      __pyx_L4_argument_unpacking_done:;
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertex_value_indices), __pyx_ptype_5numpy_ndarray, 0, "vertex_value_indices", 0))) __PYX_ERR(0, 198, __pyx_L1_error)
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_number_of_triangles_per_node), __pyx_ptype_5numpy_ndarray, 0, "number_of_triangles_per_node", 0))) __PYX_ERR(0, 198, __pyx_L1_error)
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertex_values), __pyx_ptype_5numpy_ndarray, 0, "vertex_values", 0))) __PYX_ERR(0, 198, __pyx_L1_error)
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_A), __pyx_ptype_5numpy_ndarray, 0, "A", 0))) __PYX_ERR(0, 198, __pyx_L1_error)
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_14average_vertex_values(__pyx_self, __pyx_v_vertex_value_indices, __pyx_v_number_of_triangles_per_node, __pyx_v_vertex_values, __pyx_v_A);
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      goto __pyx_L0;
      __pyx_L1_error:;
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_14average_vertex_values(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_vertex_value_indices, PyArrayObject *__pyx_v_number_of_triangles_per_node, PyArrayObject *__pyx_v_vertex_values, PyArrayObject *__pyx_v_A) {
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_A;
      __Pyx_Buffer __pyx_pybuffer_A;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_number_of_triangles_per_node;
      __Pyx_Buffer __pyx_pybuffer_number_of_triangles_per_node;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_value_indices;
      __Pyx_Buffer __pyx_pybuffer_vertex_value_indices;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("average_vertex_values", 0);
      __pyx_pybuffer_vertex_value_indices.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_value_indices.refcount = 0;
      __pyx_pybuffernd_vertex_value_indices.data = NULL;
      __pyx_pybuffernd_vertex_value_indices.rcbuffer = &__pyx_pybuffer_vertex_value_indices;
      __pyx_pybuffer_number_of_triangles_per_node.pybuffer.buf = NULL;
      __pyx_pybuffer_number_of_triangles_per_node.refcount = 0;
      __pyx_pybuffernd_number_of_triangles_per_node.data = NULL;
      __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer = &__pyx_pybuffer_number_of_triangles_per_node;
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_A.pybuffer.buf = NULL;
      __pyx_pybuffer_A.refcount = 0;
      __pyx_pybuffernd_A.data = NULL;
      __pyx_pybuffernd_A.rcbuffer = &__pyx_pybuffer_A;
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_value_indices, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 198, __pyx_L1_error)
      }
      __pyx_pybuffernd_vertex_value_indices.diminfo[0].strides = __pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_value_indices.diminfo[0].shape = __pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer.shape[0];
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer, (PyObject*)__pyx_v_number_of_triangles_per_node, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 198, __pyx_L1_error)
      }
      __pyx_pybuffernd_number_of_triangles_per_node.diminfo[0].strides = __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_number_of_triangles_per_node.diminfo[0].shape = __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer.shape[0];
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 198, __pyx_L1_error)
      }
      __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_A.rcbuffer->pybuffer, (PyObject*)__pyx_v_A, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 198, __pyx_L1_error)
      }
      __pyx_pybuffernd_A.diminfo[0].strides = __pyx_pybuffernd_A.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_A.diminfo[0].shape = __pyx_pybuffernd_A.rcbuffer->pybuffer.shape[0];
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_A.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.average_vertex_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_A.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__17 = PyTuple_Pack(6, __pyx_n_s_vertex_value_indices, __pyx_n_s_number_of_triangles_per_node, __pyx_n_s_vertex_values, __pyx_n_s_A, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(0, 198, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__17);
      __Pyx_GIVEREF(__pyx_tuple__17);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_15average_vertex_values, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 198, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_average_vertex_values, __pyx_t_1) < 0) __PYX_ERR(0, 198, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__18 = (PyObject*)__Pyx_PyCode_New(4, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__17, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_average_vertex_values, 198, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__18)) __PYX_ERR(0, 198, __pyx_L1_error)

     199:

     200:   cdef keyint N

     201:   cdef int err

     202:

    +203:   N = vertex_value_indices.shape[0]

      __pyx_v_N = (__pyx_v_vertex_value_indices->dimensions[0]);

     204:

    +205:   err = _average_vertex_values(N, &vertex_value_indices[0], &number_of_triangles_per_node[0], &vertex_values[0,0], &A[0])

      __pyx_t_1 = 0;
      __pyx_t_2 = 0;
      __pyx_t_3 = 0;
      __pyx_t_4 = 0;
      __pyx_t_5 = 0;
      __pyx_v_err = _average_vertex_values(__pyx_v_N, (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer.buf, __pyx_t_1, __pyx_pybuffernd_vertex_value_indices.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer.buf, __pyx_t_2, __pyx_pybuffernd_number_of_triangles_per_node.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_3, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_4, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_A.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_A.diminfo[0].strides))));

     206:

    +207:   assert err == 0, "average_vertex_values could not be computed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_average_vertex_values_could_not);
          __PYX_ERR(0, 207, __pyx_L1_error)
        }
      }
      #endif

     208:

    +209: def average_centroid_values(np.ndarray[long, ndim=1, mode="c"] vertex_value_indices not None, np.ndarray[long, ndim=1, mode="c"] number_of_triangles_per_node not None, np.ndarray[double, ndim=1, mode="c"] centroid_values not None, np.ndarray[double, ndim=1, mode="c"] A not None):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_17average_centroid_values(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_17average_centroid_values = {"average_centroid_values", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_17average_centroid_values, METH_VARARGS|METH_KEYWORDS, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_17average_centroid_values(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
      PyArrayObject *__pyx_v_vertex_value_indices = 0;
      PyArrayObject *__pyx_v_number_of_triangles_per_node = 0;
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_A = 0;
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("average_centroid_values (wrapper)", 0);
      {
        static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_vertex_value_indices,&__pyx_n_s_number_of_triangles_per_node,&__pyx_n_s_centroid_values,&__pyx_n_s_A,0};
        PyObject* values[4] = {0,0,0,0};
        if (unlikely(__pyx_kwds)) {
          Py_ssize_t kw_args;
          const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
          switch (pos_args) {
            case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
            CYTHON_FALLTHROUGH;
            case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
            CYTHON_FALLTHROUGH;
            case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
            CYTHON_FALLTHROUGH;
            case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
            CYTHON_FALLTHROUGH;
            case  0: break;
            default: goto __pyx_L5_argtuple_error;
          }
          kw_args = PyDict_Size(__pyx_kwds);
          switch (pos_args) {
            case  0:
            if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_vertex_value_indices)) != 0)) kw_args--;
            else goto __pyx_L5_argtuple_error;
            CYTHON_FALLTHROUGH;
            case  1:
            if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_number_of_triangles_per_node)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("average_centroid_values", 1, 4, 4, 1); __PYX_ERR(0, 209, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  2:
            if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_centroid_values)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("average_centroid_values", 1, 4, 4, 2); __PYX_ERR(0, 209, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  3:
            if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("average_centroid_values", 1, 4, 4, 3); __PYX_ERR(0, 209, __pyx_L3_error)
            }
          }
          if (unlikely(kw_args > 0)) {
            if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "average_centroid_values") < 0)) __PYX_ERR(0, 209, __pyx_L3_error)
          }
        } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
          goto __pyx_L5_argtuple_error;
        } else {
          values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
          values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
          values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
          values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        }
        __pyx_v_vertex_value_indices = ((PyArrayObject *)values[0]);
        __pyx_v_number_of_triangles_per_node = ((PyArrayObject *)values[1]);
        __pyx_v_centroid_values = ((PyArrayObject *)values[2]);
        __pyx_v_A = ((PyArrayObject *)values[3]);
      }
      goto __pyx_L4_argument_unpacking_done;
      __pyx_L5_argtuple_error:;
      __Pyx_RaiseArgtupleInvalid("average_centroid_values", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 209, __pyx_L3_error)
      __pyx_L3_error:;
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.average_centroid_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __Pyx_RefNannyFinishContext();
      return NULL;
      __pyx_L4_argument_unpacking_done:;
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertex_value_indices), __pyx_ptype_5numpy_ndarray, 0, "vertex_value_indices", 0))) __PYX_ERR(0, 209, __pyx_L1_error)
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_number_of_triangles_per_node), __pyx_ptype_5numpy_ndarray, 0, "number_of_triangles_per_node", 0))) __PYX_ERR(0, 209, __pyx_L1_error)
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_centroid_values), __pyx_ptype_5numpy_ndarray, 0, "centroid_values", 0))) __PYX_ERR(0, 209, __pyx_L1_error)
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_A), __pyx_ptype_5numpy_ndarray, 0, "A", 0))) __PYX_ERR(0, 209, __pyx_L1_error)
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_16average_centroid_values(__pyx_self, __pyx_v_vertex_value_indices, __pyx_v_number_of_triangles_per_node, __pyx_v_centroid_values, __pyx_v_A);
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      goto __pyx_L0;
      __pyx_L1_error:;
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_16average_centroid_values(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_vertex_value_indices, PyArrayObject *__pyx_v_number_of_triangles_per_node, PyArrayObject *__pyx_v_centroid_values, PyArrayObject *__pyx_v_A) {
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_A;
      __Pyx_Buffer __pyx_pybuffer_A;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_number_of_triangles_per_node;
      __Pyx_Buffer __pyx_pybuffer_number_of_triangles_per_node;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_value_indices;
      __Pyx_Buffer __pyx_pybuffer_vertex_value_indices;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("average_centroid_values", 0);
      __pyx_pybuffer_vertex_value_indices.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_value_indices.refcount = 0;
      __pyx_pybuffernd_vertex_value_indices.data = NULL;
      __pyx_pybuffernd_vertex_value_indices.rcbuffer = &__pyx_pybuffer_vertex_value_indices;
      __pyx_pybuffer_number_of_triangles_per_node.pybuffer.buf = NULL;
      __pyx_pybuffer_number_of_triangles_per_node.refcount = 0;
      __pyx_pybuffernd_number_of_triangles_per_node.data = NULL;
      __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer = &__pyx_pybuffer_number_of_triangles_per_node;
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_A.pybuffer.buf = NULL;
      __pyx_pybuffer_A.refcount = 0;
      __pyx_pybuffernd_A.data = NULL;
      __pyx_pybuffernd_A.rcbuffer = &__pyx_pybuffer_A;
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_value_indices, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 209, __pyx_L1_error)
      }
      __pyx_pybuffernd_vertex_value_indices.diminfo[0].strides = __pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_value_indices.diminfo[0].shape = __pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer.shape[0];
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer, (PyObject*)__pyx_v_number_of_triangles_per_node, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 209, __pyx_L1_error)
      }
      __pyx_pybuffernd_number_of_triangles_per_node.diminfo[0].strides = __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_number_of_triangles_per_node.diminfo[0].shape = __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer.shape[0];
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 209, __pyx_L1_error)
      }
      __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_A.rcbuffer->pybuffer, (PyObject*)__pyx_v_A, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 209, __pyx_L1_error)
      }
      __pyx_pybuffernd_A.diminfo[0].strides = __pyx_pybuffernd_A.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_A.diminfo[0].shape = __pyx_pybuffernd_A.rcbuffer->pybuffer.shape[0];
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_A.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.average_centroid_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_A.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__19 = PyTuple_Pack(6, __pyx_n_s_vertex_value_indices, __pyx_n_s_number_of_triangles_per_node, __pyx_n_s_centroid_values, __pyx_n_s_A, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 209, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__19);
      __Pyx_GIVEREF(__pyx_tuple__19);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_17average_centroid_values, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 209, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_average_centroid_values, __pyx_t_1) < 0) __PYX_ERR(0, 209, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__20 = (PyObject*)__Pyx_PyCode_New(4, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__19, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_average_centroid_values, 209, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__20)) __PYX_ERR(0, 209, __pyx_L1_error)

     210:

     211:   cdef keyint N

     212:   cdef int err

     213:

    +214:   N = vertex_value_indices.shape[0]

      __pyx_v_N = (__pyx_v_vertex_value_indices->dimensions[0]);

     215:

    +216:   err = _average_centroid_values(N, &vertex_value_indices[0], &number_of_triangles_per_node[0], &centroid_values[0], &A[0])

      __pyx_t_1 = 0;
      __pyx_t_2 = 0;
      __pyx_t_3 = 0;
      __pyx_t_4 = 0;
      __pyx_v_err = _average_centroid_values(__pyx_v_N, (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_vertex_value_indices.rcbuffer->pybuffer.buf, __pyx_t_1, __pyx_pybuffernd_vertex_value_indices.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_number_of_triangles_per_node.rcbuffer->pybuffer.buf, __pyx_t_2, __pyx_pybuffernd_number_of_triangles_per_node.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_3, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_A.rcbuffer->pybuffer.buf, __pyx_t_4, __pyx_pybuffernd_A.diminfo[0].strides))));

     217:

    +218:   assert err == 0, "average_centroid_values could not be computed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_average_centroid_values_could_no);
          __PYX_ERR(0, 218, __pyx_L1_error)
        }
      }
      #endif

     219:

    +220: def extrapolate_from_gradient(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_19extrapolate_from_gradient(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_19extrapolate_from_gradient = {"extrapolate_from_gradient", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_19extrapolate_from_gradient, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_19extrapolate_from_gradient(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("extrapolate_from_gradient (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_18extrapolate_from_gradient(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_18extrapolate_from_gradient(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_centroids = 0;
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_vertex_coordinates = 0;
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_edge_values = 0;
      CYTHON_UNUSED PyArrayObject *__pyx_v_number_of_boundaries = 0;
      CYTHON_UNUSED PyArrayObject *__pyx_v_surrogate_neighbours = 0;
      PyArrayObject *__pyx_v_x_gradient = 0;
      PyArrayObject *__pyx_v_y_gradient = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroids;
      __Pyx_Buffer __pyx_pybuffer_centroids;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_number_of_boundaries;
      __Pyx_Buffer __pyx_pybuffer_number_of_boundaries;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_surrogate_neighbours;
      __Pyx_Buffer __pyx_pybuffer_surrogate_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_coordinates;
      __Pyx_Buffer __pyx_pybuffer_vertex_coordinates;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_x_gradient;
      __Pyx_Buffer __pyx_pybuffer_x_gradient;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_y_gradient;
      __Pyx_Buffer __pyx_pybuffer_y_gradient;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("extrapolate_from_gradient", 0);
      __pyx_pybuffer_centroids.pybuffer.buf = NULL;
      __pyx_pybuffer_centroids.refcount = 0;
      __pyx_pybuffernd_centroids.data = NULL;
      __pyx_pybuffernd_centroids.rcbuffer = &__pyx_pybuffer_centroids;
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_vertex_coordinates.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_coordinates.refcount = 0;
      __pyx_pybuffernd_vertex_coordinates.data = NULL;
      __pyx_pybuffernd_vertex_coordinates.rcbuffer = &__pyx_pybuffer_vertex_coordinates;
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
      __pyx_pybuffer_number_of_boundaries.pybuffer.buf = NULL;
      __pyx_pybuffer_number_of_boundaries.refcount = 0;
      __pyx_pybuffernd_number_of_boundaries.data = NULL;
      __pyx_pybuffernd_number_of_boundaries.rcbuffer = &__pyx_pybuffer_number_of_boundaries;
      __pyx_pybuffer_surrogate_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_surrogate_neighbours.refcount = 0;
      __pyx_pybuffernd_surrogate_neighbours.data = NULL;
      __pyx_pybuffernd_surrogate_neighbours.rcbuffer = &__pyx_pybuffer_surrogate_neighbours;
      __pyx_pybuffer_x_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_x_gradient.refcount = 0;
      __pyx_pybuffernd_x_gradient.data = NULL;
      __pyx_pybuffernd_x_gradient.rcbuffer = &__pyx_pybuffer_x_gradient;
      __pyx_pybuffer_y_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_y_gradient.refcount = 0;
      __pyx_pybuffernd_y_gradient.data = NULL;
      __pyx_pybuffernd_y_gradient.rcbuffer = &__pyx_pybuffer_y_gradient;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroids.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.extrapolate_from_gradient", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroids.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroids);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_coordinates);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_number_of_boundaries);
      __Pyx_XDECREF((PyObject *)__pyx_v_surrogate_neighbours);
      __Pyx_XDECREF((PyObject *)__pyx_v_x_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_y_gradient);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__21 = PyTuple_Pack(13, __pyx_n_s_quantity, __pyx_n_s_domain, __pyx_n_s_centroids, __pyx_n_s_centroid_values, __pyx_n_s_vertex_coordinates, __pyx_n_s_vertex_values, __pyx_n_s_edge_values, __pyx_n_s_number_of_boundaries, __pyx_n_s_surrogate_neighbours, __pyx_n_s_x_gradient, __pyx_n_s_y_gradient, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 220, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__21);
      __Pyx_GIVEREF(__pyx_tuple__21);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_19extrapolate_from_gradient, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 220, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_extrapolate_from_gradient, __pyx_t_1) < 0) __PYX_ERR(0, 220, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__22 = (PyObject*)__Pyx_PyCode_New(1, 0, 13, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__21, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_extrapolate_from_gradient, 220, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__22)) __PYX_ERR(0, 220, __pyx_L1_error)

     221:

     222:   cdef object domain

     223:

     224:   cdef np.ndarray[double, ndim=2, mode="c"] centroids

     225:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     226:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_coordinates

     227:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     228:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     229:   cdef np.ndarray[long, ndim=1, mode="c"] number_of_boundaries

     230:   cdef np.ndarray[long, ndim=2, mode="c"] surrogate_neighbours

     231:   cdef np.ndarray[double, ndim=1, mode="c"] x_gradient

     232:   cdef np.ndarray[double, ndim=1, mode="c"] y_gradient

     233:

     234:   cdef keyint N

     235:   cdef int err

     236:

    +237:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 237, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     238:

    +239:   centroids = domain.centroid_coordinates

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_centroid_coordinates); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 239, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroids.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroids.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroids.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroids, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_centroids.diminfo[0].strides = __pyx_pybuffernd_centroids.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroids.diminfo[0].shape = __pyx_pybuffernd_centroids.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_centroids.diminfo[1].strides = __pyx_pybuffernd_centroids.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_centroids.diminfo[1].shape = __pyx_pybuffernd_centroids.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 239, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_centroids = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +240:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 240, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 240, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 240, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +241:   surrogate_neighbours = domain.surrogate_neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_surrogate_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 241, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 241, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_surrogate_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_surrogate_neighbours.diminfo[0].strides = __pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_surrogate_neighbours.diminfo[0].shape = __pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_surrogate_neighbours.diminfo[1].strides = __pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_surrogate_neighbours.diminfo[1].shape = __pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 241, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_surrogate_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +242:   number_of_boundaries = domain.number_of_boundaries

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_number_of_boundaries); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 242, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 242, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer, (PyObject*)__pyx_v_number_of_boundaries, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_number_of_boundaries.diminfo[0].strides = __pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_number_of_boundaries.diminfo[0].shape = __pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 242, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_number_of_boundaries = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +243:   vertex_coordinates = domain.vertex_coordinates

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_vertex_coordinates); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 243, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 243, __pyx_L1_error)
      __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_coordinates, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_vertex_coordinates.diminfo[0].strides = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_coordinates.diminfo[0].shape = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_coordinates.diminfo[1].strides = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_coordinates.diminfo[1].shape = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 243, __pyx_L1_error)
      }
      __pyx_t_10 = 0;
      __pyx_v_vertex_coordinates = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +244:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 244, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 244, __pyx_L1_error)
      __pyx_t_11 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 244, __pyx_L1_error)
      }
      __pyx_t_11 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +245:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 245, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 245, __pyx_L1_error)
      __pyx_t_12 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 245, __pyx_L1_error)
      }
      __pyx_t_12 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +246:   x_gradient = quantity.x_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_x_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 246, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 246, __pyx_L1_error)
      __pyx_t_13 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_13, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_x_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_x_gradient.diminfo[0].strides = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x_gradient.diminfo[0].shape = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 246, __pyx_L1_error)
      }
      __pyx_t_13 = 0;
      __pyx_v_x_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +247:   y_gradient = quantity.y_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_y_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 247, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 247, __pyx_L1_error)
      __pyx_t_14 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_14, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_y_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_y_gradient.diminfo[0].strides = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y_gradient.diminfo[0].shape = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 247, __pyx_L1_error)
      }
      __pyx_t_14 = 0;
      __pyx_v_y_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     248:

    +249:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     250:

    +251:   err = _extrapolate_from_gradient(N,\

      __pyx_v_err = _extrapolate_from_gradient(__pyx_v_N, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_centroids.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_centroids.diminfo[0].strides, __pyx_t_16, __pyx_pybuffernd_centroids.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_vertex_coordinates.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_vertex_coordinates.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_21, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_edge_values.diminfo[0].strides, __pyx_t_23, __pyx_pybuffernd_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_24, __pyx_pybuffernd_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_25, __pyx_pybuffernd_y_gradient.diminfo[0].strides))));

    +252: 							&centroids[0,0],\

      __pyx_t_15 = 0;
      __pyx_t_16 = 0;

    +253: 							&centroid_values[0],\

      __pyx_t_17 = 0;

    +254: 							&vertex_coordinates[0,0],\

      __pyx_t_18 = 0;
      __pyx_t_19 = 0;

    +255: 							&vertex_values[0,0],\

      __pyx_t_20 = 0;
      __pyx_t_21 = 0;

    +256: 							&edge_values[0,0],\

      __pyx_t_22 = 0;
      __pyx_t_23 = 0;

    +257: 							&x_gradient[0],\

      __pyx_t_24 = 0;

    +258: 							&y_gradient[0])

      __pyx_t_25 = 0;

     259:

    +260:   assert err == 0, "Internal function _extrapolate failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__extrapolate_f);
          __PYX_ERR(0, 260, __pyx_L1_error)
        }
      }
      #endif

     261:

    +262: def compute_local_gradients(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_21compute_local_gradients(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_21compute_local_gradients = {"compute_local_gradients", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_21compute_local_gradients, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_21compute_local_gradients(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("compute_local_gradients (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_20compute_local_gradients(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_20compute_local_gradients(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_vertex_coordinates = 0;
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_x_gradient = 0;
      PyArrayObject *__pyx_v_y_gradient = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_coordinates;
      __Pyx_Buffer __pyx_pybuffer_vertex_coordinates;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_x_gradient;
      __Pyx_Buffer __pyx_pybuffer_x_gradient;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_y_gradient;
      __Pyx_Buffer __pyx_pybuffer_y_gradient;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("compute_local_gradients", 0);
      __pyx_pybuffer_vertex_coordinates.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_coordinates.refcount = 0;
      __pyx_pybuffernd_vertex_coordinates.data = NULL;
      __pyx_pybuffernd_vertex_coordinates.rcbuffer = &__pyx_pybuffer_vertex_coordinates;
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_x_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_x_gradient.refcount = 0;
      __pyx_pybuffernd_x_gradient.data = NULL;
      __pyx_pybuffernd_x_gradient.rcbuffer = &__pyx_pybuffer_x_gradient;
      __pyx_pybuffer_y_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_y_gradient.refcount = 0;
      __pyx_pybuffernd_y_gradient.data = NULL;
      __pyx_pybuffernd_y_gradient.rcbuffer = &__pyx_pybuffer_y_gradient;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.compute_local_gradients", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_coordinates);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_x_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_y_gradient);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__23 = PyTuple_Pack(8, __pyx_n_s_quantity, __pyx_n_s_domain, __pyx_n_s_vertex_coordinates, __pyx_n_s_vertex_values, __pyx_n_s_x_gradient, __pyx_n_s_y_gradient, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 262, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__23);
      __Pyx_GIVEREF(__pyx_tuple__23);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_21compute_local_gradients, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 262, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_compute_local_gradients, __pyx_t_1) < 0) __PYX_ERR(0, 262, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_compute_local_gradients, 262, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 262, __pyx_L1_error)

     263:

     264:   cdef object domain

     265:

     266:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_coordinates

     267:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     268:   cdef np.ndarray[double, ndim=1, mode="c"] x_gradient

     269:   cdef np.ndarray[double, ndim=1, mode="c"] y_gradient

     270:

     271:   cdef keyint N

     272:   cdef int err

     273:

    +274:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 274, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     275:

    +276:   vertex_coordinates = domain.vertex_coordinates

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_vertex_coordinates); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 276, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 276, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_coordinates, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_vertex_coordinates.diminfo[0].strides = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_coordinates.diminfo[0].shape = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_coordinates.diminfo[1].strides = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_coordinates.diminfo[1].shape = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 276, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_vertex_coordinates = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +277:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 277, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 277, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 277, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +278:   x_gradient = quantity.x_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_x_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 278, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 278, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_x_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_x_gradient.diminfo[0].strides = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x_gradient.diminfo[0].shape = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 278, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_x_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +279:   y_gradient = quantity.y_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_y_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 279, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 279, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_y_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_y_gradient.diminfo[0].strides = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y_gradient.diminfo[0].shape = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 279, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_y_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     280:

    +281:   N = vertex_values.shape[0]

      __pyx_v_N = (__pyx_v_vertex_values->dimensions[0]);

     282:

    +283:   err = _compute_local_gradients(N, &vertex_coordinates[0,0], &vertex_values[0,0], &x_gradient[0], &y_gradient[0])

      __pyx_t_10 = 0;
      __pyx_t_11 = 0;
      __pyx_t_12 = 0;
      __pyx_t_13 = 0;
      __pyx_t_14 = 0;
      __pyx_t_15 = 0;
      __pyx_v_err = _compute_local_gradients(__pyx_v_N, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_vertex_coordinates.diminfo[0].strides, __pyx_t_11, __pyx_pybuffernd_vertex_coordinates.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_13, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_y_gradient.diminfo[0].strides))));

     284:

    +285:   assert err == 0, "Internal function _compute_local_gradient failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__compute_local);
          __PYX_ERR(0, 285, __pyx_L1_error)
        }
      }
      #endif

     286:

    +287: def extrapolate_second_order_and_limit_by_edge(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_23extrapolate_second_order_and_limit_by_edge(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_23extrapolate_second_order_and_limit_by_edge = {"extrapolate_second_order_and_limit_by_edge", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_23extrapolate_second_order_and_limit_by_edge, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_23extrapolate_second_order_and_limit_by_edge(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("extrapolate_second_order_and_limit_by_edge (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_22extrapolate_second_order_and_limit_by_edge(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_22extrapolate_second_order_and_limit_by_edge(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_domain_centroids = 0;
      PyArrayObject *__pyx_v_domain_vertex_coordinates = 0;
      PyArrayObject *__pyx_v_domain_number_of_boundaries = 0;
      PyArrayObject *__pyx_v_domain_surrogate_neighbours = 0;
      PyArrayObject *__pyx_v_domain_neighbours = 0;
      PyArrayObject *__pyx_v_quantity_centroid_values = 0;
      PyArrayObject *__pyx_v_quantity_vertex_values = 0;
      PyArrayObject *__pyx_v_quantity_edge_values = 0;
      CYTHON_UNUSED PyArrayObject *__pyx_v_quantity_phi = 0;
      PyArrayObject *__pyx_v_quantity_x_gradient = 0;
      PyArrayObject *__pyx_v_quantity_y_gradient = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_ntri;
      double __pyx_v_beta;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_domain_centroids;
      __Pyx_Buffer __pyx_pybuffer_domain_centroids;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_domain_neighbours;
      __Pyx_Buffer __pyx_pybuffer_domain_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_domain_number_of_boundaries;
      __Pyx_Buffer __pyx_pybuffer_domain_number_of_boundaries;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_domain_surrogate_neighbours;
      __Pyx_Buffer __pyx_pybuffer_domain_surrogate_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_domain_vertex_coordinates;
      __Pyx_Buffer __pyx_pybuffer_domain_vertex_coordinates;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_quantity_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_edge_values;
      __Pyx_Buffer __pyx_pybuffer_quantity_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_phi;
      __Pyx_Buffer __pyx_pybuffer_quantity_phi;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_quantity_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_x_gradient;
      __Pyx_Buffer __pyx_pybuffer_quantity_x_gradient;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_y_gradient;
      __Pyx_Buffer __pyx_pybuffer_quantity_y_gradient;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("extrapolate_second_order_and_limit_by_edge", 0);
      __pyx_pybuffer_domain_centroids.pybuffer.buf = NULL;
      __pyx_pybuffer_domain_centroids.refcount = 0;
      __pyx_pybuffernd_domain_centroids.data = NULL;
      __pyx_pybuffernd_domain_centroids.rcbuffer = &__pyx_pybuffer_domain_centroids;
      __pyx_pybuffer_domain_vertex_coordinates.pybuffer.buf = NULL;
      __pyx_pybuffer_domain_vertex_coordinates.refcount = 0;
      __pyx_pybuffernd_domain_vertex_coordinates.data = NULL;
      __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer = &__pyx_pybuffer_domain_vertex_coordinates;
      __pyx_pybuffer_domain_number_of_boundaries.pybuffer.buf = NULL;
      __pyx_pybuffer_domain_number_of_boundaries.refcount = 0;
      __pyx_pybuffernd_domain_number_of_boundaries.data = NULL;
      __pyx_pybuffernd_domain_number_of_boundaries.rcbuffer = &__pyx_pybuffer_domain_number_of_boundaries;
      __pyx_pybuffer_domain_surrogate_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_domain_surrogate_neighbours.refcount = 0;
      __pyx_pybuffernd_domain_surrogate_neighbours.data = NULL;
      __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer = &__pyx_pybuffer_domain_surrogate_neighbours;
      __pyx_pybuffer_domain_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_domain_neighbours.refcount = 0;
      __pyx_pybuffernd_domain_neighbours.data = NULL;
      __pyx_pybuffernd_domain_neighbours.rcbuffer = &__pyx_pybuffer_domain_neighbours;
      __pyx_pybuffer_quantity_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_centroid_values.refcount = 0;
      __pyx_pybuffernd_quantity_centroid_values.data = NULL;
      __pyx_pybuffernd_quantity_centroid_values.rcbuffer = &__pyx_pybuffer_quantity_centroid_values;
      __pyx_pybuffer_quantity_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_vertex_values.refcount = 0;
      __pyx_pybuffernd_quantity_vertex_values.data = NULL;
      __pyx_pybuffernd_quantity_vertex_values.rcbuffer = &__pyx_pybuffer_quantity_vertex_values;
      __pyx_pybuffer_quantity_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_edge_values.refcount = 0;
      __pyx_pybuffernd_quantity_edge_values.data = NULL;
      __pyx_pybuffernd_quantity_edge_values.rcbuffer = &__pyx_pybuffer_quantity_edge_values;
      __pyx_pybuffer_quantity_phi.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_phi.refcount = 0;
      __pyx_pybuffernd_quantity_phi.data = NULL;
      __pyx_pybuffernd_quantity_phi.rcbuffer = &__pyx_pybuffer_quantity_phi;
      __pyx_pybuffer_quantity_x_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_x_gradient.refcount = 0;
      __pyx_pybuffernd_quantity_x_gradient.data = NULL;
      __pyx_pybuffernd_quantity_x_gradient.rcbuffer = &__pyx_pybuffer_quantity_x_gradient;
      __pyx_pybuffer_quantity_y_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_y_gradient.refcount = 0;
      __pyx_pybuffernd_quantity_y_gradient.data = NULL;
      __pyx_pybuffernd_quantity_y_gradient.rcbuffer = &__pyx_pybuffer_quantity_y_gradient;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.extrapolate_second_order_and_limit_by_edge", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_domain_centroids);
      __Pyx_XDECREF((PyObject *)__pyx_v_domain_vertex_coordinates);
      __Pyx_XDECREF((PyObject *)__pyx_v_domain_number_of_boundaries);
      __Pyx_XDECREF((PyObject *)__pyx_v_domain_surrogate_neighbours);
      __Pyx_XDECREF((PyObject *)__pyx_v_domain_neighbours);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_phi);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_x_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_y_gradient);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__25 = PyTuple_Pack(16, __pyx_n_s_quantity, __pyx_n_s_domain, __pyx_n_s_domain_centroids, __pyx_n_s_domain_vertex_coordinates, __pyx_n_s_domain_number_of_boundaries, __pyx_n_s_domain_surrogate_neighbours, __pyx_n_s_domain_neighbours, __pyx_n_s_quantity_centroid_values, __pyx_n_s_quantity_vertex_values, __pyx_n_s_quantity_edge_values, __pyx_n_s_quantity_phi, __pyx_n_s_quantity_x_gradient, __pyx_n_s_quantity_y_gradient, __pyx_n_s_ntri, __pyx_n_s_beta, __pyx_n_s_err); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 287, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__25);
      __Pyx_GIVEREF(__pyx_tuple__25);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_23extrapolate_second_order_and_limit_by_edge, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 287, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_extrapolate_second_order_and_lim, __pyx_t_1) < 0) __PYX_ERR(0, 287, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(1, 0, 16, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_extrapolate_second_order_and_lim, 287, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) __PYX_ERR(0, 287, __pyx_L1_error)

     288:

     289:   cdef object domain

     290:

     291:   cdef np.ndarray[double, ndim=2, mode="c"] domain_centroids

     292:   cdef np.ndarray[double, ndim=2, mode="c"] domain_vertex_coordinates

     293:   cdef np.ndarray[long, ndim=1, mode="c"] domain_number_of_boundaries

     294:   cdef np.ndarray[long, ndim=2, mode="c"] domain_surrogate_neighbours

     295:   cdef np.ndarray[long, ndim=2, mode="c"] domain_neighbours

     296:

     297:   cdef np.ndarray[double, ndim=1, mode="c"] quantity_centroid_values

     298:   cdef np.ndarray[double, ndim=2, mode="c"] quantity_vertex_values

     299:   cdef np.ndarray[double, ndim=2, mode="c"] quantity_edge_values

     300:   cdef np.ndarray[double, ndim=1, mode="c"] quantity_phi

     301:   cdef np.ndarray[double, ndim=1, mode="c"] quantity_x_gradient

     302:   cdef np.ndarray[double, ndim=1, mode="c"] quantity_y_gradient

     303:

     304:   cdef keyint ntri

     305:   cdef double beta

     306:   cdef int err

     307:

    +308:   domain = quantity.object

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_object); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 308, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     309:

    +310:   domain_centroids = domain.centroid_coordinates

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_centroid_coordinates); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 310, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 310, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer, (PyObject*)__pyx_v_domain_centroids, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_domain_centroids.diminfo[0].strides = __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_domain_centroids.diminfo[0].shape = __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_domain_centroids.diminfo[1].strides = __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_domain_centroids.diminfo[1].shape = __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 310, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_domain_centroids = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +311:   domain_surrogate_neighbours = domain.surrogate_neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_surrogate_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 311, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 311, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_domain_surrogate_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[0].strides = __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[0].shape = __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[1].strides = __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[1].shape = __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 311, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_domain_surrogate_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +312:   domain_number_of_boundaries = domain.number_of_boundaries

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_number_of_boundaries); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 312, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 312, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer, (PyObject*)__pyx_v_domain_number_of_boundaries, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_domain_number_of_boundaries.diminfo[0].strides = __pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_domain_number_of_boundaries.diminfo[0].shape = __pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 312, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_domain_number_of_boundaries = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +313:   domain_vertex_coordinates = domain.vertex_coordinates

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_vertex_coordinates); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 313, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 313, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer, (PyObject*)__pyx_v_domain_vertex_coordinates, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_domain_vertex_coordinates.diminfo[0].strides = __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_domain_vertex_coordinates.diminfo[0].shape = __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_domain_vertex_coordinates.diminfo[1].strides = __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_domain_vertex_coordinates.diminfo[1].shape = __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 313, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_domain_vertex_coordinates = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +314:   domain_neighbours = domain.neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 314, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 314, __pyx_L1_error)
      __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_domain_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_domain_neighbours.diminfo[0].strides = __pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_domain_neighbours.diminfo[0].shape = __pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_domain_neighbours.diminfo[1].strides = __pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_domain_neighbours.diminfo[1].shape = __pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 314, __pyx_L1_error)
      }
      __pyx_t_10 = 0;
      __pyx_v_domain_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     315:

    +316:   quantity_centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 316, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 316, __pyx_L1_error)
      __pyx_t_11 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_quantity_centroid_values.diminfo[0].strides = __pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_centroid_values.diminfo[0].shape = __pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 316, __pyx_L1_error)
      }
      __pyx_t_11 = 0;
      __pyx_v_quantity_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +317:   quantity_vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 317, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 317, __pyx_L1_error)
      __pyx_t_12 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_quantity_vertex_values.diminfo[0].strides = __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_vertex_values.diminfo[0].shape = __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_quantity_vertex_values.diminfo[1].strides = __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_quantity_vertex_values.diminfo[1].shape = __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 317, __pyx_L1_error)
      }
      __pyx_t_12 = 0;
      __pyx_v_quantity_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +318:   quantity_edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 318, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 318, __pyx_L1_error)
      __pyx_t_13 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_13, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_quantity_edge_values.diminfo[0].strides = __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_edge_values.diminfo[0].shape = __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_quantity_edge_values.diminfo[1].strides = __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_quantity_edge_values.diminfo[1].shape = __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 318, __pyx_L1_error)
      }
      __pyx_t_13 = 0;
      __pyx_v_quantity_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +319:   quantity_phi = quantity.phi

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_phi); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 319, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 319, __pyx_L1_error)
      __pyx_t_14 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer, (PyObject*)__pyx_t_14, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_phi, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_quantity_phi.diminfo[0].strides = __pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_phi.diminfo[0].shape = __pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 319, __pyx_L1_error)
      }
      __pyx_t_14 = 0;
      __pyx_v_quantity_phi = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +320:   quantity_x_gradient = quantity.x_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_x_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 320, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 320, __pyx_L1_error)
      __pyx_t_15 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_15, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_x_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_quantity_x_gradient.diminfo[0].strides = __pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_x_gradient.diminfo[0].shape = __pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 320, __pyx_L1_error)
      }
      __pyx_t_15 = 0;
      __pyx_v_quantity_x_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +321:   quantity_y_gradient = quantity.y_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_y_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 321, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 321, __pyx_L1_error)
      __pyx_t_16 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_16, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_y_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_quantity_y_gradient.diminfo[0].strides = __pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_y_gradient.diminfo[0].shape = __pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 321, __pyx_L1_error)
      }
      __pyx_t_16 = 0;
      __pyx_v_quantity_y_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     322:

    +323:   beta = quantity.beta

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_beta); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 323, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_17 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_17 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 323, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_beta = __pyx_t_17;

     324:

    +325:   ntri = quantity_centroid_values.shape[0]

      __pyx_v_ntri = (__pyx_v_quantity_centroid_values->dimensions[0]);

     326:

    +327:   err = _compute_gradients(ntri,\

      __pyx_v_err = _compute_gradients(__pyx_v_ntri, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_domain_centroids.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_domain_centroids.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_quantity_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_domain_number_of_boundaries.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(long *, __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[0].strides, __pyx_t_23, __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_24, __pyx_pybuffernd_quantity_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_25, __pyx_pybuffernd_quantity_y_gradient.diminfo[0].strides))));

    +328: 						&domain_centroids[0,0],\

      __pyx_t_18 = 0;
      __pyx_t_19 = 0;

    +329: 						&quantity_centroid_values[0],\

      __pyx_t_20 = 0;

    +330: 						&domain_number_of_boundaries[0],\

      __pyx_t_21 = 0;

    +331: 						&domain_surrogate_neighbours[0,0],\

      __pyx_t_22 = 0;
      __pyx_t_23 = 0;

    +332: 						&quantity_x_gradient[0],\

      __pyx_t_24 = 0;

    +333: 						&quantity_y_gradient[0])

      __pyx_t_25 = 0;

     334:

    +335:   assert err == 0, "Internal function _compute_gradient failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__compute_gradi);
          __PYX_ERR(0, 335, __pyx_L1_error)
        }
      }
      #endif

     336:

    +337:   err = _extrapolate_from_gradient(ntri,\

      __pyx_v_err = _extrapolate_from_gradient(__pyx_v_ntri, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.buf, __pyx_t_25, __pyx_pybuffernd_domain_centroids.diminfo[0].strides, __pyx_t_24, __pyx_pybuffernd_domain_centroids.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_23, __pyx_pybuffernd_quantity_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_domain_vertex_coordinates.diminfo[0].strides, __pyx_t_21, __pyx_pybuffernd_domain_vertex_coordinates.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_quantity_vertex_values.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_quantity_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_quantity_edge_values.diminfo[0].strides, __pyx_t_26, __pyx_pybuffernd_quantity_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_27, __pyx_pybuffernd_quantity_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_28, __pyx_pybuffernd_quantity_y_gradient.diminfo[0].strides))));

    +338: 						&domain_centroids[0,0],\

      __pyx_t_25 = 0;
      __pyx_t_24 = 0;

    +339: 						&quantity_centroid_values[0],\

      __pyx_t_23 = 0;

    +340: 						&domain_vertex_coordinates[0,0],\

      __pyx_t_22 = 0;
      __pyx_t_21 = 0;

    +341: 						&quantity_vertex_values[0,0],\

      __pyx_t_20 = 0;
      __pyx_t_19 = 0;

    +342: 						&quantity_edge_values[0,0],\

      __pyx_t_18 = 0;
      __pyx_t_26 = 0;

    +343: 						&quantity_x_gradient[0],\

      __pyx_t_27 = 0;

    +344: 						&quantity_y_gradient[0])

      __pyx_t_28 = 0;

     345:

    +346:   assert err == 0, "Internal function _extrapolate_from_gradient failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__extrapolate_f_2);
          __PYX_ERR(0, 346, __pyx_L1_error)
        }
      }
      #endif

     347:

    +348:   err = _limit_edges_by_all_neighbours(ntri, beta,\

      __pyx_v_err = _limit_edges_by_all_neighbours(__pyx_v_ntri, __pyx_v_beta, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_28, __pyx_pybuffernd_quantity_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_27, __pyx_pybuffernd_quantity_vertex_values.diminfo[0].strides, __pyx_t_26, __pyx_pybuffernd_quantity_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_quantity_edge_values.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_quantity_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(long *, __pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_domain_neighbours.diminfo[0].strides, __pyx_t_21, __pyx_pybuffernd_domain_neighbours.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_quantity_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_23, __pyx_pybuffernd_quantity_y_gradient.diminfo[0].strides))));

    +349: 						&quantity_centroid_values[0],\

      __pyx_t_28 = 0;

    +350: 						&quantity_vertex_values[0,0],\

      __pyx_t_27 = 0;
      __pyx_t_26 = 0;

    +351: 						&quantity_edge_values[0,0],\

      __pyx_t_18 = 0;
      __pyx_t_19 = 0;

    +352: 						&domain_neighbours[0,0],\

      __pyx_t_20 = 0;
      __pyx_t_21 = 0;

    +353: 						&quantity_x_gradient[0],\

      __pyx_t_22 = 0;

    +354: 						&quantity_y_gradient[0])

      __pyx_t_23 = 0;

     355:

    +356:   assert err == 0, "Internal function _limit_edges_by_all_neighbours failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__limit_edges_b);
          __PYX_ERR(0, 356, __pyx_L1_error)
        }
      }
      #endif

     357:

    +358: def extrapolate_second_order_and_limit_by_vertex(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_25extrapolate_second_order_and_limit_by_vertex(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_25extrapolate_second_order_and_limit_by_vertex = {"extrapolate_second_order_and_limit_by_vertex", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_25extrapolate_second_order_and_limit_by_vertex, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_25extrapolate_second_order_and_limit_by_vertex(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("extrapolate_second_order_and_limit_by_vertex (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_24extrapolate_second_order_and_limit_by_vertex(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_24extrapolate_second_order_and_limit_by_vertex(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_domain_centroids = 0;
      PyArrayObject *__pyx_v_domain_vertex_coordinates = 0;
      PyArrayObject *__pyx_v_domain_number_of_boundaries = 0;
      PyArrayObject *__pyx_v_domain_surrogate_neighbours = 0;
      PyArrayObject *__pyx_v_domain_neighbours = 0;
      PyArrayObject *__pyx_v_quantity_centroid_values = 0;
      PyArrayObject *__pyx_v_quantity_vertex_values = 0;
      PyArrayObject *__pyx_v_quantity_edge_values = 0;
      CYTHON_UNUSED PyArrayObject *__pyx_v_quantity_phi = 0;
      PyArrayObject *__pyx_v_quantity_x_gradient = 0;
      PyArrayObject *__pyx_v_quantity_y_gradient = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_ntri;
      double __pyx_v_beta;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_domain_centroids;
      __Pyx_Buffer __pyx_pybuffer_domain_centroids;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_domain_neighbours;
      __Pyx_Buffer __pyx_pybuffer_domain_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_domain_number_of_boundaries;
      __Pyx_Buffer __pyx_pybuffer_domain_number_of_boundaries;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_domain_surrogate_neighbours;
      __Pyx_Buffer __pyx_pybuffer_domain_surrogate_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_domain_vertex_coordinates;
      __Pyx_Buffer __pyx_pybuffer_domain_vertex_coordinates;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_quantity_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_edge_values;
      __Pyx_Buffer __pyx_pybuffer_quantity_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_phi;
      __Pyx_Buffer __pyx_pybuffer_quantity_phi;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_quantity_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_x_gradient;
      __Pyx_Buffer __pyx_pybuffer_quantity_x_gradient;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_quantity_y_gradient;
      __Pyx_Buffer __pyx_pybuffer_quantity_y_gradient;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("extrapolate_second_order_and_limit_by_vertex", 0);
      __pyx_pybuffer_domain_centroids.pybuffer.buf = NULL;
      __pyx_pybuffer_domain_centroids.refcount = 0;
      __pyx_pybuffernd_domain_centroids.data = NULL;
      __pyx_pybuffernd_domain_centroids.rcbuffer = &__pyx_pybuffer_domain_centroids;
      __pyx_pybuffer_domain_vertex_coordinates.pybuffer.buf = NULL;
      __pyx_pybuffer_domain_vertex_coordinates.refcount = 0;
      __pyx_pybuffernd_domain_vertex_coordinates.data = NULL;
      __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer = &__pyx_pybuffer_domain_vertex_coordinates;
      __pyx_pybuffer_domain_number_of_boundaries.pybuffer.buf = NULL;
      __pyx_pybuffer_domain_number_of_boundaries.refcount = 0;
      __pyx_pybuffernd_domain_number_of_boundaries.data = NULL;
      __pyx_pybuffernd_domain_number_of_boundaries.rcbuffer = &__pyx_pybuffer_domain_number_of_boundaries;
      __pyx_pybuffer_domain_surrogate_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_domain_surrogate_neighbours.refcount = 0;
      __pyx_pybuffernd_domain_surrogate_neighbours.data = NULL;
      __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer = &__pyx_pybuffer_domain_surrogate_neighbours;
      __pyx_pybuffer_domain_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_domain_neighbours.refcount = 0;
      __pyx_pybuffernd_domain_neighbours.data = NULL;
      __pyx_pybuffernd_domain_neighbours.rcbuffer = &__pyx_pybuffer_domain_neighbours;
      __pyx_pybuffer_quantity_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_centroid_values.refcount = 0;
      __pyx_pybuffernd_quantity_centroid_values.data = NULL;
      __pyx_pybuffernd_quantity_centroid_values.rcbuffer = &__pyx_pybuffer_quantity_centroid_values;
      __pyx_pybuffer_quantity_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_vertex_values.refcount = 0;
      __pyx_pybuffernd_quantity_vertex_values.data = NULL;
      __pyx_pybuffernd_quantity_vertex_values.rcbuffer = &__pyx_pybuffer_quantity_vertex_values;
      __pyx_pybuffer_quantity_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_edge_values.refcount = 0;
      __pyx_pybuffernd_quantity_edge_values.data = NULL;
      __pyx_pybuffernd_quantity_edge_values.rcbuffer = &__pyx_pybuffer_quantity_edge_values;
      __pyx_pybuffer_quantity_phi.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_phi.refcount = 0;
      __pyx_pybuffernd_quantity_phi.data = NULL;
      __pyx_pybuffernd_quantity_phi.rcbuffer = &__pyx_pybuffer_quantity_phi;
      __pyx_pybuffer_quantity_x_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_x_gradient.refcount = 0;
      __pyx_pybuffernd_quantity_x_gradient.data = NULL;
      __pyx_pybuffernd_quantity_x_gradient.rcbuffer = &__pyx_pybuffer_quantity_x_gradient;
      __pyx_pybuffer_quantity_y_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_quantity_y_gradient.refcount = 0;
      __pyx_pybuffernd_quantity_y_gradient.data = NULL;
      __pyx_pybuffernd_quantity_y_gradient.rcbuffer = &__pyx_pybuffer_quantity_y_gradient;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.extrapolate_second_order_and_limit_by_vertex", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_domain_centroids);
      __Pyx_XDECREF((PyObject *)__pyx_v_domain_vertex_coordinates);
      __Pyx_XDECREF((PyObject *)__pyx_v_domain_number_of_boundaries);
      __Pyx_XDECREF((PyObject *)__pyx_v_domain_surrogate_neighbours);
      __Pyx_XDECREF((PyObject *)__pyx_v_domain_neighbours);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_phi);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_x_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_quantity_y_gradient);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__27 = PyTuple_Pack(16, __pyx_n_s_quantity, __pyx_n_s_domain, __pyx_n_s_domain_centroids, __pyx_n_s_domain_vertex_coordinates, __pyx_n_s_domain_number_of_boundaries, __pyx_n_s_domain_surrogate_neighbours, __pyx_n_s_domain_neighbours, __pyx_n_s_quantity_centroid_values, __pyx_n_s_quantity_vertex_values, __pyx_n_s_quantity_edge_values, __pyx_n_s_quantity_phi, __pyx_n_s_quantity_x_gradient, __pyx_n_s_quantity_y_gradient, __pyx_n_s_ntri, __pyx_n_s_beta, __pyx_n_s_err); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(0, 358, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__27);
      __Pyx_GIVEREF(__pyx_tuple__27);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_25extrapolate_second_order_and_limit_by_vertex, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 358, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_extrapolate_second_order_and_lim_2, __pyx_t_1) < 0) __PYX_ERR(0, 358, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__28 = (PyObject*)__Pyx_PyCode_New(1, 0, 16, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__27, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_extrapolate_second_order_and_lim_2, 358, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__28)) __PYX_ERR(0, 358, __pyx_L1_error)

     359:

     360:   cdef object domain

     361:

     362:   cdef np.ndarray[double, ndim=2, mode="c"] domain_centroids

     363:   cdef np.ndarray[double, ndim=2, mode="c"] domain_vertex_coordinates

     364:   cdef np.ndarray[long, ndim=1, mode="c"] domain_number_of_boundaries

     365:   cdef np.ndarray[long, ndim=2, mode="c"] domain_surrogate_neighbours

     366:   cdef np.ndarray[long, ndim=2, mode="c"] domain_neighbours

     367:

     368:   cdef np.ndarray[double, ndim=1, mode="c"] quantity_centroid_values

     369:   cdef np.ndarray[double, ndim=2, mode="c"] quantity_vertex_values

     370:   cdef np.ndarray[double, ndim=2, mode="c"] quantity_edge_values

     371:   cdef np.ndarray[double, ndim=1, mode="c"] quantity_phi

     372:   cdef np.ndarray[double, ndim=1, mode="c"] quantity_x_gradient

     373:   cdef np.ndarray[double, ndim=1, mode="c"] quantity_y_gradient

     374:

     375:   cdef keyint ntri

     376:   cdef double beta

     377:   cdef int err

     378:

    +379:   domain = quantity.object

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_object); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 379, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     380:

    +381:   domain_centroids = domain.centroid_coordinates

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_centroid_coordinates); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 381, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 381, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer, (PyObject*)__pyx_v_domain_centroids, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_domain_centroids.diminfo[0].strides = __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_domain_centroids.diminfo[0].shape = __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_domain_centroids.diminfo[1].strides = __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_domain_centroids.diminfo[1].shape = __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 381, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_domain_centroids = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +382:   domain_surrogate_neighbours = domain.surrogate_neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_surrogate_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 382, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 382, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_domain_surrogate_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[0].strides = __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[0].shape = __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[1].strides = __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[1].shape = __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 382, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_domain_surrogate_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +383:   domain_number_of_boundaries = domain.number_of_boundaries

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_number_of_boundaries); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 383, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 383, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer, (PyObject*)__pyx_v_domain_number_of_boundaries, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_domain_number_of_boundaries.diminfo[0].strides = __pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_domain_number_of_boundaries.diminfo[0].shape = __pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 383, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_domain_number_of_boundaries = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +384:   domain_vertex_coordinates = domain.vertex_coordinates

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_vertex_coordinates); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 384, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 384, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer, (PyObject*)__pyx_v_domain_vertex_coordinates, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_domain_vertex_coordinates.diminfo[0].strides = __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_domain_vertex_coordinates.diminfo[0].shape = __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_domain_vertex_coordinates.diminfo[1].strides = __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_domain_vertex_coordinates.diminfo[1].shape = __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 384, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_domain_vertex_coordinates = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +385:   domain_neighbours = domain.neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 385, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 385, __pyx_L1_error)
      __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_domain_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_domain_neighbours.diminfo[0].strides = __pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_domain_neighbours.diminfo[0].shape = __pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_domain_neighbours.diminfo[1].strides = __pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_domain_neighbours.diminfo[1].shape = __pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 385, __pyx_L1_error)
      }
      __pyx_t_10 = 0;
      __pyx_v_domain_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     386:

    +387:   quantity_centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 387, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 387, __pyx_L1_error)
      __pyx_t_11 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_quantity_centroid_values.diminfo[0].strides = __pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_centroid_values.diminfo[0].shape = __pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 387, __pyx_L1_error)
      }
      __pyx_t_11 = 0;
      __pyx_v_quantity_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +388:   quantity_vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 388, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 388, __pyx_L1_error)
      __pyx_t_12 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_quantity_vertex_values.diminfo[0].strides = __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_vertex_values.diminfo[0].shape = __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_quantity_vertex_values.diminfo[1].strides = __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_quantity_vertex_values.diminfo[1].shape = __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 388, __pyx_L1_error)
      }
      __pyx_t_12 = 0;
      __pyx_v_quantity_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +389:   quantity_edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 389, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 389, __pyx_L1_error)
      __pyx_t_13 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_13, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_quantity_edge_values.diminfo[0].strides = __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_edge_values.diminfo[0].shape = __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_quantity_edge_values.diminfo[1].strides = __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_quantity_edge_values.diminfo[1].shape = __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 389, __pyx_L1_error)
      }
      __pyx_t_13 = 0;
      __pyx_v_quantity_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +390:   quantity_phi = quantity.phi

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_phi); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 390, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 390, __pyx_L1_error)
      __pyx_t_14 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer, (PyObject*)__pyx_t_14, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_phi, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_quantity_phi.diminfo[0].strides = __pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_phi.diminfo[0].shape = __pyx_pybuffernd_quantity_phi.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 390, __pyx_L1_error)
      }
      __pyx_t_14 = 0;
      __pyx_v_quantity_phi = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +391:   quantity_x_gradient = quantity.x_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_x_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 391, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 391, __pyx_L1_error)
      __pyx_t_15 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_15, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_x_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_quantity_x_gradient.diminfo[0].strides = __pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_x_gradient.diminfo[0].shape = __pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 391, __pyx_L1_error)
      }
      __pyx_t_15 = 0;
      __pyx_v_quantity_x_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +392:   quantity_y_gradient = quantity.y_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_y_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 392, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 392, __pyx_L1_error)
      __pyx_t_16 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_16, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_quantity_y_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_quantity_y_gradient.diminfo[0].strides = __pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_quantity_y_gradient.diminfo[0].shape = __pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 392, __pyx_L1_error)
      }
      __pyx_t_16 = 0;
      __pyx_v_quantity_y_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     393:

    +394:   beta = quantity.beta

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_beta); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 394, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_17 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_17 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 394, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_beta = __pyx_t_17;

     395:

    +396:   ntri = quantity_centroid_values.shape[0]

      __pyx_v_ntri = (__pyx_v_quantity_centroid_values->dimensions[0]);

     397:

    +398:   err = _compute_gradients(ntri,\

      __pyx_v_err = _compute_gradients(__pyx_v_ntri, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_domain_centroids.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_domain_centroids.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_quantity_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_domain_number_of_boundaries.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_domain_number_of_boundaries.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(long *, __pyx_pybuffernd_domain_surrogate_neighbours.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[0].strides, __pyx_t_23, __pyx_pybuffernd_domain_surrogate_neighbours.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_24, __pyx_pybuffernd_quantity_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_25, __pyx_pybuffernd_quantity_y_gradient.diminfo[0].strides))));

    +399: 						&domain_centroids[0,0],\

      __pyx_t_18 = 0;
      __pyx_t_19 = 0;

    +400: 						&quantity_centroid_values[0],\

      __pyx_t_20 = 0;

    +401: 						&domain_number_of_boundaries[0],\

      __pyx_t_21 = 0;

    +402: 						&domain_surrogate_neighbours[0,0],\

      __pyx_t_22 = 0;
      __pyx_t_23 = 0;

    +403: 						&quantity_x_gradient[0],\

      __pyx_t_24 = 0;

    +404: 						&quantity_y_gradient[0])

      __pyx_t_25 = 0;

     405:

    +406:   assert err == 0, "Internal function _compute_gradient failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__compute_gradi);
          __PYX_ERR(0, 406, __pyx_L1_error)
        }
      }
      #endif

     407:

    +408:   err = _extrapolate_from_gradient(ntri,\

      __pyx_v_err = _extrapolate_from_gradient(__pyx_v_ntri, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_domain_centroids.rcbuffer->pybuffer.buf, __pyx_t_25, __pyx_pybuffernd_domain_centroids.diminfo[0].strides, __pyx_t_24, __pyx_pybuffernd_domain_centroids.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_23, __pyx_pybuffernd_quantity_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_domain_vertex_coordinates.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_domain_vertex_coordinates.diminfo[0].strides, __pyx_t_21, __pyx_pybuffernd_domain_vertex_coordinates.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_quantity_vertex_values.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_quantity_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_quantity_edge_values.diminfo[0].strides, __pyx_t_26, __pyx_pybuffernd_quantity_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_27, __pyx_pybuffernd_quantity_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_28, __pyx_pybuffernd_quantity_y_gradient.diminfo[0].strides))));

    +409: 						&domain_centroids[0,0],\

      __pyx_t_25 = 0;
      __pyx_t_24 = 0;

    +410: 						&quantity_centroid_values[0],\

      __pyx_t_23 = 0;

    +411: 						&domain_vertex_coordinates[0,0],\

      __pyx_t_22 = 0;
      __pyx_t_21 = 0;

    +412: 						&quantity_vertex_values[0,0],\

      __pyx_t_20 = 0;
      __pyx_t_19 = 0;

    +413: 						&quantity_edge_values[0,0],\

      __pyx_t_18 = 0;
      __pyx_t_26 = 0;

    +414: 						&quantity_x_gradient[0],\

      __pyx_t_27 = 0;

    +415: 						&quantity_y_gradient[0])

      __pyx_t_28 = 0;

     416:

    +417:   assert err == 0, "Internal function _extrapolate_from_gradient failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__extrapolate_f_2);
          __PYX_ERR(0, 417, __pyx_L1_error)
        }
      }
      #endif

     418:

    +419:   err = _limit_vertices_by_all_neighbours(ntri, beta,\

      __pyx_v_err = _limit_vertices_by_all_neighbours(__pyx_v_ntri, __pyx_v_beta, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_28, __pyx_pybuffernd_quantity_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_quantity_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_27, __pyx_pybuffernd_quantity_vertex_values.diminfo[0].strides, __pyx_t_26, __pyx_pybuffernd_quantity_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_quantity_edge_values.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_quantity_edge_values.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_quantity_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(long *, __pyx_pybuffernd_domain_neighbours.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_domain_neighbours.diminfo[0].strides, __pyx_t_21, __pyx_pybuffernd_domain_neighbours.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_quantity_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_quantity_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_23, __pyx_pybuffernd_quantity_y_gradient.diminfo[0].strides))));

    +420: 						&quantity_centroid_values[0],\

      __pyx_t_28 = 0;

    +421: 						&quantity_vertex_values[0,0],\

      __pyx_t_27 = 0;
      __pyx_t_26 = 0;

    +422: 						&quantity_edge_values[0,0],\

      __pyx_t_18 = 0;
      __pyx_t_19 = 0;

    +423: 						&domain_neighbours[0,0],\

      __pyx_t_20 = 0;
      __pyx_t_21 = 0;

    +424: 						&quantity_x_gradient[0],\

      __pyx_t_22 = 0;

    +425: 						&quantity_y_gradient[0])

      __pyx_t_23 = 0;

     426:

    +427:   assert err == 0, "Internal function _limit_edges_by_all_neighbours failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__limit_edges_b);
          __PYX_ERR(0, 427, __pyx_L1_error)
        }
      }
      #endif

     428:

    +429: def compute_gradients(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_27compute_gradients(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_27compute_gradients = {"compute_gradients", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_27compute_gradients, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_27compute_gradients(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("compute_gradients (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_26compute_gradients(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_26compute_gradients(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_centroids = 0;
      PyArrayObject *__pyx_v_centroid_values = 0;
      CYTHON_UNUSED PyArrayObject *__pyx_v_vertex_coordinates = 0;
      CYTHON_UNUSED PyArrayObject *__pyx_v_vertex_values = 0;
      CYTHON_UNUSED PyArrayObject *__pyx_v_edge_values = 0;
      PyArrayObject *__pyx_v_number_of_boundaries = 0;
      PyArrayObject *__pyx_v_surrogate_neighbours = 0;
      PyArrayObject *__pyx_v_x_gradient = 0;
      PyArrayObject *__pyx_v_y_gradient = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroids;
      __Pyx_Buffer __pyx_pybuffer_centroids;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_number_of_boundaries;
      __Pyx_Buffer __pyx_pybuffer_number_of_boundaries;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_surrogate_neighbours;
      __Pyx_Buffer __pyx_pybuffer_surrogate_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_coordinates;
      __Pyx_Buffer __pyx_pybuffer_vertex_coordinates;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_x_gradient;
      __Pyx_Buffer __pyx_pybuffer_x_gradient;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_y_gradient;
      __Pyx_Buffer __pyx_pybuffer_y_gradient;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("compute_gradients", 0);
      __pyx_pybuffer_centroids.pybuffer.buf = NULL;
      __pyx_pybuffer_centroids.refcount = 0;
      __pyx_pybuffernd_centroids.data = NULL;
      __pyx_pybuffernd_centroids.rcbuffer = &__pyx_pybuffer_centroids;
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_vertex_coordinates.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_coordinates.refcount = 0;
      __pyx_pybuffernd_vertex_coordinates.data = NULL;
      __pyx_pybuffernd_vertex_coordinates.rcbuffer = &__pyx_pybuffer_vertex_coordinates;
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
      __pyx_pybuffer_number_of_boundaries.pybuffer.buf = NULL;
      __pyx_pybuffer_number_of_boundaries.refcount = 0;
      __pyx_pybuffernd_number_of_boundaries.data = NULL;
      __pyx_pybuffernd_number_of_boundaries.rcbuffer = &__pyx_pybuffer_number_of_boundaries;
      __pyx_pybuffer_surrogate_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_surrogate_neighbours.refcount = 0;
      __pyx_pybuffernd_surrogate_neighbours.data = NULL;
      __pyx_pybuffernd_surrogate_neighbours.rcbuffer = &__pyx_pybuffer_surrogate_neighbours;
      __pyx_pybuffer_x_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_x_gradient.refcount = 0;
      __pyx_pybuffernd_x_gradient.data = NULL;
      __pyx_pybuffernd_x_gradient.rcbuffer = &__pyx_pybuffer_x_gradient;
      __pyx_pybuffer_y_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_y_gradient.refcount = 0;
      __pyx_pybuffernd_y_gradient.data = NULL;
      __pyx_pybuffernd_y_gradient.rcbuffer = &__pyx_pybuffer_y_gradient;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroids.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.compute_gradients", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroids.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroids);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_coordinates);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_number_of_boundaries);
      __Pyx_XDECREF((PyObject *)__pyx_v_surrogate_neighbours);
      __Pyx_XDECREF((PyObject *)__pyx_v_x_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_y_gradient);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__29 = PyTuple_Pack(13, __pyx_n_s_quantity, __pyx_n_s_domain, __pyx_n_s_centroids, __pyx_n_s_centroid_values, __pyx_n_s_vertex_coordinates, __pyx_n_s_vertex_values, __pyx_n_s_edge_values, __pyx_n_s_number_of_boundaries, __pyx_n_s_surrogate_neighbours, __pyx_n_s_x_gradient, __pyx_n_s_y_gradient, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(0, 429, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__29);
      __Pyx_GIVEREF(__pyx_tuple__29);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_27compute_gradients, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 429, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_compute_gradients, __pyx_t_1) < 0) __PYX_ERR(0, 429, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__30 = (PyObject*)__Pyx_PyCode_New(1, 0, 13, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__29, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_compute_gradients, 429, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__30)) __PYX_ERR(0, 429, __pyx_L1_error)

     430:

     431:   cdef object domain

     432:

     433:   cdef np.ndarray[double, ndim=2, mode="c"] centroids

     434:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     435:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_coordinates

     436:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     437:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     438:   cdef np.ndarray[long, ndim=1, mode="c"] number_of_boundaries

     439:   cdef np.ndarray[long, ndim=2, mode="c"] surrogate_neighbours

     440:   cdef np.ndarray[double, ndim=1, mode="c"] x_gradient

     441:   cdef np.ndarray[double, ndim=1, mode="c"] y_gradient

     442:

     443:   cdef keyint N

     444:   cdef int err

     445:

    +446:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     447:

    +448:   centroids = domain.centroid_coordinates

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_centroid_coordinates); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 448, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 448, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroids.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroids.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroids.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroids, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_centroids.diminfo[0].strides = __pyx_pybuffernd_centroids.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroids.diminfo[0].shape = __pyx_pybuffernd_centroids.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_centroids.diminfo[1].strides = __pyx_pybuffernd_centroids.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_centroids.diminfo[1].shape = __pyx_pybuffernd_centroids.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 448, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_centroids = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +449:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 449, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 449, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 449, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +450:   surrogate_neighbours = domain.surrogate_neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_surrogate_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 450, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 450, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_surrogate_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_surrogate_neighbours.diminfo[0].strides = __pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_surrogate_neighbours.diminfo[0].shape = __pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_surrogate_neighbours.diminfo[1].strides = __pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_surrogate_neighbours.diminfo[1].shape = __pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 450, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_surrogate_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +451:   number_of_boundaries = domain.number_of_boundaries

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_number_of_boundaries); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 451, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 451, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer, (PyObject*)__pyx_v_number_of_boundaries, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_number_of_boundaries.diminfo[0].strides = __pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_number_of_boundaries.diminfo[0].shape = __pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 451, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_number_of_boundaries = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +452:   vertex_coordinates = domain.vertex_coordinates

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_vertex_coordinates); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 452, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 452, __pyx_L1_error)
      __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_coordinates, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_vertex_coordinates.diminfo[0].strides = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_coordinates.diminfo[0].shape = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_coordinates.diminfo[1].strides = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_coordinates.diminfo[1].shape = __pyx_pybuffernd_vertex_coordinates.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 452, __pyx_L1_error)
      }
      __pyx_t_10 = 0;
      __pyx_v_vertex_coordinates = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +453:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 453, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 453, __pyx_L1_error)
      __pyx_t_11 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 453, __pyx_L1_error)
      }
      __pyx_t_11 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +454:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 454, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 454, __pyx_L1_error)
      __pyx_t_12 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 454, __pyx_L1_error)
      }
      __pyx_t_12 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +455:   x_gradient = quantity.x_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_x_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 455, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 455, __pyx_L1_error)
      __pyx_t_13 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_13, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_x_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_x_gradient.diminfo[0].strides = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x_gradient.diminfo[0].shape = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 455, __pyx_L1_error)
      }
      __pyx_t_13 = 0;
      __pyx_v_x_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +456:   y_gradient = quantity.y_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_y_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 456, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 456, __pyx_L1_error)
      __pyx_t_14 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_14, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_y_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_y_gradient.diminfo[0].strides = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y_gradient.diminfo[0].shape = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 456, __pyx_L1_error)
      }
      __pyx_t_14 = 0;
      __pyx_v_y_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     457:

    +458:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     459:

    +460:   err = _compute_gradients(N,\

      __pyx_v_err = _compute_gradients(__pyx_v_N, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_centroids.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_centroids.diminfo[0].strides, __pyx_t_16, __pyx_pybuffernd_centroids.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(long *, __pyx_pybuffernd_number_of_boundaries.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_number_of_boundaries.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(long *, __pyx_pybuffernd_surrogate_neighbours.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_surrogate_neighbours.diminfo[0].strides, __pyx_t_20, __pyx_pybuffernd_surrogate_neighbours.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_y_gradient.diminfo[0].strides))));

    +461: 						&centroids[0,0],\

      __pyx_t_15 = 0;
      __pyx_t_16 = 0;

    +462: 						&centroid_values[0],\

      __pyx_t_17 = 0;

    +463: 						&number_of_boundaries[0],\

      __pyx_t_18 = 0;

    +464: 						&surrogate_neighbours[0,0],\

      __pyx_t_19 = 0;
      __pyx_t_20 = 0;

    +465: 						&x_gradient[0],\

      __pyx_t_21 = 0;

    +466: 						&y_gradient[0])

      __pyx_t_22 = 0;

     467:

    +468:   assert err == 0, "Gradient could not be computed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Gradient_could_not_be_computed);
          __PYX_ERR(0, 468, __pyx_L1_error)
        }
      }
      #endif

     469:

    +470: def limit_old(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_29limit_old(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_29limit_old = {"limit_old", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_29limit_old, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_29limit_old(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("limit_old (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_28limit_old(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_28limit_old(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_qc = 0;
      PyArrayObject *__pyx_v_qv = 0;
      PyArrayObject *__pyx_v_neighbours = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      double __pyx_v_beta_w;
      int __pyx_v_err;
      PyArrayObject *__pyx_v_qmin = 0;
      PyArrayObject *__pyx_v_qmax = 0;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_neighbours;
      __Pyx_Buffer __pyx_pybuffer_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_qc;
      __Pyx_Buffer __pyx_pybuffer_qc;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_qmax;
      __Pyx_Buffer __pyx_pybuffer_qmax;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_qmin;
      __Pyx_Buffer __pyx_pybuffer_qmin;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_qv;
      __Pyx_Buffer __pyx_pybuffer_qv;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("limit_old", 0);
      __pyx_pybuffer_qc.pybuffer.buf = NULL;
      __pyx_pybuffer_qc.refcount = 0;
      __pyx_pybuffernd_qc.data = NULL;
      __pyx_pybuffernd_qc.rcbuffer = &__pyx_pybuffer_qc;
      __pyx_pybuffer_qv.pybuffer.buf = NULL;
      __pyx_pybuffer_qv.refcount = 0;
      __pyx_pybuffernd_qv.data = NULL;
      __pyx_pybuffernd_qv.rcbuffer = &__pyx_pybuffer_qv;
      __pyx_pybuffer_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_neighbours.refcount = 0;
      __pyx_pybuffernd_neighbours.data = NULL;
      __pyx_pybuffernd_neighbours.rcbuffer = &__pyx_pybuffer_neighbours;
      __pyx_pybuffer_qmin.pybuffer.buf = NULL;
      __pyx_pybuffer_qmin.refcount = 0;
      __pyx_pybuffernd_qmin.data = NULL;
      __pyx_pybuffernd_qmin.rcbuffer = &__pyx_pybuffer_qmin;
      __pyx_pybuffer_qmax.pybuffer.buf = NULL;
      __pyx_pybuffer_qmax.refcount = 0;
      __pyx_pybuffernd_qmax.data = NULL;
      __pyx_pybuffernd_qmax.rcbuffer = &__pyx_pybuffer_qmax;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      __Pyx_XDECREF(__pyx_t_10);
      __Pyx_XDECREF(__pyx_t_11);
      __Pyx_XDECREF(__pyx_t_12);
      __Pyx_XDECREF(__pyx_t_13);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_qc.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_qmax.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_qmin.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_qv.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.limit_old", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_qc.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_qmax.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_qmin.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_qv.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_qc);
      __Pyx_XDECREF((PyObject *)__pyx_v_qv);
      __Pyx_XDECREF((PyObject *)__pyx_v_neighbours);
      __Pyx_XDECREF((PyObject *)__pyx_v_qmin);
      __Pyx_XDECREF((PyObject *)__pyx_v_qmax);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__31 = PyTuple_Pack(10, __pyx_n_s_quantity, __pyx_n_s_domain, __pyx_n_s_qc, __pyx_n_s_qv, __pyx_n_s_neighbours, __pyx_n_s_N, __pyx_n_s_beta_w, __pyx_n_s_err, __pyx_n_s_qmin, __pyx_n_s_qmax); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(0, 470, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__31);
      __Pyx_GIVEREF(__pyx_tuple__31);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_29limit_old, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 470, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_limit_old, __pyx_t_1) < 0) __PYX_ERR(0, 470, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__32 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__31, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_limit_old, 470, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__32)) __PYX_ERR(0, 470, __pyx_L1_error)

     471:

     472:   cdef object domain

     473:

     474:   cdef np.ndarray[double, ndim=1, mode="c"] qc

     475:   cdef np.ndarray[double, ndim=2, mode="c"] qv

     476:   cdef np.ndarray[long, ndim=2, mode="c"] neighbours

     477:

     478:   cdef keyint N

     479:   cdef double beta_w

     480:   cdef int err

     481:

    +482:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 482, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     483:

    +484:   neighbours = domain.neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 484, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 484, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_neighbours.diminfo[0].strides = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_neighbours.diminfo[0].shape = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_neighbours.diminfo[1].strides = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_neighbours.diminfo[1].shape = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 484, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     485:

    +486:   beta_w = domain.beta_w

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_beta_w); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 486, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 486, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_beta_w = __pyx_t_7;

     487:

    +488:   qc = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 488, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 488, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_qc.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_qc.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_qc.rcbuffer->pybuffer, (PyObject*)__pyx_v_qc, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_qc.diminfo[0].strides = __pyx_pybuffernd_qc.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_qc.diminfo[0].shape = __pyx_pybuffernd_qc.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 488, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_qc = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +489:   qv = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 489, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 489, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_qv.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_qv.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_qv.rcbuffer->pybuffer, (PyObject*)__pyx_v_qv, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_qv.diminfo[0].strides = __pyx_pybuffernd_qv.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_qv.diminfo[0].shape = __pyx_pybuffernd_qv.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_qv.diminfo[1].strides = __pyx_pybuffernd_qv.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_qv.diminfo[1].shape = __pyx_pybuffernd_qv.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 489, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_qv = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     490:

    +491:   N = qc.shape[0]

      __pyx_v_N = (__pyx_v_qc->dimensions[0]);

     492:

    +493:   cdef np.ndarray[double, ndim=1, mode="c"] qmin = np.empty(N, dtype=np.float64)

      __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 493, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 493, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_N); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 493, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 493, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_GIVEREF(__pyx_t_1);
      PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_1);
      __pyx_t_1 = 0;
      __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 493, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_n_s_np); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 493, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_12);
      __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_float64); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 493, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
      if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_13) < 0) __PYX_ERR(0, 493, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
      __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_11, __pyx_t_1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 493, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 493, __pyx_L1_error)
      __pyx_t_14 = ((PyArrayObject *)__pyx_t_13);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_qmin.rcbuffer->pybuffer, (PyObject*)__pyx_t_14, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
          __pyx_v_qmin = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_qmin.rcbuffer->pybuffer.buf = NULL;
          __PYX_ERR(0, 493, __pyx_L1_error)
        } else {__pyx_pybuffernd_qmin.diminfo[0].strides = __pyx_pybuffernd_qmin.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_qmin.diminfo[0].shape = __pyx_pybuffernd_qmin.rcbuffer->pybuffer.shape[0];
        }
      }
      __pyx_t_14 = 0;
      __pyx_v_qmin = ((PyArrayObject *)__pyx_t_13);
      __pyx_t_13 = 0;

    +494:   cdef np.ndarray[double, ndim=1, mode="c"] qmax = np.empty(N, dtype=np.float64)

      __Pyx_GetModuleGlobalName(__pyx_t_13, __pyx_n_s_np); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 494, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 494, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
      __pyx_t_13 = __Pyx_PyInt_From_long(__pyx_v_N); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 494, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
      __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 494, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_GIVEREF(__pyx_t_13);
      PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_13);
      __pyx_t_13 = 0;
      __pyx_t_13 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 494, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
      __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_np); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 494, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float64); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 494, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_12);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      if (PyDict_SetItem(__pyx_t_13, __pyx_n_s_dtype, __pyx_t_12) < 0) __PYX_ERR(0, 494, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
      __pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_11, __pyx_t_13); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 494, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_12);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
      if (!(likely(((__pyx_t_12) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_12, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 494, __pyx_L1_error)
      __pyx_t_15 = ((PyArrayObject *)__pyx_t_12);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_qmax.rcbuffer->pybuffer, (PyObject*)__pyx_t_15, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
          __pyx_v_qmax = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_qmax.rcbuffer->pybuffer.buf = NULL;
          __PYX_ERR(0, 494, __pyx_L1_error)
        } else {__pyx_pybuffernd_qmax.diminfo[0].strides = __pyx_pybuffernd_qmax.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_qmax.diminfo[0].shape = __pyx_pybuffernd_qmax.rcbuffer->pybuffer.shape[0];
        }
      }
      __pyx_t_15 = 0;
      __pyx_v_qmax = ((PyArrayObject *)__pyx_t_12);
      __pyx_t_12 = 0;

     495:

    +496:   err = _min_and_max_centroid_values(N, &qc[0], &qv[0,0], &neighbours[0,0], &qmin[0], &qmax[0])

      __pyx_t_16 = 0;
      __pyx_t_17 = 0;
      __pyx_t_18 = 0;
      __pyx_t_19 = 0;
      __pyx_t_20 = 0;
      __pyx_t_21 = 0;
      __pyx_t_22 = 0;
      __pyx_v_err = _min_and_max_centroid_values(__pyx_v_N, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_qc.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_qc.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_qv.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_qv.diminfo[0].strides, __pyx_t_18, __pyx_pybuffernd_qv.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(long *, __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_neighbours.diminfo[0].strides, __pyx_t_20, __pyx_pybuffernd_neighbours.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_qmin.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_qmin.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_qmax.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_qmax.diminfo[0].strides))));

     497:

    +498:   assert err == 0, "Internal function _min_and_max_centroid_values failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__min_and_max_c);
          __PYX_ERR(0, 498, __pyx_L1_error)
        }
      }
      #endif

     499:

    +500:   _limit_old(N, beta_w, &qc[0], &qv[0,0], &qmin[0], &qmax[0])

      __pyx_t_22 = 0;
      __pyx_t_21 = 0;
      __pyx_t_20 = 0;
      __pyx_t_19 = 0;
      __pyx_t_18 = 0;
      _limit_old(__pyx_v_N, __pyx_v_beta_w, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_qc.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_qc.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_qv.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_qv.diminfo[0].strides, __pyx_t_20, __pyx_pybuffernd_qv.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_qmin.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_qmin.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_qmax.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_qmax.diminfo[0].strides))));

     501:

    +502: def limit_vertices_by_all_neighbours(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_31limit_vertices_by_all_neighbours(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_31limit_vertices_by_all_neighbours = {"limit_vertices_by_all_neighbours", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_31limit_vertices_by_all_neighbours, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_31limit_vertices_by_all_neighbours(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("limit_vertices_by_all_neighbours (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_30limit_vertices_by_all_neighbours(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_30limit_vertices_by_all_neighbours(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_edge_values = 0;
      PyArrayObject *__pyx_v_neighbours = 0;
      PyArrayObject *__pyx_v_x_gradient = 0;
      PyArrayObject *__pyx_v_y_gradient = 0;
      double __pyx_v_beta_w;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_neighbours;
      __Pyx_Buffer __pyx_pybuffer_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_x_gradient;
      __Pyx_Buffer __pyx_pybuffer_x_gradient;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_y_gradient;
      __Pyx_Buffer __pyx_pybuffer_y_gradient;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("limit_vertices_by_all_neighbours", 0);
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
      __pyx_pybuffer_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_neighbours.refcount = 0;
      __pyx_pybuffernd_neighbours.data = NULL;
      __pyx_pybuffernd_neighbours.rcbuffer = &__pyx_pybuffer_neighbours;
      __pyx_pybuffer_x_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_x_gradient.refcount = 0;
      __pyx_pybuffernd_x_gradient.data = NULL;
      __pyx_pybuffernd_x_gradient.rcbuffer = &__pyx_pybuffer_x_gradient;
      __pyx_pybuffer_y_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_y_gradient.refcount = 0;
      __pyx_pybuffernd_y_gradient.data = NULL;
      __pyx_pybuffernd_y_gradient.rcbuffer = &__pyx_pybuffer_y_gradient;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.limit_vertices_by_all_neighbours", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_neighbours);
      __Pyx_XDECREF((PyObject *)__pyx_v_x_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_y_gradient);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__33 = PyTuple_Pack(11, __pyx_n_s_quantity, __pyx_n_s_domain, __pyx_n_s_vertex_values, __pyx_n_s_centroid_values, __pyx_n_s_edge_values, __pyx_n_s_neighbours, __pyx_n_s_x_gradient, __pyx_n_s_y_gradient, __pyx_n_s_beta_w, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(0, 502, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__33);
      __Pyx_GIVEREF(__pyx_tuple__33);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_31limit_vertices_by_all_neighbours, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 502, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_limit_vertices_by_all_neighbours, __pyx_t_1) < 0) __PYX_ERR(0, 502, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__34 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__33, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_limit_vertices_by_all_neighbours, 502, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__34)) __PYX_ERR(0, 502, __pyx_L1_error)

     503:

     504:   cdef object domain

     505:

     506:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     507:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     508:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     509:   cdef np.ndarray[long, ndim=2, mode="c"] neighbours

     510:   cdef np.ndarray[double, ndim=1, mode="c"] x_gradient

     511:   cdef np.ndarray[double, ndim=1, mode="c"] y_gradient

     512:

     513:   cdef double beta_w

     514:   cdef keyint N

     515:   cdef int err

     516:

    +517:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 517, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     518:

    +519:   beta_w = domain.beta_w

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_beta_w); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 519, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_2 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 519, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_beta_w = __pyx_t_2;

     520:

    +521:   neighbours = domain.neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 521, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 521, __pyx_L1_error)
      __pyx_t_3 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_3, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_neighbours.diminfo[0].strides = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_neighbours.diminfo[0].shape = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_neighbours.diminfo[1].strides = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_neighbours.diminfo[1].shape = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 521, __pyx_L1_error)
      }
      __pyx_t_3 = 0;
      __pyx_v_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +522:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 522, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 522, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 522, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +523:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 523, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 523, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 523, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +524:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 524, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 524, __pyx_L1_error)
      __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 524, __pyx_L1_error)
      }
      __pyx_t_10 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +525:   x_gradient = quantity.x_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_x_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 525, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 525, __pyx_L1_error)
      __pyx_t_11 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_x_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_x_gradient.diminfo[0].strides = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x_gradient.diminfo[0].shape = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 525, __pyx_L1_error)
      }
      __pyx_t_11 = 0;
      __pyx_v_x_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +526:   y_gradient = quantity.y_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_y_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 526, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 526, __pyx_L1_error)
      __pyx_t_12 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_y_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_y_gradient.diminfo[0].strides = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y_gradient.diminfo[0].shape = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 526, __pyx_L1_error)
      }
      __pyx_t_12 = 0;
      __pyx_v_y_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +527:   beta_w = domain.beta_w

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_beta_w); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 527, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_2 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 527, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_beta_w = __pyx_t_2;

     528:

    +529:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     530:

    +531:   err = _limit_vertices_by_all_neighbours(N, beta_w,\

      __pyx_v_err = _limit_vertices_by_all_neighbours(__pyx_v_N, __pyx_v_beta_w, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_edge_values.diminfo[0].strides, __pyx_t_17, __pyx_pybuffernd_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(long *, __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_neighbours.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_neighbours.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_y_gradient.diminfo[0].strides))));

    +532: 											&centroid_values[0],\

      __pyx_t_13 = 0;

    +533: 											&vertex_values[0,0],\

      __pyx_t_14 = 0;
      __pyx_t_15 = 0;

    +534: 											&edge_values[0,0],\

      __pyx_t_16 = 0;
      __pyx_t_17 = 0;

    +535: 											&neighbours[0,0],\

      __pyx_t_18 = 0;
      __pyx_t_19 = 0;

    +536: 											&x_gradient[0],\

      __pyx_t_20 = 0;

    +537: 											&y_gradient[0])

      __pyx_t_21 = 0;

     538:

    +539:   assert err == 0, "Internal function _limit_by_vertex failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__limit_by_vert);
          __PYX_ERR(0, 539, __pyx_L1_error)
        }
      }
      #endif

     540:

    +541: def limit_edges_by_all_neighbours(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_33limit_edges_by_all_neighbours(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_33limit_edges_by_all_neighbours = {"limit_edges_by_all_neighbours", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_33limit_edges_by_all_neighbours, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_33limit_edges_by_all_neighbours(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("limit_edges_by_all_neighbours (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_32limit_edges_by_all_neighbours(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_32limit_edges_by_all_neighbours(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_edge_values = 0;
      PyArrayObject *__pyx_v_neighbours = 0;
      PyArrayObject *__pyx_v_x_gradient = 0;
      PyArrayObject *__pyx_v_y_gradient = 0;
      double __pyx_v_beta_w;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_neighbours;
      __Pyx_Buffer __pyx_pybuffer_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_x_gradient;
      __Pyx_Buffer __pyx_pybuffer_x_gradient;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_y_gradient;
      __Pyx_Buffer __pyx_pybuffer_y_gradient;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("limit_edges_by_all_neighbours", 0);
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
      __pyx_pybuffer_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_neighbours.refcount = 0;
      __pyx_pybuffernd_neighbours.data = NULL;
      __pyx_pybuffernd_neighbours.rcbuffer = &__pyx_pybuffer_neighbours;
      __pyx_pybuffer_x_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_x_gradient.refcount = 0;
      __pyx_pybuffernd_x_gradient.data = NULL;
      __pyx_pybuffernd_x_gradient.rcbuffer = &__pyx_pybuffer_x_gradient;
      __pyx_pybuffer_y_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_y_gradient.refcount = 0;
      __pyx_pybuffernd_y_gradient.data = NULL;
      __pyx_pybuffernd_y_gradient.rcbuffer = &__pyx_pybuffer_y_gradient;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.limit_edges_by_all_neighbours", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_neighbours);
      __Pyx_XDECREF((PyObject *)__pyx_v_x_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_y_gradient);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__35 = PyTuple_Pack(11, __pyx_n_s_quantity, __pyx_n_s_domain, __pyx_n_s_vertex_values, __pyx_n_s_centroid_values, __pyx_n_s_edge_values, __pyx_n_s_neighbours, __pyx_n_s_x_gradient, __pyx_n_s_y_gradient, __pyx_n_s_beta_w, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__35)) __PYX_ERR(0, 541, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__35);
      __Pyx_GIVEREF(__pyx_tuple__35);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_33limit_edges_by_all_neighbours, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 541, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_limit_edges_by_all_neighbours, __pyx_t_1) < 0) __PYX_ERR(0, 541, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__36 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__35, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_limit_edges_by_all_neighbours, 541, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__36)) __PYX_ERR(0, 541, __pyx_L1_error)

     542:

     543:   cdef object domain

     544:

     545:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     546:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     547:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     548:   cdef np.ndarray[long, ndim=2, mode="c"] neighbours

     549:   cdef np.ndarray[double, ndim=1, mode="c"] x_gradient

     550:   cdef np.ndarray[double, ndim=1, mode="c"] y_gradient

     551:

     552:   cdef double beta_w

     553:   cdef keyint N

     554:   cdef int err

     555:

    +556:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 556, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     557:

    +558:   beta_w = domain.beta_w

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_beta_w); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 558, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_2 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 558, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_beta_w = __pyx_t_2;

     559:

    +560:   neighbours = domain.neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 560, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 560, __pyx_L1_error)
      __pyx_t_3 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_3, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_neighbours.diminfo[0].strides = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_neighbours.diminfo[0].shape = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_neighbours.diminfo[1].strides = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_neighbours.diminfo[1].shape = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 560, __pyx_L1_error)
      }
      __pyx_t_3 = 0;
      __pyx_v_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +561:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 561, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 561, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 561, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +562:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 562, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 562, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 562, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +563:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 563, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 563, __pyx_L1_error)
      __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 563, __pyx_L1_error)
      }
      __pyx_t_10 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +564:   x_gradient = quantity.x_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_x_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 564, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 564, __pyx_L1_error)
      __pyx_t_11 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_x_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_x_gradient.diminfo[0].strides = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x_gradient.diminfo[0].shape = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 564, __pyx_L1_error)
      }
      __pyx_t_11 = 0;
      __pyx_v_x_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +565:   y_gradient = quantity.y_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_y_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 565, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 565, __pyx_L1_error)
      __pyx_t_12 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_y_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_y_gradient.diminfo[0].strides = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y_gradient.diminfo[0].shape = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 565, __pyx_L1_error)
      }
      __pyx_t_12 = 0;
      __pyx_v_y_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +566:   beta_w = domain.beta_w

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_beta_w); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 566, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_2 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 566, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_beta_w = __pyx_t_2;

     567:

    +568:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     569:

    +570:   err = _limit_edges_by_all_neighbours(N, beta_w,\

      __pyx_v_err = _limit_edges_by_all_neighbours(__pyx_v_N, __pyx_v_beta_w, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_edge_values.diminfo[0].strides, __pyx_t_17, __pyx_pybuffernd_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(long *, __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_neighbours.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_neighbours.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_y_gradient.diminfo[0].strides))));

    +571: 											&centroid_values[0],\

      __pyx_t_13 = 0;

    +572: 											&vertex_values[0,0],\

      __pyx_t_14 = 0;
      __pyx_t_15 = 0;

    +573: 											&edge_values[0,0],\

      __pyx_t_16 = 0;
      __pyx_t_17 = 0;

    +574: 											&neighbours[0,0],\

      __pyx_t_18 = 0;
      __pyx_t_19 = 0;

    +575: 											&x_gradient[0],\

      __pyx_t_20 = 0;

    +576: 											&y_gradient[0])

      __pyx_t_21 = 0;

     577:

    +578:   assert err == 0, "Internal function _limit_by_edges failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__limit_by_edge);
          __PYX_ERR(0, 578, __pyx_L1_error)
        }
      }
      #endif

     579:

    +580: def bound_vertices_below_by_constant(object quantity, double bound):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_35bound_vertices_below_by_constant(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_35bound_vertices_below_by_constant = {"bound_vertices_below_by_constant", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_35bound_vertices_below_by_constant, METH_VARARGS|METH_KEYWORDS, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_35bound_vertices_below_by_constant(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
      PyObject *__pyx_v_quantity = 0;
      double __pyx_v_bound;
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("bound_vertices_below_by_constant (wrapper)", 0);
      {
        static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_quantity,&__pyx_n_s_bound,0};
        PyObject* values[2] = {0,0};
        if (unlikely(__pyx_kwds)) {
          Py_ssize_t kw_args;
          const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
          switch (pos_args) {
            case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
            CYTHON_FALLTHROUGH;
            case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
            CYTHON_FALLTHROUGH;
            case  0: break;
            default: goto __pyx_L5_argtuple_error;
          }
          kw_args = PyDict_Size(__pyx_kwds);
          switch (pos_args) {
            case  0:
            if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_quantity)) != 0)) kw_args--;
            else goto __pyx_L5_argtuple_error;
            CYTHON_FALLTHROUGH;
            case  1:
            if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_bound)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("bound_vertices_below_by_constant", 1, 2, 2, 1); __PYX_ERR(0, 580, __pyx_L3_error)
            }
          }
          if (unlikely(kw_args > 0)) {
            if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "bound_vertices_below_by_constant") < 0)) __PYX_ERR(0, 580, __pyx_L3_error)
          }
        } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
          goto __pyx_L5_argtuple_error;
        } else {
          values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
          values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        }
        __pyx_v_quantity = values[0];
        __pyx_v_bound = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_bound == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 580, __pyx_L3_error)
      }
      goto __pyx_L4_argument_unpacking_done;
      __pyx_L5_argtuple_error:;
      __Pyx_RaiseArgtupleInvalid("bound_vertices_below_by_constant", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 580, __pyx_L3_error)
      __pyx_L3_error:;
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.bound_vertices_below_by_constant", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __Pyx_RefNannyFinishContext();
      return NULL;
      __pyx_L4_argument_unpacking_done:;
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_34bound_vertices_below_by_constant(__pyx_self, __pyx_v_quantity, __pyx_v_bound);
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_34bound_vertices_below_by_constant(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity, double __pyx_v_bound) {
      CYTHON_UNUSED PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_edge_values = 0;
      PyArrayObject *__pyx_v_x_gradient = 0;
      PyArrayObject *__pyx_v_y_gradient = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_x_gradient;
      __Pyx_Buffer __pyx_pybuffer_x_gradient;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_y_gradient;
      __Pyx_Buffer __pyx_pybuffer_y_gradient;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("bound_vertices_below_by_constant", 0);
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
      __pyx_pybuffer_x_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_x_gradient.refcount = 0;
      __pyx_pybuffernd_x_gradient.data = NULL;
      __pyx_pybuffernd_x_gradient.rcbuffer = &__pyx_pybuffer_x_gradient;
      __pyx_pybuffer_y_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_y_gradient.refcount = 0;
      __pyx_pybuffernd_y_gradient.data = NULL;
      __pyx_pybuffernd_y_gradient.rcbuffer = &__pyx_pybuffer_y_gradient;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.bound_vertices_below_by_constant", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_x_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_y_gradient);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__37 = PyTuple_Pack(10, __pyx_n_s_quantity, __pyx_n_s_bound, __pyx_n_s_domain, __pyx_n_s_vertex_values, __pyx_n_s_centroid_values, __pyx_n_s_edge_values, __pyx_n_s_x_gradient, __pyx_n_s_y_gradient, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__37)) __PYX_ERR(0, 580, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__37);
      __Pyx_GIVEREF(__pyx_tuple__37);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_35bound_vertices_below_by_constant, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 580, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_bound_vertices_below_by_constant, __pyx_t_1) < 0) __PYX_ERR(0, 580, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__38 = (PyObject*)__Pyx_PyCode_New(2, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__37, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_bound_vertices_below_by_constant, 580, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__38)) __PYX_ERR(0, 580, __pyx_L1_error)

     581:

     582:   cdef object domain

     583:

     584:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     585:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     586:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     587:   cdef np.ndarray[double, ndim=1, mode="c"] x_gradient

     588:   cdef np.ndarray[double, ndim=1, mode="c"] y_gradient

     589:

     590:   cdef keyint N

     591:   cdef int err

     592:

    +593:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 593, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     594:

    +595:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 595, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 595, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 595, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +596:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 596, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 596, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 596, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +597:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 597, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 597, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 597, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +598:   x_gradient = quantity.x_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_x_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 598, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 598, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_x_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_x_gradient.diminfo[0].strides = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x_gradient.diminfo[0].shape = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 598, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_x_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +599:   y_gradient = quantity.y_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_y_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 599, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 599, __pyx_L1_error)
      __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_y_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_y_gradient.diminfo[0].strides = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y_gradient.diminfo[0].shape = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 599, __pyx_L1_error)
      }
      __pyx_t_10 = 0;
      __pyx_v_y_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     600:

    +601:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     602:

    +603:   err = _bound_vertices_below_by_constant(N, bound,\

      __pyx_v_err = _bound_vertices_below_by_constant(__pyx_v_N, __pyx_v_bound, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_13, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_edge_values.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_y_gradient.diminfo[0].strides))));

    +604: 										&centroid_values[0],\

      __pyx_t_11 = 0;

    +605: 										&vertex_values[0,0],\

      __pyx_t_12 = 0;
      __pyx_t_13 = 0;

    +606: 										&edge_values[0,0],\

      __pyx_t_14 = 0;
      __pyx_t_15 = 0;

    +607: 										&x_gradient[0],\

      __pyx_t_16 = 0;

    +608: 										&y_gradient[0])

      __pyx_t_17 = 0;

     609:

    +610:   assert err == 0, "Internal function _bound_vertices_below_by_constant failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__bound_vertice);
          __PYX_ERR(0, 610, __pyx_L1_error)
        }
      }
      #endif

     611:

    +612: def bound_vertices_below_by_quantity(object quantity, object bounding_quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_37bound_vertices_below_by_quantity(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_37bound_vertices_below_by_quantity = {"bound_vertices_below_by_quantity", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_37bound_vertices_below_by_quantity, METH_VARARGS|METH_KEYWORDS, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_37bound_vertices_below_by_quantity(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
      PyObject *__pyx_v_quantity = 0;
      PyObject *__pyx_v_bounding_quantity = 0;
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("bound_vertices_below_by_quantity (wrapper)", 0);
      {
        static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_quantity,&__pyx_n_s_bounding_quantity,0};
        PyObject* values[2] = {0,0};
        if (unlikely(__pyx_kwds)) {
          Py_ssize_t kw_args;
          const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
          switch (pos_args) {
            case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
            CYTHON_FALLTHROUGH;
            case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
            CYTHON_FALLTHROUGH;
            case  0: break;
            default: goto __pyx_L5_argtuple_error;
          }
          kw_args = PyDict_Size(__pyx_kwds);
          switch (pos_args) {
            case  0:
            if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_quantity)) != 0)) kw_args--;
            else goto __pyx_L5_argtuple_error;
            CYTHON_FALLTHROUGH;
            case  1:
            if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_bounding_quantity)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("bound_vertices_below_by_quantity", 1, 2, 2, 1); __PYX_ERR(0, 612, __pyx_L3_error)
            }
          }
          if (unlikely(kw_args > 0)) {
            if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "bound_vertices_below_by_quantity") < 0)) __PYX_ERR(0, 612, __pyx_L3_error)
          }
        } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
          goto __pyx_L5_argtuple_error;
        } else {
          values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
          values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        }
        __pyx_v_quantity = values[0];
        __pyx_v_bounding_quantity = values[1];
      }
      goto __pyx_L4_argument_unpacking_done;
      __pyx_L5_argtuple_error:;
      __Pyx_RaiseArgtupleInvalid("bound_vertices_below_by_quantity", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 612, __pyx_L3_error)
      __pyx_L3_error:;
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.bound_vertices_below_by_quantity", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __Pyx_RefNannyFinishContext();
      return NULL;
      __pyx_L4_argument_unpacking_done:;
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_36bound_vertices_below_by_quantity(__pyx_self, __pyx_v_quantity, __pyx_v_bounding_quantity);
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_36bound_vertices_below_by_quantity(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity, PyObject *__pyx_v_bounding_quantity) {
      CYTHON_UNUSED PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_edge_values = 0;
      PyArrayObject *__pyx_v_x_gradient = 0;
      PyArrayObject *__pyx_v_y_gradient = 0;
      PyArrayObject *__pyx_v_bound_vertex_values = 0;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_bound_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_bound_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_x_gradient;
      __Pyx_Buffer __pyx_pybuffer_x_gradient;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_y_gradient;
      __Pyx_Buffer __pyx_pybuffer_y_gradient;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("bound_vertices_below_by_quantity", 0);
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
      __pyx_pybuffer_x_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_x_gradient.refcount = 0;
      __pyx_pybuffernd_x_gradient.data = NULL;
      __pyx_pybuffernd_x_gradient.rcbuffer = &__pyx_pybuffer_x_gradient;
      __pyx_pybuffer_y_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_y_gradient.refcount = 0;
      __pyx_pybuffernd_y_gradient.data = NULL;
      __pyx_pybuffernd_y_gradient.rcbuffer = &__pyx_pybuffer_y_gradient;
      __pyx_pybuffer_bound_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_bound_vertex_values.refcount = 0;
      __pyx_pybuffernd_bound_vertex_values.data = NULL;
      __pyx_pybuffernd_bound_vertex_values.rcbuffer = &__pyx_pybuffer_bound_vertex_values;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_bound_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.bound_vertices_below_by_quantity", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_bound_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_x_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_y_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_bound_vertex_values);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__39 = PyTuple_Pack(11, __pyx_n_s_quantity, __pyx_n_s_bounding_quantity, __pyx_n_s_domain, __pyx_n_s_vertex_values, __pyx_n_s_centroid_values, __pyx_n_s_edge_values, __pyx_n_s_x_gradient, __pyx_n_s_y_gradient, __pyx_n_s_bound_vertex_values, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__39)) __PYX_ERR(0, 612, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__39);
      __Pyx_GIVEREF(__pyx_tuple__39);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_37bound_vertices_below_by_quantity, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 612, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_bound_vertices_below_by_quantity, __pyx_t_1) < 0) __PYX_ERR(0, 612, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__40 = (PyObject*)__Pyx_PyCode_New(2, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__39, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_bound_vertices_below_by_quantity, 612, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__40)) __PYX_ERR(0, 612, __pyx_L1_error)

     613:

     614:   cdef object domain

     615:

     616:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     617:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     618:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     619:   cdef np.ndarray[double, ndim=1, mode="c"] x_gradient

     620:   cdef np.ndarray[double, ndim=1, mode="c"] y_gradient

     621:   cdef np.ndarray[double, ndim=2, mode="c"] bound_vertex_values

     622:

     623:   cdef keyint N

     624:   cdef int err

     625:

    +626:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 626, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     627:

    +628:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 628, __pyx_L1_error)
      __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 628, __pyx_L1_error)
      }
      __pyx_t_2 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +629:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 629, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 629, __pyx_L1_error)
      __pyx_t_7 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 629, __pyx_L1_error)
      }
      __pyx_t_7 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +630:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 630, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 630, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 630, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +631:   x_gradient = quantity.x_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_x_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 631, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 631, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_x_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_x_gradient.diminfo[0].strides = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x_gradient.diminfo[0].shape = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 631, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_x_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +632:   y_gradient = quantity.y_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_y_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 632, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 632, __pyx_L1_error)
      __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_y_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_4, __pyx_t_5, __pyx_t_6);
          }
          __pyx_t_4 = __pyx_t_5 = __pyx_t_6 = 0;
        }
        __pyx_pybuffernd_y_gradient.diminfo[0].strides = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y_gradient.diminfo[0].shape = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 632, __pyx_L1_error)
      }
      __pyx_t_10 = 0;
      __pyx_v_y_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +633:   bound_vertex_values = bounding_quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_bounding_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 633, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 633, __pyx_L1_error)
      __pyx_t_11 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_bound_vertex_values.rcbuffer->pybuffer);
        __pyx_t_3 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_bound_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_3 < 0)) {
          PyErr_Fetch(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_bound_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_bound_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_6, __pyx_t_5, __pyx_t_4);
          }
          __pyx_t_6 = __pyx_t_5 = __pyx_t_4 = 0;
        }
        __pyx_pybuffernd_bound_vertex_values.diminfo[0].strides = __pyx_pybuffernd_bound_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_bound_vertex_values.diminfo[0].shape = __pyx_pybuffernd_bound_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_bound_vertex_values.diminfo[1].strides = __pyx_pybuffernd_bound_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_bound_vertex_values.diminfo[1].shape = __pyx_pybuffernd_bound_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 633, __pyx_L1_error)
      }
      __pyx_t_11 = 0;
      __pyx_v_bound_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     634:

    +635:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     636:

    +637:   err = _bound_vertices_below_by_quantity(N,\

      __pyx_v_err = _bound_vertices_below_by_quantity(__pyx_v_N, (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_bound_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_bound_vertex_values.diminfo[0].strides, __pyx_t_13, __pyx_pybuffernd_bound_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_16, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_edge_values.diminfo[0].strides, __pyx_t_18, __pyx_pybuffernd_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_y_gradient.diminfo[0].strides))));

    +638:   										&bound_vertex_values[0,0],\

      __pyx_t_12 = 0;
      __pyx_t_13 = 0;

    +639: 										&centroid_values[0],\

      __pyx_t_14 = 0;

    +640: 										&vertex_values[0,0],\

      __pyx_t_15 = 0;
      __pyx_t_16 = 0;

    +641: 										&edge_values[0,0],\

      __pyx_t_17 = 0;
      __pyx_t_18 = 0;

    +642: 										&x_gradient[0],\

      __pyx_t_19 = 0;

    +643: 										&y_gradient[0])

      __pyx_t_20 = 0;

     644:

    +645:   assert err == 0, "Internal function _bound_vertices_below_by_quantity failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__bound_vertice_2);
          __PYX_ERR(0, 645, __pyx_L1_error)
        }
      }
      #endif

     646:

    +647: def limit_edges_by_neighbour(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_39limit_edges_by_neighbour(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_39limit_edges_by_neighbour = {"limit_edges_by_neighbour", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_39limit_edges_by_neighbour, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_39limit_edges_by_neighbour(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("limit_edges_by_neighbour (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_38limit_edges_by_neighbour(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_38limit_edges_by_neighbour(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_edge_values = 0;
      PyArrayObject *__pyx_v_neighbours = 0;
      double __pyx_v_beta_w;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_neighbours;
      __Pyx_Buffer __pyx_pybuffer_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("limit_edges_by_neighbour", 0);
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
      __pyx_pybuffer_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_neighbours.refcount = 0;
      __pyx_pybuffernd_neighbours.data = NULL;
      __pyx_pybuffernd_neighbours.rcbuffer = &__pyx_pybuffer_neighbours;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.limit_edges_by_neighbour", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_neighbours);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__41 = PyTuple_Pack(9, __pyx_n_s_quantity, __pyx_n_s_domain, __pyx_n_s_vertex_values, __pyx_n_s_centroid_values, __pyx_n_s_edge_values, __pyx_n_s_neighbours, __pyx_n_s_beta_w, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__41)) __PYX_ERR(0, 647, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__41);
      __Pyx_GIVEREF(__pyx_tuple__41);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_39limit_edges_by_neighbour, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 647, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_limit_edges_by_neighbour, __pyx_t_1) < 0) __PYX_ERR(0, 647, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_codeobj__42 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__41, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_anuga_abstract_2d_finite_volumes, __pyx_n_s_limit_edges_by_neighbour, 647, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__42)) __PYX_ERR(0, 647, __pyx_L1_error)

     648:

     649:   cdef object domain

     650:

     651:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     652:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     653:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     654:   cdef np.ndarray[long, ndim=2, mode="c"] neighbours

     655:

     656:   cdef double beta_w

     657:   cdef keyint N

     658:   cdef int err

     659:

    +660:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 660, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     661:

    +662:   beta_w = domain.beta_w

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_beta_w); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 662, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_2 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 662, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_beta_w = __pyx_t_2;

     663:

    +664:   neighbours = domain.neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 664, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 664, __pyx_L1_error)
      __pyx_t_3 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_3, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_neighbours.diminfo[0].strides = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_neighbours.diminfo[0].shape = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_neighbours.diminfo[1].strides = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_neighbours.diminfo[1].shape = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 664, __pyx_L1_error)
      }
      __pyx_t_3 = 0;
      __pyx_v_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +665:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 665, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 665, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 665, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +666:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 666, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 666, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 666, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +667:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 667, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 667, __pyx_L1_error)
      __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 667, __pyx_L1_error)
      }
      __pyx_t_10 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     668:

    +669:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     670:

    +671:   err = _limit_edges_by_neighbour(N, beta_w,\

      __pyx_v_err = _limit_edges_by_neighbour(__pyx_v_N, __pyx_v_beta_w, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_13, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_edge_values.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(long *, __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_neighbours.diminfo[0].strides, __pyx_t_17, __pyx_pybuffernd_neighbours.diminfo[1].strides))));

    +672: 								&centroid_values[0],\

      __pyx_t_11 = 0;

    +673: 								&vertex_values[0,0],\

      __pyx_t_12 = 0;
      __pyx_t_13 = 0;

    +674: 								&edge_values[0,0],\

      __pyx_t_14 = 0;
      __pyx_t_15 = 0;

    +675: 								&neighbours[0,0])

      __pyx_t_16 = 0;
      __pyx_t_17 = 0;

     676:

    +677:   assert err == 0, "Internal function _limit_edges_by_neighbour failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__limit_edges_b_2);
          __PYX_ERR(0, 677, __pyx_L1_error)
        }
      }
      #endif

     678:

    +679: def limit_gradient_by_neighbour(object quantity):

    /* Python wrapper */
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_41limit_gradient_by_neighbour(PyObject *__pyx_self, PyObject *__pyx_v_quantity); /*proto*/
    static PyMethodDef __pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_41limit_gradient_by_neighbour = {"limit_gradient_by_neighbour", (PyCFunction)__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_41limit_gradient_by_neighbour, METH_O, 0};
    static PyObject *__pyx_pw_5anuga_26abstract_2d_finite_volumes_12quantity_ext_41limit_gradient_by_neighbour(PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("limit_gradient_by_neighbour (wrapper)", 0);
      __pyx_r = __pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_40limit_gradient_by_neighbour(__pyx_self, ((PyObject *)__pyx_v_quantity));

      /* function exit code */
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_5anuga_26abstract_2d_finite_volumes_12quantity_ext_40limit_gradient_by_neighbour(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quantity) {
      PyObject *__pyx_v_domain = 0;
      PyArrayObject *__pyx_v_vertex_values = 0;
      PyArrayObject *__pyx_v_centroid_values = 0;
      PyArrayObject *__pyx_v_edge_values = 0;
      PyArrayObject *__pyx_v_x_gradient = 0;
      PyArrayObject *__pyx_v_y_gradient = 0;
      PyArrayObject *__pyx_v_neighbours = 0;
      double __pyx_v_beta_w;
      __pyx_t_5anuga_26abstract_2d_finite_volumes_12quantity_ext_keyint __pyx_v_N;
      int __pyx_v_err;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_centroid_values;
      __Pyx_Buffer __pyx_pybuffer_centroid_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_edge_values;
      __Pyx_Buffer __pyx_pybuffer_edge_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_neighbours;
      __Pyx_Buffer __pyx_pybuffer_neighbours;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_vertex_values;
      __Pyx_Buffer __pyx_pybuffer_vertex_values;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_x_gradient;
      __Pyx_Buffer __pyx_pybuffer_x_gradient;
      __Pyx_LocalBuf_ND __pyx_pybuffernd_y_gradient;
      __Pyx_Buffer __pyx_pybuffer_y_gradient;
      PyObject *__pyx_r = NULL;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("limit_gradient_by_neighbour", 0);
      __pyx_pybuffer_vertex_values.pybuffer.buf = NULL;
      __pyx_pybuffer_vertex_values.refcount = 0;
      __pyx_pybuffernd_vertex_values.data = NULL;
      __pyx_pybuffernd_vertex_values.rcbuffer = &__pyx_pybuffer_vertex_values;
      __pyx_pybuffer_centroid_values.pybuffer.buf = NULL;
      __pyx_pybuffer_centroid_values.refcount = 0;
      __pyx_pybuffernd_centroid_values.data = NULL;
      __pyx_pybuffernd_centroid_values.rcbuffer = &__pyx_pybuffer_centroid_values;
      __pyx_pybuffer_edge_values.pybuffer.buf = NULL;
      __pyx_pybuffer_edge_values.refcount = 0;
      __pyx_pybuffernd_edge_values.data = NULL;
      __pyx_pybuffernd_edge_values.rcbuffer = &__pyx_pybuffer_edge_values;
      __pyx_pybuffer_x_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_x_gradient.refcount = 0;
      __pyx_pybuffernd_x_gradient.data = NULL;
      __pyx_pybuffernd_x_gradient.rcbuffer = &__pyx_pybuffer_x_gradient;
      __pyx_pybuffer_y_gradient.pybuffer.buf = NULL;
      __pyx_pybuffer_y_gradient.refcount = 0;
      __pyx_pybuffernd_y_gradient.data = NULL;
      __pyx_pybuffernd_y_gradient.rcbuffer = &__pyx_pybuffer_y_gradient;
      __pyx_pybuffer_neighbours.pybuffer.buf = NULL;
      __pyx_pybuffer_neighbours.refcount = 0;
      __pyx_pybuffernd_neighbours.data = NULL;
      __pyx_pybuffernd_neighbours.rcbuffer = &__pyx_pybuffer_neighbours;
    /* … */
      /* function exit code */
      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
      __Pyx_AddTraceback("anuga.abstract_2d_finite_volumes.quantity_ext.limit_gradient_by_neighbour", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      goto __pyx_L2;
      __pyx_L0:;
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
      __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
      __pyx_L2:;
      __Pyx_XDECREF(__pyx_v_domain);
      __Pyx_XDECREF((PyObject *)__pyx_v_vertex_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_centroid_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_edge_values);
      __Pyx_XDECREF((PyObject *)__pyx_v_x_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_y_gradient);
      __Pyx_XDECREF((PyObject *)__pyx_v_neighbours);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }
    /* … */
      __pyx_tuple__43 = PyTuple_Pack(11, __pyx_n_s_quantity, __pyx_n_s_domain, __pyx_n_s_vertex_values, __pyx_n_s_centroid_values, __pyx_n_s_edge_values, __pyx_n_s_x_gradient, __pyx_n_s_y_gradient, __pyx_n_s_neighbours, __pyx_n_s_beta_w, __pyx_n_s_N, __pyx_n_s_err); if (unlikely(!__pyx_tuple__43)) __PYX_ERR(0, 679, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_tuple__43);
      __Pyx_GIVEREF(__pyx_tuple__43);
    /* … */
      __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5anuga_26abstract_2d_finite_volumes_12quantity_ext_41limit_gradient_by_neighbour, NULL, __pyx_n_s_anuga_abstract_2d_finite_volumes_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 679, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_limit_gradient_by_neighbour, __pyx_t_1) < 0) __PYX_ERR(0, 679, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

     680:

     681:   cdef object domain

     682:

     683:   cdef np.ndarray[double, ndim=2, mode="c"] vertex_values

     684:   cdef np.ndarray[double, ndim=1, mode="c"] centroid_values

     685:   cdef np.ndarray[double, ndim=2, mode="c"] edge_values

     686:   cdef np.ndarray[double, ndim=1, mode="c"] x_gradient

     687:   cdef np.ndarray[double, ndim=1, mode="c"] y_gradient

     688:   cdef np.ndarray[long, ndim=2, mode="c"] neighbours

     689:

     690:   cdef double beta_w

     691:   cdef keyint N

     692:   cdef int err

     693:

    +694:   domain = quantity.domain

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_domain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 694, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_v_domain = __pyx_t_1;
      __pyx_t_1 = 0;

     695:

    +696:   beta_w = domain.beta_w

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_beta_w); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 696, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_2 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 696, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_beta_w = __pyx_t_2;

     697:

    +698:   neighbours = domain.neighbours

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_domain, __pyx_n_s_neighbours); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 698, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 698, __pyx_L1_error)
      __pyx_t_3 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_t_3, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_neighbours.rcbuffer->pybuffer, (PyObject*)__pyx_v_neighbours, &__Pyx_TypeInfo_long, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_neighbours.diminfo[0].strides = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_neighbours.diminfo[0].shape = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_neighbours.diminfo[1].strides = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_neighbours.diminfo[1].shape = __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 698, __pyx_L1_error)
      }
      __pyx_t_3 = 0;
      __pyx_v_neighbours = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +699:   centroid_values = quantity.centroid_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_centroid_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 699, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 699, __pyx_L1_error)
      __pyx_t_8 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_centroid_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_centroid_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_centroid_values.diminfo[0].strides = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_centroid_values.diminfo[0].shape = __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 699, __pyx_L1_error)
      }
      __pyx_t_8 = 0;
      __pyx_v_centroid_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +700:   vertex_values = quantity.vertex_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_vertex_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 700, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 700, __pyx_L1_error)
      __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertex_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertex_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_vertex_values.diminfo[0].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertex_values.diminfo[0].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertex_values.diminfo[1].strides = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertex_values.diminfo[1].shape = __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 700, __pyx_L1_error)
      }
      __pyx_t_9 = 0;
      __pyx_v_vertex_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +701:   edge_values = quantity.edge_values

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_edge_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 701, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 701, __pyx_L1_error)
      __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_edge_values.rcbuffer->pybuffer, (PyObject*)__pyx_v_edge_values, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_edge_values.diminfo[0].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_edge_values.diminfo[0].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_edge_values.diminfo[1].strides = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_edge_values.diminfo[1].shape = __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.shape[1];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 701, __pyx_L1_error)
      }
      __pyx_t_10 = 0;
      __pyx_v_edge_values = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +702:   x_gradient = quantity.x_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_x_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 702, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 702, __pyx_L1_error)
      __pyx_t_11 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_x_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
          }
          __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
        }
        __pyx_pybuffernd_x_gradient.diminfo[0].strides = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x_gradient.diminfo[0].shape = __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 702, __pyx_L1_error)
      }
      __pyx_t_11 = 0;
      __pyx_v_x_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +703:   y_gradient = quantity.y_gradient

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_quantity, __pyx_n_s_y_gradient); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 703, __pyx_L1_error)
      __pyx_t_12 = ((PyArrayObject *)__pyx_t_1);
      {
        __Pyx_BufFmt_StackElem __pyx_stack[1];
        __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer);
        __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_t_12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack);
        if (unlikely(__pyx_t_4 < 0)) {
          PyErr_Fetch(&__pyx_t_7, &__pyx_t_6, &__pyx_t_5);
          if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y_gradient.rcbuffer->pybuffer, (PyObject*)__pyx_v_y_gradient, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {
            Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_7, __pyx_t_6, __pyx_t_5);
          }
          __pyx_t_7 = __pyx_t_6 = __pyx_t_5 = 0;
        }
        __pyx_pybuffernd_y_gradient.diminfo[0].strides = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y_gradient.diminfo[0].shape = __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.shape[0];
        if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 703, __pyx_L1_error)
      }
      __pyx_t_12 = 0;
      __pyx_v_y_gradient = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     704:

    +705:   N = centroid_values.shape[0]

      __pyx_v_N = (__pyx_v_centroid_values->dimensions[0]);

     706:

    +707:   err = _limit_gradient_by_neighbour(N, beta_w,\

      __pyx_v_err = _limit_gradient_by_neighbour(__pyx_v_N, __pyx_v_beta_w, (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_centroid_values.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_centroid_values.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_vertex_values.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_vertex_values.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_vertex_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(double *, __pyx_pybuffernd_edge_values.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_edge_values.diminfo[0].strides, __pyx_t_17, __pyx_pybuffernd_edge_values.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_x_gradient.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_x_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig1d(double *, __pyx_pybuffernd_y_gradient.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_y_gradient.diminfo[0].strides))), (&(*__Pyx_BufPtrCContig2d(long *, __pyx_pybuffernd_neighbours.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_neighbours.diminfo[0].strides, __pyx_t_21, __pyx_pybuffernd_neighbours.diminfo[1].strides))));

    +708: 								&centroid_values[0],\

      __pyx_t_13 = 0;

    +709: 								&vertex_values[0,0],\

      __pyx_t_14 = 0;
      __pyx_t_15 = 0;

    +710: 								&edge_values[0,0],\

      __pyx_t_16 = 0;
      __pyx_t_17 = 0;

    +711: 								&x_gradient[0],\

      __pyx_t_18 = 0;

    +712: 								&y_gradient[0],\

      __pyx_t_19 = 0;

    +713: 								&neighbours[0,0])

      __pyx_t_20 = 0;
      __pyx_t_21 = 0;

     714:

    +715:   assert err == 0, "Internal function _limit_gradient_by_neighbour failed"

      #ifndef CYTHON_WITHOUT_ASSERTIONS
      if (unlikely(!Py_OptimizeFlag)) {
        if (unlikely(!((__pyx_v_err == 0) != 0))) {
          PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_Internal_function__limit_gradien);
          __PYX_ERR(0, 715, __pyx_L1_error)
        }
      }
      #endif

     716: