Changeset 8476


Ignore:
Timestamp:
Jul 23, 2012, 9:57:39 PM (13 years ago)
Author:
steve
Message:

Adding in discontinuous flux calculation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/anuga_core/source/anuga/shallow_water/shallow_water_ext.c

    r8457 r8476  
    342342    _rotate(q_right_rotated, n1, n2);
    343343
     344
     345    if (fabs(z_left - z_right) > 1.0e-10) {
     346                report_python_error(AT, "Discontinuous Elevation");
     347                return 0.0;
     348            }
    344349    z = 0.5 * (z_left + z_right); // Average elevation values.
    345350    // Even though this will nominally allow
     
    436441    return 0;
    437442}
     443
     444int _flux_function_central_discontinuous(double *q_left, double *q_right,
     445        double z_left, double z_right,
     446        double n1, double n2,
     447        double epsilon,
     448        double h0,
     449        double limiting_threshold,
     450        double g,
     451        double *edgeflux, double *max_speed,
     452        double *p_left, double *p_right) {
     453
     454    /*Compute fluxes between volumes for the shallow water wave equation
     455      cast in terms of the 'stage', w = h+z using
     456      the 'central scheme' as described in
     457
     458      Kurganov, Noelle, Petrova. 'Semidiscrete Central-Upwind Schemes For
     459      Hyperbolic Conservation Laws and Hamilton-Jacobi Equations'.
     460      Siam J. Sci. Comput. Vol. 23, No. 3, pp. 707-740.
     461
     462      The implemented formula is given in equation (3.15) on page 714
     463     */
     464
     465    int i;
     466
     467    double w_left, h_left, uh_left, vh_left, u_left, v_left;
     468    double w_right, h_right, uh_right, vh_right, u_right, v_right;
     469    double z_star, h_left_star, h_right_star;
     470    double s_min, s_max, soundspeed_left, soundspeed_right;
     471    double denom, inverse_denominator, z;
     472
     473    // Workspace (allocate once, use many)
     474    static double q_left_rotated[3], q_right_rotated[3], flux_right[3], flux_left[3];
     475
     476    // Copy conserved quantities to protect from modification
     477    q_left_rotated[0] = q_left[0];
     478    q_right_rotated[0] = q_right[0];
     479    q_left_rotated[1] = q_left[1];
     480    q_right_rotated[1] = q_right[1];
     481    q_left_rotated[2] = q_left[2];
     482    q_right_rotated[2] = q_right[2];
     483
     484    // Align x- and y-momentum with x-axis
     485    _rotate(q_left_rotated, n1, n2);
     486    _rotate(q_right_rotated, n1, n2);
     487
     488
     489    //if (fabs(z_left - z_right) > 1.0e-10) {
     490    //            report_python_error(AT, "Discontinuous Elevation");
     491    //            return 0.0;
     492    //        }
     493
     494    z_star = max(z_left, z_right);
     495    // Audusse's discontinuous method
     496
     497    // Compute speeds in x-direction
     498    w_left = q_left_rotated[0];
     499    h_left = w_left - z_left;
     500    uh_left = q_left_rotated[1];
     501    u_left = _compute_speed(&uh_left, &h_left,
     502            epsilon, h0, limiting_threshold);
     503    h_left_star = max(0.0,  w_left - z_star);
     504
     505    w_right = q_right_rotated[0];
     506    h_right = w_right - z_right;
     507    uh_right = q_right_rotated[1];
     508    u_right = _compute_speed(&uh_right, &h_right,
     509            epsilon, h0, limiting_threshold);
     510    h_right_star = max(0.0,  w_right - z_star);
     511
     512    // Momentum in y-direction
     513    vh_left = q_left_rotated[2];
     514    vh_right = q_right_rotated[2];
     515
     516    // Limit y-momentum if necessary
     517    // Leaving this out, improves speed significantly (Ole 27/5/2009)
     518    // All validation tests pass, so do we really need it anymore?
     519    v_left  = _compute_speed(&vh_left, &h_left,
     520            epsilon, h0, limiting_threshold);
     521    v_right = _compute_speed(&vh_right, &h_right,
     522            epsilon, h0, limiting_threshold);
     523
     524    // Maximal and minimal wave speeds
     525    soundspeed_left = sqrt(g * h_left_star);
     526    soundspeed_right = sqrt(g * h_right_star);
     527
     528    s_max = max(u_left + soundspeed_left, u_right + soundspeed_right);
     529    if (s_max < 0.0) {
     530        s_max = 0.0;
     531    }
     532
     533    s_min = min(u_left - soundspeed_left, u_right - soundspeed_right);
     534    if (s_min > 0.0) {
     535        s_min = 0.0;
     536    }
     537
     538    // Flux formulas
     539    flux_left[0] = u_left * h_left_star;
     540    flux_left[1] = u_left * u_left * h_left_star + 0.5 * g * h_left_star*h_left_star;
     541    flux_left[2] = u_left * v_left * h_left_star;
     542
     543    flux_right[0] = u_right * h_right_star;
     544    flux_right[1] = u_right * u_right * h_right_star + 0.5 * g * h_right_star * h_right_star;
     545    flux_right[2] = u_right * v_right * h_right_star;
     546
     547    // Flux computation
     548    denom = s_max - s_min;
     549    if (denom < epsilon) { // FIXME (Ole): Try using h0 here
     550        memset(edgeflux, 0, 3 * sizeof (double));
     551        *max_speed = 0.0;
     552        *p_left  = 0.0;
     553        *p_right = 0.0;
     554    }
     555    else {
     556        inverse_denominator = 1.0 / denom;
     557        for (i = 0; i < 3; i++) {
     558            edgeflux[i] = s_max * flux_left[i] - s_min * flux_right[i];
     559            edgeflux[i] += s_max * s_min * (q_right_rotated[i] - q_left_rotated[i]);
     560            edgeflux[i] *= inverse_denominator;
     561        }
     562
     563        // Corrections for well balaning with discontinuus bed
     564        *p_left  = - 0.5 * g * h_left_star*h_left_star + 0.5 * g * h_left*h_left;
     565        *p_right = - 0.5 * g * h_right_star * h_right_star + 0.5 * g * h_right * h_right;
     566
     567        // Maximal wavespeed
     568        *max_speed = max(fabs(s_max), fabs(s_min));
     569
     570        // Rotate back
     571        _rotate(edgeflux, n1, -n2);
     572    }
     573
     574    return 0;
     575}
     576
     577
    438578
    439579// Innermost flux function (using stage w=z+h)
     
    44054545
    44064546
     4547/*
    44074548            if (fabs(zl - zr) > 1.0e-10) {
    44084549                report_python_error(AT, "Discontinuous Elevation");
    44094550                return 0.0;
    44104551            }
     4552*/
    44114553
    44124554            // Outward pointing normal vector (domain.normals[k, 2*i:2*i+2])
Note: See TracChangeset for help on using the changeset viewer.