Ignore:
Timestamp:
May 13, 2005, 6:15:08 PM (20 years ago)
Author:
steve
Message:

Need to look at uint test for inscribed circle

File:
1 edited

Legend:

Unmodified
Added
Removed
  • inundation/ga/storm_surge/pyvolution/shallow_water_ext.c

    r1017 r1387  
    22//
    33// To compile (Python2.3):
    4 //  gcc -c domain_ext.c -I/usr/include/python2.3 -o domain_ext.o -Wall -O 
    5 //  gcc -shared domain_ext.o  -o domain_ext.so 
     4//  gcc -c domain_ext.c -I/usr/include/python2.3 -o domain_ext.o -Wall -O
     5//  gcc -shared domain_ext.o  -o domain_ext.so
    66//
    77// or use python compile.py
     
    1111//
    1212// Ole Nielsen, GA 2004
    13    
    14    
     13
     14
    1515#include "Python.h"
    1616#include "Numeric/arrayobject.h"
    1717#include "math.h"
     18#include <stdio.h>
    1819
    1920//Shared code snippets
     
    2627  /*Rotate the momentum component q (q[1], q[2])
    2728    from x,y coordinates to coordinates based on normal vector (n1, n2).
    28    
    29     Result is returned in array 3x1 r     
     29
     30    Result is returned in array 3x1 r
    3031    To rotate in opposite direction, call rotate with (q, n1, -n2)
    31    
    32     Contents of q are changed by this function */   
     32
     33    Contents of q are changed by this function */
    3334
    3435
    3536  double q1, q2;
    36  
     37
    3738  //Shorthands
    3839  q1 = q[1];  //uh momentum
     
    4142  //Rotate
    4243  q[1] =  n1*q1 + n2*q2;
    43   q[2] = -n2*q1 + n1*q2; 
     44  q[2] = -n2*q1 + n1*q2;
    4445
    4546  return 0;
    46 } 
    47 
    48 
    49        
     47}
     48
     49
     50
    5051// Computational function for flux computation (using stage w=z+h)
    51 int flux_function(double *q_left, double *q_right, 
    52                   double z_left, double z_right, 
    53                   double n1, double n2, 
    54                   double epsilon, double g, 
     52int flux_function(double *q_left, double *q_right,
     53                  double z_left, double z_right,
     54                  double n1, double n2,
     55                  double epsilon, double g,
    5556                  double *edgeflux, double *max_speed) {
    56  
     57
    5758  /*Compute fluxes between volumes for the shallow water wave equation
    58     cast in terms of the 'stage', w = h+z using 
     59    cast in terms of the 'stage', w = h+z using
    5960    the 'central scheme' as described in
    60    
     61
    6162    Kurganov, Noelle, Petrova. 'Semidiscrete Central-Upwind Schemes For
    6263    Hyperbolic Conservation Laws and Hamilton-Jacobi Equations'.
    6364    Siam J. Sci. Comput. Vol. 23, No. 3, pp. 707-740.
    64    
    65     The implemented formula is given in equation (3.15) on page 714 
     65
     66    The implemented formula is given in equation (3.15) on page 714
    6667  */
    67        
     68
    6869  int i;
    69        
     70
    7071  double w_left, h_left, uh_left, vh_left, u_left;
    7172  double w_right, h_right, uh_right, vh_right, u_right;
    7273  double s_min, s_max, soundspeed_left, soundspeed_right;
    7374  double denom, z;
    74   double q_left_copy[3], q_right_copy[3];   
     75  double q_left_copy[3], q_right_copy[3];
    7576  double flux_right[3], flux_left[3];
    76  
     77
    7778  //Copy conserved quantities to protect from modification
    7879  for (i=0; i<3; i++) {
    7980    q_left_copy[i] = q_left[i];
    8081    q_right_copy[i] = q_right[i];
    81   } 
    82    
     82  }
     83
    8384  //Align x- and y-momentum with x-axis
    8485  _rotate(q_left_copy, n1, n2);
    85   _rotate(q_right_copy, n1, n2);   
     86  _rotate(q_right_copy, n1, n2);
    8687
    8788  z = (z_left+z_right)/2; //Take average of field values
     
    9596    h_left = 0.0;  //Could have been negative
    9697    u_left = 0.0;
    97   } else { 
     98  } else {
    9899    u_left = uh_left/h_left;
    99100  }
    100  
     101
    101102  w_right = q_right_copy[0];
    102103  h_right = w_right-z;
     
    106107    h_right = 0.0; //Could have been negative
    107108    u_right = 0.0;
    108   } else { 
     109  } else {
    109110    u_right = uh_right/h_right;
    110111  }
    111112
    112   //Momentum in y-direction             
     113  //Momentum in y-direction
    113114  vh_left  = q_left_copy[2];
    114   vh_right = q_right_copy[2];   
    115        
     115  vh_right = q_right_copy[2];
     116
    116117
    117118  //Maximal and minimal wave speeds
    118   soundspeed_left  = sqrt(g*h_left); 
     119  soundspeed_left  = sqrt(g*h_left);
    119120  soundspeed_right = sqrt(g*h_right);
    120    
     121
    121122  s_max = max(u_left+soundspeed_left, u_right+soundspeed_right);
    122   if (s_max < 0.0) s_max = 0.0; 
    123  
     123  if (s_max < 0.0) s_max = 0.0;
     124
    124125  s_min = min(u_left-soundspeed_left, u_right-soundspeed_right);
    125   if (s_min > 0.0) s_min = 0.0;   
    126  
    127   //Flux formulas 
     126  if (s_min > 0.0) s_min = 0.0;
     127
     128  //Flux formulas
    128129  flux_left[0] = u_left*h_left;
    129130  flux_left[1] = u_left*uh_left + 0.5*g*h_left*h_left;
    130131  flux_left[2] = u_left*vh_left;
    131  
     132
    132133  flux_right[0] = u_right*h_right;
    133134  flux_right[1] = u_right*uh_right + 0.5*g*h_right*h_right;
    134135  flux_right[2] = u_right*vh_right;
    135    
    136 
    137   //Flux computation   
     136
     137
     138  //Flux computation
    138139  denom = s_max-s_min;
    139140  if (denom == 0.0) {
    140141    for (i=0; i<3; i++) edgeflux[i] = 0.0;
    141142    *max_speed = 0.0;
    142   } else {   
     143  } else {
    143144    for (i=0; i<3; i++) {
    144145      edgeflux[i] = s_max*flux_left[i] - s_min*flux_right[i];
    145146      edgeflux[i] += s_max*s_min*(q_right_copy[i]-q_left_copy[i]);
    146147      edgeflux[i] /= denom;
    147     } 
    148        
     148    }
     149
    149150    //Maximal wavespeed
    150151    *max_speed = max(fabs(s_max), fabs(s_min));
    151    
    152     //Rotate back       
     152
     153    //Rotate back
    153154    _rotate(edgeflux, n1, -n2);
    154155  }
    155156  return 0;
    156157}
    157        
    158 void _manning_friction(double g, double eps, int N, 
    159                        double* w, double* z, 
    160                        double* uh, double* vh, 
    161                        double* eta, double* xmom, double* ymom) {     
     158
     159void _manning_friction(double g, double eps, int N,
     160                       double* w, double* z,
     161                       double* uh, double* vh,
     162                       double* eta, double* xmom, double* ymom) {
    162163
    163164  int k;
    164165  double S, h;
    165  
     166
    166167  for (k=0; k<N; k++) {
    167168    if (eta[k] > eps) {
     
    180181  }
    181182}
    182            
     183
    183184
    184185
    185186int _balance_deep_and_shallow(int N,
    186187                              double* wc,
    187                               double* zc, 
    188                               double* hc,                             
    189                               double* wv, 
    190                               double* zv, 
     188                              double* zc,
     189                              double* hc,
     190                              double* wv,
     191                              double* zv,
    191192                              double* hv,
    192                               double* hvbar,                         
    193                               double* xmomc, 
    194                               double* ymomc, 
    195                               double* xmomv, 
    196                               double* ymomv) { 
    197  
     193                              double* hvbar,
     194                              double* xmomc,
     195                              double* ymomc,
     196                              double* xmomv,
     197                              double* ymomv) {
     198
    198199  int k, k3, i;
    199200  double dz, hmin, alpha;
    200  
     201
    201202  //Compute linear combination between w-limited stages and
    202   //h-limited stages close to the bed elevation.     
    203  
     203  //h-limited stages close to the bed elevation.
     204
    204205  for (k=0; k<N; k++) {
    205206    // Compute maximal variation in bed elevation
     
    211212
    212213    k3 = 3*k;
    213    
     214
    214215    //FIXME: Try with this one precomputed
    215216    dz = 0.0;
     
    220221    }
    221222
    222    
    223     //Create alpha in [0,1], where alpha==0 means using the h-limited 
     223
     224    //Create alpha in [0,1], where alpha==0 means using the h-limited
    224225    //stage and alpha==1 means using the w-limited stage as
    225226    //computed by the gradient limiter (both 1st or 2nd order)
     
    227228    //If hmin > dz/2 then alpha = 1 and the bed will have no effect
    228229    //If hmin < 0 then alpha = 0 reverting to constant height above bed.
    229    
     230
    230231
    231232    if (dz > 0.0)
    232       //if (hmin<0.0) 
     233      //if (hmin<0.0)
    233234      //        alpha = 0.0;
    234235      //else
    235236      //  alpha = max( min( hc[k]/dz, 1.0), 0.0 );
    236237      alpha = max( min( 2.0*hmin/dz, 1.0), 0.0 );
    237    
    238238    else
    239239      alpha = 1.0;  //Flat bed
    240240
     241    //alpha = 1.0;
     242
    241243    //printf("dz = %.3f, alpha = %.8f\n", dz, alpha);
    242244
    243     //  Let 
    244     // 
    245     //    wvi be the w-limited stage (wvi = zvi + hvi)       
     245    //  Let
     246    //
     247    //    wvi be the w-limited stage (wvi = zvi + hvi)
    246248    //    wvi- be the h-limited state (wvi- = zvi + hvi-)
    247     //     
    248     //     
     249    //
     250    //
    249251    //  where i=0,1,2 denotes the vertex ids
    250     // 
    251     //  Weighted balance between w-limited and h-limited stage is 
    252     //   
    253     //    wvi := (1-alpha)*(zvi+hvi-) + alpha*(zvi+hvi)   
    254     // 
     252    //
     253    //  Weighted balance between w-limited and h-limited stage is
     254    //
     255    //    wvi := (1-alpha)*(zvi+hvi-) + alpha*(zvi+hvi)
     256    //
    255257    //  It follows that the updated wvi is
    256258    //    wvi := zvi + (1-alpha)*hvi- + alpha*hvi
    257     //   
     259    //
    258260    //   Momentum is balanced between constant and limited
    259261
    260     if (alpha < 1) {         
     262    if (alpha < 1) {
    261263      for (i=0; i<3; i++) {
    262264        wv[k3+i] = zv[k3+i] + (1-alpha)*hvbar[k3+i] + alpha*hv[k3+i];
    263            
    264         //Update momentum as a linear combination of 
     265
     266        //Update momentum as a linear combination of
    265267        //xmomc and ymomc (shallow) and momentum
    266268        //from extrapolator xmomv and ymomv (deep).
    267         xmomv[k3+i] = (1-alpha)*xmomc[k] + alpha*xmomv[k3+i];           
     269        xmomv[k3+i] = (1-alpha)*xmomc[k] + alpha*xmomv[k3+i];
    268270        ymomv[k3+i] = (1-alpha)*ymomc[k] + alpha*ymomv[k3+i];
    269       } 
     271      }
    270272    }
    271   }         
     273  }
    272274  return 0;
    273275}
     
    275277
    276278
    277 int _protect(int N, 
    278              double minimum_allowed_height,       
     279int _protect(int N,
     280             double minimum_allowed_height,
    279281             double* wc,
    280              double* zc, 
    281              double* xmomc, 
     282             double* zc,
     283             double* xmomc,
    282284             double* ymomc) {
    283  
    284   int k; 
     285
     286  int k;
    285287  double hc;
    286  
     288
    287289  //Protect against initesimal and negative heights
    288  
     290
    289291  for (k=0; k<N; k++) {
    290292    hc = wc[k] - zc[k];
    291    
    292     if (hc < minimum_allowed_height) {   
    293       wc[k] = zc[k];       
     293
     294    if (hc < minimum_allowed_height) {
     295      wc[k] = zc[k];
    294296      xmomc[k] = 0.0;
    295       ymomc[k] = 0.0;     
     297      ymomc[k] = 0.0;
    296298    }
    297    
     299
    298300  }
    299301  return 0;
     
    309311int _assign_wind_field_values(int N,
    310312                              double* xmom_update,
    311                               double* ymom_update, 
     313                              double* ymom_update,
    312314                              double* s_vec,
    313315                              double* phi_vec,
     
    318320  int k;
    319321  double S, s, phi, u, v;
    320  
     322
    321323  for (k=0; k<N; k++) {
    322    
     324
    323325    s = s_vec[k];
    324326    phi = phi_vec[k];
     
    330332    u = s*cos(phi);
    331333    v = s*sin(phi);
    332        
     334
    333335    //Compute wind stress
    334336    S = cw * sqrt(u*u + v*v);
    335337    xmom_update[k] += S*u;
    336     ymom_update[k] += S*v;       
    337   }
    338   return 0; 
    339 }           
     338    ymom_update[k] += S*v;
     339  }
     340  return 0;
     341}
    340342
    341343
     
    348350  //  gravity(g, h, v, x, xmom, ymom)
    349351  //
    350  
    351  
     352
     353
    352354  PyArrayObject *h, *v, *x, *xmom, *ymom;
    353355  int k, i, N, k3, k6;
    354356  double g, avg_h, zx, zy;
    355357  double x0, y0, x1, y1, x2, y2, z0, z1, z2;
    356    
     358
    357359  if (!PyArg_ParseTuple(args, "dOOOOO",
    358                         &g, &h, &v, &x, 
    359                         &xmom, &ymom)) 
    360     return NULL; 
     360                        &g, &h, &v, &x,
     361                        &xmom, &ymom))
     362    return NULL;
    361363
    362364  N = h -> dimensions[0];
    363365  for (k=0; k<N; k++) {
    364366    k3 = 3*k;  // base index
    365     k6 = 6*k;  // base index   
    366    
     367    k6 = 6*k;  // base index
     368
    367369    avg_h = 0.0;
    368370    for (i=0; i<3; i++) {
    369371      avg_h += ((double *) h -> data)[k3+i];
    370     }   
     372    }
    371373    avg_h /= 3;
    372        
    373    
     374
     375
    374376    //Compute bed slope
    375377    x0 = ((double*) x -> data)[k6 + 0];
    376     y0 = ((double*) x -> data)[k6 + 1];   
     378    y0 = ((double*) x -> data)[k6 + 1];
    377379    x1 = ((double*) x -> data)[k6 + 2];
    378     y1 = ((double*) x -> data)[k6 + 3];       
     380    y1 = ((double*) x -> data)[k6 + 3];
    379381    x2 = ((double*) x -> data)[k6 + 4];
    380     y2 = ((double*) x -> data)[k6 + 5];           
     382    y2 = ((double*) x -> data)[k6 + 5];
    381383
    382384
    383385    z0 = ((double*) v -> data)[k3 + 0];
    384386    z1 = ((double*) v -> data)[k3 + 1];
    385     z2 = ((double*) v -> data)[k3 + 2];       
     387    z2 = ((double*) v -> data)[k3 + 2];
    386388
    387389    _gradient(x0, y0, x1, y1, x2, y2, z0, z1, z2, &zx, &zy);
     
    389391    //Update momentum
    390392    ((double*) xmom -> data)[k] += -g*zx*avg_h;
    391     ((double*) ymom -> data)[k] += -g*zy*avg_h;       
    392   }
    393    
     393    ((double*) ymom -> data)[k] += -g*zy*avg_h;
     394  }
     395
    394396  return Py_BuildValue("");
    395397}
     
    400402  // manning_friction(g, eps, h, uh, vh, eta, xmom_update, ymom_update)
    401403  //
    402  
    403  
     404
     405
    404406  PyArrayObject *w, *z, *uh, *vh, *eta, *xmom, *ymom;
    405407  int N;
    406408  double g, eps;
    407    
     409
    408410  if (!PyArg_ParseTuple(args, "ddOOOOOOO",
    409                         &g, &eps, &w, &z, &uh, &vh, &eta, 
    410                         &xmom, &ymom)) 
    411     return NULL; 
    412 
    413   N = w -> dimensions[0];   
     411                        &g, &eps, &w, &z, &uh, &vh, &eta,
     412                        &xmom, &ymom))
     413    return NULL;
     414
     415  N = w -> dimensions[0];
    414416  _manning_friction(g, eps, N,
    415417                    (double*) w -> data,
    416                     (double*) z -> data,                   
    417                     (double*) uh -> data, 
    418                     (double*) vh -> data, 
     418                    (double*) z -> data,
     419                    (double*) uh -> data,
     420                    (double*) vh -> data,
    419421                    (double*) eta -> data,
    420                     (double*) xmom -> data, 
     422                    (double*) xmom -> data,
    421423                    (double*) ymom -> data);
    422424
    423425  return Py_BuildValue("");
    424 }                   
     426}
    425427
    426428PyObject *rotate(PyObject *self, PyObject *args, PyObject *kwargs) {
     
    431433  // normal a Float numeric array of length 2.
    432434
    433  
     435
    434436  PyObject *Q, *Normal;
    435437  PyArrayObject *q, *r, *normal;
    436  
     438
    437439  static char *argnames[] = {"q", "normal", "direction", NULL};
    438440  int dimensions[1], i, direction=1;
    439441  double n1, n2;
    440442
    441   // Convert Python arguments to C 
    442   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i", argnames, 
    443                                    &Q, &Normal, &direction)) 
    444     return NULL; 
     443  // Convert Python arguments to C
     444  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i", argnames,
     445                                   &Q, &Normal, &direction))
     446    return NULL;
    445447
    446448  //Input checks (convert sequences into numeric arrays)
    447   q = (PyArrayObject *) 
     449  q = (PyArrayObject *)
    448450    PyArray_ContiguousFromObject(Q, PyArray_DOUBLE, 0, 0);
    449   normal = (PyArrayObject *) 
     451  normal = (PyArrayObject *)
    450452    PyArray_ContiguousFromObject(Normal, PyArray_DOUBLE, 0, 0);
    451453
    452  
     454
    453455  if (normal -> dimensions[0] != 2) {
    454456    PyErr_SetString(PyExc_RuntimeError, "Normal vector must have 2 components");
     
    456458  }
    457459
    458   //Allocate space for return vector r (don't DECREF) 
     460  //Allocate space for return vector r (don't DECREF)
    459461  dimensions[0] = 3;
    460462  r = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE);
     
    462464  //Copy
    463465  for (i=0; i<3; i++) {
    464     ((double *) (r -> data))[i] = ((double *) (q -> data))[i]; 
    465   }
    466  
     466    ((double *) (r -> data))[i] = ((double *) (q -> data))[i];
     467  }
     468
    467469  //Get normal and direction
    468   n1 = ((double *) normal -> data)[0]; 
    469   n2 = ((double *) normal -> data)[1];   
     470  n1 = ((double *) normal -> data)[0];
     471  n2 = ((double *) normal -> data)[1];
    470472  if (direction == -1) n2 = -n2;
    471473
     
    474476
    475477  //Release numeric arrays
    476   Py_DECREF(q);   
     478  Py_DECREF(q);
    477479  Py_DECREF(normal);
    478        
     480
    479481  //return result using PyArray to avoid memory leak
    480482  return PyArray_Return(r);
    481 }   
     483}
    482484
    483485
     
    490492    Fluxes across each edge are scaled by edgelengths and summed up
    491493    Resulting flux is then scaled by area and stored in
    492     explicit_update for each of the three conserved quantities 
     494    explicit_update for each of the three conserved quantities
    493495    stage, xmomentum and ymomentum
    494496
     
    496498    is converted to a timestep that must not be exceeded. The minimum of
    497499    those is computed as the next overall timestep.
    498    
     500
    499501    Python call:
    500     domain.timestep = compute_fluxes(timestep, 
    501                                      domain.epsilon, 
     502    domain.timestep = compute_fluxes(timestep,
     503                                     domain.epsilon,
    502504                                     domain.g,
    503505                                     domain.neighbours,
    504506                                     domain.neighbour_edges,
    505507                                     domain.normals,
    506                                      domain.edgelengths,                       
     508                                     domain.edgelengths,
    507509                                     domain.radii,
    508510                                     domain.areas,
    509                                      Stage.edge_values, 
    510                                      Xmom.edge_values, 
    511                                      Ymom.edge_values, 
    512                                      Bed.edge_values,   
     511                                     Stage.edge_values,
     512                                     Xmom.edge_values,
     513                                     Ymom.edge_values,
     514                                     Bed.edge_values,
    513515                                     Stage.boundary_values,
    514516                                     Xmom.boundary_values,
     
    517519                                     Xmom.explicit_update,
    518520                                     Ymom.explicit_update)
    519        
     521
    520522
    521523    Post conditions:
    522524      domain.explicit_update is reset to computed flux values
    523       domain.timestep is set to the largest step satisfying all volumes. 
    524 
    525            
     525      domain.timestep is set to the largest step satisfying all volumes.
     526
     527
    526528  */
    527529
    528  
     530
    529531  PyArrayObject *neighbours, *neighbour_edges,
    530532    *normals, *edgelengths, *radii, *areas,
    531     *stage_edge_values, 
    532     *xmom_edge_values, 
    533     *ymom_edge_values, 
    534     *bed_edge_values,   
     533    *stage_edge_values,
     534    *xmom_edge_values,
     535    *ymom_edge_values,
     536    *bed_edge_values,
    535537    *stage_boundary_values,
    536538    *xmom_boundary_values,
     
    540542    *ymom_explicit_update;
    541543
    542    
    543   //Local variables 
     544
     545  //Local variables
    544546  double timestep, max_speed, epsilon, g;
    545547  double normal[2], ql[3], qr[3], zl, zr;
     
    548550  int number_of_elements, k, i, j, m, n;
    549551  int ki, nm, ki2; //Index shorthands
    550  
    551  
    552   // Convert Python arguments to C 
     552
     553
     554  // Convert Python arguments to C
    553555  if (!PyArg_ParseTuple(args, "dddOOOOOOOOOOOOOOOO",
    554556                        &timestep,
    555557                        &epsilon,
    556558                        &g,
    557                         &neighbours, 
     559                        &neighbours,
    558560                        &neighbour_edges,
    559                         &normals, 
     561                        &normals,
    560562                        &edgelengths, &radii, &areas,
    561                         &stage_edge_values, 
    562                         &xmom_edge_values, 
    563                         &ymom_edge_values, 
    564                         &bed_edge_values,   
     563                        &stage_edge_values,
     564                        &xmom_edge_values,
     565                        &ymom_edge_values,
     566                        &bed_edge_values,
    565567                        &stage_boundary_values,
    566568                        &xmom_boundary_values,
     
    574576
    575577  number_of_elements = stage_edge_values -> dimensions[0];
    576  
    577    
     578
     579
    578580  for (k=0; k<number_of_elements; k++) {
    579581
    580582    //Reset work array
    581583    for (j=0; j<3; j++) flux[j] = 0.0;
    582                          
     584
    583585    //Loop through neighbours and compute edge flux for each
    584586    for (i=0; i<3; i++) {
     
    586588      ql[0] = ((double *) stage_edge_values -> data)[ki];
    587589      ql[1] = ((double *) xmom_edge_values -> data)[ki];
    588       ql[2] = ((double *) ymom_edge_values -> data)[ki];           
    589       zl =    ((double *) bed_edge_values -> data)[ki];                 
     590      ql[2] = ((double *) ymom_edge_values -> data)[ki];
     591      zl =    ((double *) bed_edge_values -> data)[ki];
    590592
    591593      //Quantities at neighbour on nearest face
     
    593595      if (n < 0) {
    594596        m = -n-1; //Convert negative flag to index
    595         qr[0] = ((double *) stage_boundary_values -> data)[m]; 
    596         qr[1] = ((double *) xmom_boundary_values -> data)[m];   
    597         qr[2] = ((double *) ymom_boundary_values -> data)[m];   
     597        qr[0] = ((double *) stage_boundary_values -> data)[m];
     598        qr[1] = ((double *) xmom_boundary_values -> data)[m];
     599        qr[2] = ((double *) ymom_boundary_values -> data)[m];
    598600        zr = zl; //Extend bed elevation to boundary
    599       } else {   
     601      } else {
    600602        m = ((long *) neighbour_edges -> data)[ki];
    601        
    602         nm = n*3+m;     
     603
     604        nm = n*3+m;
    603605        qr[0] = ((double *) stage_edge_values -> data)[nm];
    604606        qr[1] = ((double *) xmom_edge_values -> data)[nm];
    605         qr[2] = ((double *) ymom_edge_values -> data)[nm];           
    606         zr =    ((double *) bed_edge_values -> data)[nm];                 
     607        qr[2] = ((double *) ymom_edge_values -> data)[nm];
     608        zr =    ((double *) bed_edge_values -> data)[nm];
    607609      }
    608610
    609611      //printf("%d %d [%d] (%d, %d): %.2f %.2f %.2f\n", k, i, ki, n, m,
    610       //             ql[0], ql[1], ql[2]);       
    611 
    612      
    613       // Outward pointing normal vector   
     612      //             ql[0], ql[1], ql[2]);
     613
     614
     615      // Outward pointing normal vector
    614616      // normal = domain.normals[k, 2*i:2*i+2]
    615617      ki2 = 2*ki; //k*6 + i*2
    616618      normal[0] = ((double *) normals -> data)[ki2];
    617       normal[1] = ((double *) normals -> data)[ki2+1];     
     619      normal[1] = ((double *) normals -> data)[ki2+1];
    618620
    619621      //Edge flux computation
    620       flux_function(ql, qr, zl, zr, 
     622      flux_function(ql, qr, zl, zr,
    621623                    normal[0], normal[1],
    622                     epsilon, g, 
     624                    epsilon, g,
    623625                    edgeflux, &max_speed);
    624626
    625                    
     627
    626628      //flux -= edgeflux * edgelengths[k,i]
    627       for (j=0; j<3; j++) { 
     629      for (j=0; j<3; j++) {
    628630        flux[j] -= edgeflux[j]*((double *) edgelengths -> data)[ki];
    629631      }
    630      
     632
    631633      //Update timestep
    632634      //timestep = min(timestep, domain.radii[k]/max_speed)
     
    634636      if (max_speed > epsilon) {
    635637        timestep = min(timestep, ((double *) radii -> data)[k]/max_speed);
    636       }   
     638      }
    637639    } // end for i
    638    
     640
    639641    //Normalise by area and store for when all conserved
    640642    //quantities get updated
    641643    // flux /= areas[k]
    642     for (j=0; j<3; j++) { 
     644    for (j=0; j<3; j++) {
    643645      flux[j] /= ((double *) areas -> data)[k];
    644646    }
     
    646648    ((double *) stage_explicit_update -> data)[k] = flux[0];
    647649    ((double *) xmom_explicit_update -> data)[k] = flux[1];
    648     ((double *) ymom_explicit_update -> data)[k] = flux[2];       
     650    ((double *) ymom_explicit_update -> data)[k] = flux[2];
    649651
    650652  } //end for k
    651653
    652654  return Py_BuildValue("d", timestep);
    653 }   
     655}
    654656
    655657
     
    658660  //
    659661  //    protect(minimum_allowed_height, wc, zc, xmomc, ymomc)
    660  
    661 
    662   PyArrayObject 
     662
     663
     664  PyArrayObject
    663665  *wc,            //Stage at centroids
    664   *zc,            //Elevation at centroids   
     666  *zc,            //Elevation at centroids
    665667  *xmomc,         //Momentums at centroids
    666   *ymomc; 
    667 
    668    
    669   int N; 
     668  *ymomc;
     669
     670
     671  int N;
    670672  double minimum_allowed_height;
    671  
    672   // Convert Python arguments to C 
    673   if (!PyArg_ParseTuple(args, "dOOOO", 
     673
     674  // Convert Python arguments to C
     675  if (!PyArg_ParseTuple(args, "dOOOO",
    674676                        &minimum_allowed_height,
    675677                        &wc, &zc, &xmomc, &ymomc))
     
    677679
    678680  N = wc -> dimensions[0];
    679    
     681
    680682  _protect(N,
    681683           minimum_allowed_height,
    682684           (double*) wc -> data,
    683            (double*) zc -> data, 
    684            (double*) xmomc -> data, 
     685           (double*) zc -> data,
     686           (double*) xmomc -> data,
    685687           (double*) ymomc -> data);
    686  
    687   return Py_BuildValue(""); 
     688
     689  return Py_BuildValue("");
    688690}
    689691
     
    694696  //    balance_deep_and_shallow(wc, zc, hc, wv, zv, hv,
    695697  //                             xmomc, ymomc, xmomv, ymomv)
    696  
    697 
    698   PyArrayObject 
     698
     699
     700  PyArrayObject
    699701    *wc,            //Stage at centroids
    700     *zc,            //Elevation at centroids   
    701     *hc,            //Height at centroids       
     702    *zc,            //Elevation at centroids
     703    *hc,            //Height at centroids
    702704    *wv,            //Stage at vertices
    703705    *zv,            //Elevation at vertices
    704     *hv,            //Depths at vertices   
    705     *hvbar,         //h-Limited depths at vertices       
     706    *hv,            //Depths at vertices
     707    *hvbar,         //h-Limited depths at vertices
    706708    *xmomc,         //Momentums at centroids and vertices
    707     *ymomc, 
    708     *xmomv, 
    709     *ymomv;   
    710    
     709    *ymomc,
     710    *xmomv,
     711    *ymomv;
     712
    711713  int N; //, err;
    712  
    713   // Convert Python arguments to C 
    714   if (!PyArg_ParseTuple(args, "OOOOOOOOOOO", 
    715                         &wc, &zc, &hc, 
     714
     715  // Convert Python arguments to C
     716  if (!PyArg_ParseTuple(args, "OOOOOOOOOOO",
     717                        &wc, &zc, &hc,
    716718                        &wv, &zv, &hv, &hvbar,
    717719                        &xmomc, &ymomc, &xmomv, &ymomv))
     
    719721
    720722  N = wc -> dimensions[0];
    721    
     723
    722724  _balance_deep_and_shallow(N,
    723725                            (double*) wc -> data,
    724                             (double*) zc -> data, 
    725                             (double*) hc -> data,                           
    726                             (double*) wv -> data, 
    727                             (double*) zv -> data, 
     726                            (double*) zc -> data,
     727                            (double*) hc -> data,
     728                            (double*) wv -> data,
     729                            (double*) zv -> data,
    728730                            (double*) hv -> data,
    729                             (double*) hvbar -> data,                       
    730                             (double*) xmomc -> data, 
    731                             (double*) ymomc -> data, 
    732                             (double*) xmomv -> data, 
    733                             (double*) ymomv -> data); 
    734  
    735  
    736   return Py_BuildValue(""); 
     731                            (double*) hvbar -> data,
     732                            (double*) xmomc -> data,
     733                            (double*) ymomc -> data,
     734                            (double*) xmomv -> data,
     735                            (double*) ymomv -> data);
     736
     737
     738  return Py_BuildValue("");
    737739}
    738740
     
    740742
    741743PyObject *h_limiter(PyObject *self, PyObject *args) {
    742  
     744
    743745  PyObject *domain, *Tmp;
    744   PyArrayObject 
    745     *hv, *hc, //Depth at vertices and centroids       
     746  PyArrayObject
     747    *hv, *hc, //Depth at vertices and centroids
    746748    *hvbar,   //Limited depth at vertices (return values)
    747749    *neighbours;
    748    
     750
    749751  int k, i, n, N, k3;
    750752  int dimensions[2];
    751753  double beta_h; //Safety factor (see config.py)
    752754  double *hmin, *hmax, hn;
    753  
    754   // Convert Python arguments to C 
    755   if (!PyArg_ParseTuple(args, "OOO", &domain, &hc, &hv)) 
     755
     756  // Convert Python arguments to C
     757  if (!PyArg_ParseTuple(args, "OOO", &domain, &hc, &hv))
    756758    return NULL;
    757759
     
    759761
    760762  //Get safety factor beta_h
    761   Tmp = PyObject_GetAttrString(domain, "beta_h"); 
    762   if (!Tmp) 
    763     return NULL;
    764      
    765   beta_h = PyFloat_AsDouble(Tmp); 
    766  
    767   Py_DECREF(Tmp);   
     763  Tmp = PyObject_GetAttrString(domain, "beta_h");
     764  if (!Tmp)
     765    return NULL;
     766
     767  beta_h = PyFloat_AsDouble(Tmp);
     768
     769  Py_DECREF(Tmp);
    768770
    769771  N = hc -> dimensions[0];
    770  
     772
    771773  //Create hvbar
    772774  dimensions[0] = N;
    773   dimensions[1] = 3; 
     775  dimensions[1] = 3;
    774776  hvbar = (PyArrayObject *) PyArray_FromDims(2, dimensions, PyArray_DOUBLE);
    775  
     777
    776778
    777779  //Find min and max of this and neighbour's centroid values
    778780  hmin = malloc(N * sizeof(double));
    779   hmax = malloc(N * sizeof(double)); 
     781  hmax = malloc(N * sizeof(double));
    780782  for (k=0; k<N; k++) {
    781783    k3=k*3;
    782    
     784
    783785    hmin[k] = ((double*) hc -> data)[k];
    784786    hmax[k] = hmin[k];
    785    
     787
    786788    for (i=0; i<3; i++) {
    787789      n = ((long*) neighbours -> data)[k3+i];
    788      
     790
    789791      //Initialise hvbar with values from hv
    790       ((double*) hvbar -> data)[k3+i] = ((double*) hv -> data)[k3+i]; 
    791      
     792      ((double*) hvbar -> data)[k3+i] = ((double*) hv -> data)[k3+i];
     793
    792794      if (n >= 0) {
    793795        hn = ((double*) hc -> data)[n]; //Neighbour's centroid value
    794          
     796
    795797        hmin[k] = min(hmin[k], hn);
    796798        hmax[k] = max(hmax[k], hn);
     
    798800    }
    799801  }
    800  
     802
    801803  // Call underlying standard routine
    802804  _limit(N, beta_h, (double*) hc -> data, (double*) hvbar -> data, hmin, hmax);
    803          
    804   // // //Py_DECREF(domain); //FIXME: NEcessary?         
     805
     806  // // //Py_DECREF(domain); //FIXME: NEcessary?
    805807  free(hmin);
    806   free(hmax); 
    807  
    808   //return result using PyArray to avoid memory leak 
     808  free(hmax);
     809
     810  //return result using PyArray to avoid memory leak
    809811  return PyArray_Return(hvbar);
    810   //return Py_BuildValue("");   
     812  //return Py_BuildValue("");
    811813}
    812814
     
    819821  //                              s_vec, phi_vec, self.const)
    820822
    821  
     823
    822824
    823825  PyArrayObject   //(one element per triangle)
    824   *s_vec,         //Speeds 
    825   *phi_vec,       //Bearings 
     826  *s_vec,         //Speeds
     827  *phi_vec,       //Bearings
    826828  *xmom_update,   //Momentum updates
    827   *ymom_update; 
    828 
    829    
    830   int N; 
     829  *ymom_update;
     830
     831
     832  int N;
    831833  double cw;
    832  
    833   // Convert Python arguments to C 
    834   if (!PyArg_ParseTuple(args, "OOOOd", 
     834
     835  // Convert Python arguments to C
     836  if (!PyArg_ParseTuple(args, "OOOOd",
    835837                        &xmom_update,
    836                         &ymom_update,                   
    837                         &s_vec, &phi_vec, 
     838                        &ymom_update,
     839                        &s_vec, &phi_vec,
    838840                        &cw))
    839841    return NULL;
    840842
    841843  N = xmom_update -> dimensions[0];
    842    
     844
    843845  _assign_wind_field_values(N,
    844846           (double*) xmom_update -> data,
    845            (double*) ymom_update -> data, 
    846            (double*) s_vec -> data, 
     847           (double*) ymom_update -> data,
     848           (double*) s_vec -> data,
    847849           (double*) phi_vec -> data,
    848850           cw);
    849  
    850   return Py_BuildValue(""); 
    851 }
    852 
    853 
    854 
    855 
    856 //////////////////////////////////////////     
     851
     852  return Py_BuildValue("");
     853}
     854
     855
     856
     857
     858//////////////////////////////////////////
    857859// Method table for python module
    858860static struct PyMethodDef MethodTable[] = {
     
    861863   * three.
    862864   */
    863  
     865
    864866  {"rotate", (PyCFunction)rotate, METH_VARARGS | METH_KEYWORDS, "Print out"},
    865   {"compute_fluxes", compute_fluxes, METH_VARARGS, "Print out"},   
    866   {"gravity", gravity, METH_VARARGS, "Print out"},     
    867   {"manning_friction", manning_friction, METH_VARARGS, "Print out"},       
    868   {"balance_deep_and_shallow", balance_deep_and_shallow, 
    869    METH_VARARGS, "Print out"},         
    870   {"h_limiter", h_limiter, 
    871    METH_VARARGS, "Print out"},             
    872   {"protect", protect, METH_VARARGS | METH_KEYWORDS, "Print out"},   
    873   {"assign_windfield_values", assign_windfield_values, 
    874    METH_VARARGS | METH_KEYWORDS, "Print out"},     
    875   //{"distribute_to_vertices_and_edges", 
    876   // distribute_to_vertices_and_edges, METH_VARARGS},   
    877   //{"update_conserved_quantities", 
    878   // update_conserved_quantities, METH_VARARGS},       
    879   //{"set_initialcondition", 
    880   // set_initialcondition, METH_VARARGS},   
     867  {"compute_fluxes", compute_fluxes, METH_VARARGS, "Print out"},
     868  {"gravity", gravity, METH_VARARGS, "Print out"},
     869  {"manning_friction", manning_friction, METH_VARARGS, "Print out"},
     870  {"balance_deep_and_shallow", balance_deep_and_shallow,
     871   METH_VARARGS, "Print out"},
     872  {"h_limiter", h_limiter,
     873   METH_VARARGS, "Print out"},
     874  {"protect", protect, METH_VARARGS | METH_KEYWORDS, "Print out"},
     875  {"assign_windfield_values", assign_windfield_values,
     876   METH_VARARGS | METH_KEYWORDS, "Print out"},
     877  //{"distribute_to_vertices_and_edges",
     878  // distribute_to_vertices_and_edges, METH_VARARGS},
     879  //{"update_conserved_quantities",
     880  // update_conserved_quantities, METH_VARARGS},
     881  //{"set_initialcondition",
     882  // set_initialcondition, METH_VARARGS},
    881883  {NULL, NULL}
    882884};
    883        
    884 // Module initialisation   
     885
     886// Module initialisation
    885887void initshallow_water_ext(void){
    886888  Py_InitModule("shallow_water_ext", MethodTable);
    887  
    888   import_array();     //Necessary for handling of NumPY structures 
    889 }
     889
     890  import_array();     //Necessary for handling of NumPY structures
     891}
Note: See TracChangeset for help on using the changeset viewer.