Changeset 8476
- Timestamp:
- Jul 23, 2012, 9:57:39 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/anuga_core/source/anuga/shallow_water/shallow_water_ext.c
r8457 r8476 342 342 _rotate(q_right_rotated, n1, n2); 343 343 344 345 if (fabs(z_left - z_right) > 1.0e-10) { 346 report_python_error(AT, "Discontinuous Elevation"); 347 return 0.0; 348 } 344 349 z = 0.5 * (z_left + z_right); // Average elevation values. 345 350 // Even though this will nominally allow … … 436 441 return 0; 437 442 } 443 444 int _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 438 578 439 579 // Innermost flux function (using stage w=z+h) … … 4405 4545 4406 4546 4547 /* 4407 4548 if (fabs(zl - zr) > 1.0e-10) { 4408 4549 report_python_error(AT, "Discontinuous Elevation"); 4409 4550 return 0.0; 4410 4551 } 4552 */ 4411 4553 4412 4554 // Outward pointing normal vector (domain.normals[k, 2*i:2*i+2])
Note: See TracChangeset
for help on using the changeset viewer.