Changeset 4239


Ignore:
Timestamp:
Feb 7, 2007, 6:18:28 PM (18 years ago)
Author:
ole
Message:

Implemented new balanced slope limiter.
To enable, set

domain.limit2007 = 1

in the ANUGA scripts.
Later, we may make it default depending on how it goes.

Location:
anuga_core/source/anuga
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • anuga_core/source/anuga/config.py

    r4219 r4239  
    8888alpha_balance = 2.0
    8989
     90# Flag use of new limiters.
     91# limit2007 = 0 means use old limiters (e.g. for some tests)
     92# limit2007 = 1 means use new limiters that hug the bathymetry closer
     93limit2007 = 0
     94
    9095
    9196CFL = 1.0  #FIXME (ole): Is this in use yet??
  • anuga_core/source/anuga/shallow_water/shallow_water_domain.py

    r4218 r4239  
    100100from anuga.config import minimum_allowed_height, maximum_allowed_speed
    101101from anuga.config import g, beta_h, beta_w, beta_w_dry,\
    102      beta_uh, beta_uh_dry, beta_vh, beta_vh_dry
     102     beta_uh, beta_uh_dry, beta_vh, beta_vh_dry, limit2007
    103103from anuga.config import alpha_balance
    104104
     
    158158        self.beta_h      = beta_h
    159159        self.alpha_balance = alpha_balance
     160
     161        self.limit2007 = limit2007
    160162
    161163        self.flux_function = flux_function_central
     
    11841186
    11851187    #Limit h
    1186     hvbar = h_limiter(domain)
    1187 
    1188     #This is how one would make a first order h_limited value
    1189     #as in the old balancer (pre 17 Feb 2005):
    1190     #from Numeric import zeros, Float
    1191     #hvbar = zeros( (len(hc), 3), Float)
    1192     #for i in range(3):
    1193     #    hvbar[:,i] = hc[:]
     1188    if domain.beta_h > 0:
     1189        hvbar = h_limiter(domain)
     1190    else:
     1191        # print 'Using first order h-limiter'
     1192     
     1193       
     1194        #This is how one would make a first order h_limited value
     1195        #as in the old balancer (pre 17 Feb 2005):
     1196        # If we wish to hard wire this, one should modify the C-code
     1197        from Numeric import zeros, Float
     1198        hvbar = zeros( (len(hc), 3), Float)
     1199        for i in range(3):
     1200            hvbar[:,i] = hc[:]
    11941201
    11951202    from shallow_water_ext import balance_deep_and_shallow
  • anuga_core/source/anuga/shallow_water/shallow_water_ext.c

    r4218 r4239  
    428428                              double* xmomv,
    429429                              double* ymomv,
     430                              double H0,
     431                              int limit2007,
    430432                              double alpha_balance) {
    431433
    432434  int k, k3, i;
    433   double dz, hmin, alpha;
     435  double dz, hmin, alpha, h_diff;
    434436
    435437  //Compute linear combination between w-limited stages and
     
    450452    hmin = hv[k3];
    451453    for (i=0; i<3; i++) {
    452       dz = max(dz, fabs(zv[k3+i]-zc[k]));
     454      if (limit2007 == 0) {
     455        dz = max(dz, fabs(zv[k3+i]-zc[k]));
     456      }
     457     
    453458      hmin = min(hmin, hv[k3+i]);
    454459    }
     
    458463    //stage and alpha==1 means using the w-limited stage as
    459464    //computed by the gradient limiter (both 1st or 2nd order)
    460     //
    461     //If hmin > dz/alpha_balance then alpha = 1 and the bed will have no effect
    462     //If hmin < 0 then alpha = 0 reverting to constant height above bed.
    463     //The parameter alpha_balance==2 by default
    464 
    465 
    466     if (dz > 0.0) {
    467       alpha = max( min( alpha_balance*hmin/dz, 1.0), 0.0 );     
     465   
     466   
     467    if (limit2007 == 0) {     
     468      //If hmin > dz/alpha_balance then alpha = 1 and the bed will have no
     469      //effect
     470      //If hmin < 0 then alpha = 0 reverting to constant height above bed.
     471      //The parameter alpha_balance==2 by default
     472
     473     
     474      if (dz > 0.0) {
     475        alpha = max( min( alpha_balance*hmin/dz, 1.0), 0.0 );     
     476      } else {
     477        alpha = 1.0;  //Flat bed
     478      }
     479      //printf("Using old style limiter\n");
     480     
    468481    } else {
    469       alpha = 1.0;  //Flat bed
    470     }
    471 
     482
     483      // 2007 Balanced Limiter
    472484   
     485      // Make alpha as large as possible but still ensure that
     486      // final depth is positive
     487   
     488      if (hmin < H0) {
     489        alpha = 1.0;
     490        for (i=0; i<3; i++) {
     491
     492          h_diff = hvbar[k3+i] - hv[k3+i];
     493       
     494          if (h_diff <= 0) {
     495            // Deep water triangle is further away from bed than
     496            // shallow water (hbar < h). Any alpha will do
     497         
     498          } else { 
     499            // Denominator is positive which means that we need some of the
     500            // h-limited stage.
     501           
     502            alpha = min(alpha, (hvbar[k3+i] - H0)/h_diff);
     503          }
     504        }
     505
     506        // Ensure alpha in [0,1]
     507        if (alpha>1.0) alpha=1.0;
     508        if (alpha<0.0) alpha=0.0;
     509       
     510      } else {
     511        // Use w-limited stage exclusively
     512        alpha = 1.0;       
     513      }
     514    }
     515       
     516   
     517       
    473518    //printf("k=%d, hmin=%.2f, dz=%.2f, alpha=%.2f, alpha_balance=%.2f\n",
    474519    //     k, hmin, dz, alpha, alpha_balance);
    475      
    476          
    477     //alpha = 1.0;  //Always deep FIXME: This actually looks good now
    478     //alpha = 0.2;
    479520
    480521    //printf("dz = %.3f, alpha = %.8f\n", dz, alpha);
     
    499540    if (alpha < 1) {
    500541      for (i=0; i<3; i++) {
    501          wv[k3+i] = zv[k3+i] + (1-alpha)*hvbar[k3+i] + alpha*hv[k3+i];
     542        wv[k3+i] = zv[k3+i] + (1-alpha)*hvbar[k3+i] + alpha*hv[k3+i];
    502543
    503544        //Update momentum as a linear combination of
    504545        //xmomc and ymomc (shallow) and momentum
    505546        //from extrapolator xmomv and ymomv (deep).
     547        //FIXME (Ole): Is this really needed?
    506548        xmomv[k3+i] = (1-alpha)*xmomc[k] + alpha*xmomv[k3+i];
    507549        ymomv[k3+i] = (1-alpha)*ymomc[k] + alpha*ymomv[k3+i];
     
    550592      } else {
    551593        //Reduce excessive speeds derived from division by small hc
     594        //FIXME (Ole): This may be unnecessary with new slope limiters
     595        //in effect.
    552596       
    553597        u = xmomc[k]/hc;
     
    15941638   
    15951639  double alpha_balance = 2.0;
    1596 
    1597   int N; //, err;
     1640  double H0;
     1641
     1642  int N, limit2007; //, err;
    15981643
    15991644  // Convert Python arguments to C
     
    16161661  Py_DECREF(Tmp);
    16171662
    1618 
     1663 
     1664  Tmp = PyObject_GetAttrString(domain, "H0");
     1665  if (!Tmp) {
     1666    PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: balance_deep_and_shallow could not obtain object H0 from domain");
     1667    return NULL;
     1668  } 
     1669  H0 = PyFloat_AsDouble(Tmp);
     1670  Py_DECREF(Tmp);
     1671
     1672 
     1673  Tmp = PyObject_GetAttrString(domain, "limit2007");
     1674  if (!Tmp) {
     1675    PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: balance_deep_and_shallow could not obtain object limit2007 from domain");
     1676    return NULL;
     1677  } 
     1678  limit2007 = PyInt_AsLong(Tmp);
     1679  Py_DECREF(Tmp);
     1680   
     1681
     1682 
     1683 
    16191684  N = wc -> dimensions[0];
    16201685
     
    16271692                            (double*) hv -> data,
    16281693                            (double*) hvbar -> data,
    1629                                 (double*) xmomc -> data,
     1694                            (double*) xmomc -> data,
    16301695                            (double*) ymomc -> data,
    16311696                            (double*) xmomv -> data,
    16321697                            (double*) ymomv -> data,
     1698                            H0,
     1699                            (int) limit2007,
    16331700                            alpha_balance);
    16341701
  • anuga_core/source/anuga/shallow_water/test_shallow_water_domain.py

    r4218 r4239  
    10521052
    10531053       
    1054 
    1055 
    10561054       
    10571055        assert allclose(gauge_values[0], G0)
     
    34183416        domain.beta_vh_dry = 0.9
    34193417        domain.beta_h = 0.0 #Use first order in h-limiter
    3420         domain.H0 = 0 # Backwards compatibility (6/2/7)       
     3418        domain.H0 = 0 # Backwards compatibility (6/2/7)
     3419       
    34213420
    34223421        #Bed-slope and friction at vertices (and interpolated elsewhere)
Note: See TracChangeset for help on using the changeset viewer.