Changeset 9306
- Timestamp:
- Aug 15, 2014, 4:48:51 PM (11 years ago)
- Location:
- trunk/anuga_core/source/anuga/shallow_water
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/anuga_core/source/anuga/shallow_water/shallow_water_domain.py
r9292 r9306 1697 1697 # Flux calculation and gravity incorporated in same 1698 1698 # procedure 1699 # Also, fluxes are limited to prevent cells exporting more water 1700 # than they contain 1701 1702 # FIXME SR: This needs cleaning up, should just be passing through 1703 # the domain as in other compute flux calls 1699 1704 1700 from swDE1_domain_ext import compute_fluxes_ext_central \ 1705 1701 as compute_fluxes_ext 1706 #if self.timestepping_method=='euler':1707 # raise Exception, "DE1 doesn't seems to work with euler at present \1708 # (boundary conditions?), and is mostly designed for rk2"1709 Stage = self.quantities['stage']1710 Xmom = self.quantities['xmomentum']1711 Ymom = self.quantities['ymomentum']1712 Bed = self.quantities['elevation']1713 height = self.quantities['height']1714 1702 1715 1703 timestep = self.evolve_max_timestep 1716 1704 1717 flux_timestep = compute_fluxes_ext(timestep, 1718 self.epsilon, 1719 self.minimum_allowed_height, 1720 self.g, 1721 self.boundary_flux_sum, 1722 self.neighbours, 1723 self.neighbour_edges, 1724 self.normals, 1725 self.edgelengths, 1726 self.radii, 1727 self.areas, 1728 self.tri_full_flag, 1729 Stage.edge_values, 1730 Xmom.edge_values, 1731 Ymom.edge_values, 1732 Bed.edge_values, 1733 height.edge_values, 1734 Stage.boundary_values, 1735 Xmom.boundary_values, 1736 Ymom.boundary_values, 1737 self.boundary_flux_type, 1738 Stage.explicit_update, 1739 Xmom.explicit_update, 1740 Ymom.explicit_update, 1741 self.already_computed_flux, 1742 self.max_speed, 1743 int(self.optimise_dry_cells), 1744 self.timestep_fluxcalls, 1745 Stage.centroid_values, 1746 Xmom.centroid_values, 1747 Ymom.centroid_values, 1748 Bed.centroid_values, 1749 height.centroid_values, 1750 self.edge_flux_type, 1751 self.riverwallData.riverwall_elevation, 1752 self.riverwallData.hydraulic_properties_rowIndex, 1753 int(self.riverwallData.ncol_hydraulic_properties), 1754 self.riverwallData.hydraulic_properties, 1755 self.edge_flux_work, 1756 self.pressuregrad_work, 1757 self.edge_timestep, 1758 self.update_next_flux, 1759 self.allow_timestep_increase) 1705 flux_timestep = compute_fluxes_ext(self, timestep) 1760 1706 1761 1707 self.flux_timestep = flux_timestep … … 1834 1780 # Do extrapolation step 1835 1781 from swDE1_domain_ext import extrapolate_second_order_edge_sw as extrapol2 1836 1837 Stage = self.quantities['stage'] 1838 Xmom = self.quantities['xmomentum'] 1839 Ymom = self.quantities['ymomentum'] 1840 Elevation = self.quantities['elevation'] 1841 height=self.quantities['height'] 1842 1843 extrapol2(self, 1844 self.surrogate_neighbours, 1845 self.neighbour_edges, 1846 self.number_of_boundaries, 1847 self.centroid_coordinates, 1848 Stage.centroid_values, 1849 Xmom.centroid_values, 1850 Ymom.centroid_values, 1851 Elevation.centroid_values, 1852 height.centroid_values, 1853 self.edge_coordinates, 1854 Stage.edge_values, 1855 Xmom.edge_values, 1856 Ymom.edge_values, 1857 Elevation.edge_values, 1858 height.edge_values, 1859 Stage.vertex_values, 1860 Xmom.vertex_values, 1861 Ymom.vertex_values, 1862 Elevation.vertex_values, 1863 height.vertex_values, 1864 int(self.optimise_dry_cells), 1865 int(self.extrapolate_velocity_second_order), 1866 self.x_centroid_work, 1867 self.y_centroid_work, 1868 self.update_extrapolation) 1782 extrapol2(self) 1783 1869 1784 else: 1870 1785 # Code for original method … … 2633 2548 as compute_flux_update_frequency_ext 2634 2549 2635 compute_flux_update_frequency_ext( 2636 self.timestep, 2637 self.neighbours, 2638 self.neighbour_edges, 2639 self.already_computed_flux, 2640 self.edge_timestep, 2641 self.flux_update_frequency, 2642 self.update_extrapolation, 2643 self.max_flux_update_frequency, 2644 self.update_next_flux, 2645 self.allow_timestep_increase) 2550 compute_flux_update_frequency_ext(self, self.timestep) 2646 2551 2647 2552 def report_water_volume_statistics(self, verbose=True, returnStats=False): -
trunk/anuga_core/source/anuga/shallow_water/swDE1_domain_ext.c
r9292 r9306 25 25 // Shared code snippets 26 26 #include "util_ext.h" 27 #include "sw_domain.h" 27 28 28 29 … … 451 452 //////////////////////////////////////////////////////////////// 452 453 453 int _compute_flux_update_frequency(int number_of_elements, 454 long *neighbours, long *neighbour_edges, 455 long *already_computed_flux, 456 int max_flux_update_frequency, double *edge_timestep, 457 double timestep, double notSoFast, 458 long *flux_update_frequency, 459 long *update_extrapolation, 460 long *update_next_flux, 461 long *allow_timestep_increase){ 454 int _compute_flux_update_frequency(struct domain *D, double timestep){ 462 455 // Compute the 'flux_update_frequency' for each edge. 463 456 // … … 474 467 int k, i, k3, ki, m, n, nm, ii, j, ii2; 475 468 long fuf; 469 double notSoFast=1.0; 476 470 static int cyclic_number_of_steps=-1; 477 471 478 472 // QUICK EXIT 479 if( max_flux_update_frequency==1){473 if(D->max_flux_update_frequency==1){ 480 474 return 0; 481 475 } … … 483 477 // Count the steps 484 478 cyclic_number_of_steps++; 485 if(cyclic_number_of_steps== max_flux_update_frequency){479 if(cyclic_number_of_steps==D->max_flux_update_frequency){ 486 480 // The flux was just updated in every cell 487 481 cyclic_number_of_steps=0; … … 491 485 // PART 1: ONLY OCCURS FOLLOWING FLUX UPDATE 492 486 493 for ( k = 0; k < number_of_elements; k++){487 for ( k = 0; k < D->number_of_elements; k++){ 494 488 for ( i = 0; i < 3; i++){ 495 489 ki = k*3 + i; 496 if((Mod_of_power_2(cyclic_number_of_steps, flux_update_frequency[ki])==0)){490 if((Mod_of_power_2(cyclic_number_of_steps, D->flux_update_frequency[ki])==0)){ 497 491 // The flux was just updated, along with the edge_timestep 498 492 // So we better recompute the flux_update_frequency 499 n= neighbours[ki];493 n=D->neighbours[ki]; 500 494 if(n>=0){ 501 m = neighbour_edges[ki];495 m = D->neighbour_edges[ki]; 502 496 nm = n * 3 + m; // Linear index (triangle n, edge m) 503 497 } … … 506 500 // (Multiply already_computed_flux by -1 on the first update, 507 501 // and again on the 2nd) 508 if( already_computed_flux[ki] > 0 ){502 if(D->already_computed_flux[ki] > 0 ){ 509 503 // We have not fixed this flux value yet 510 already_computed_flux[ki] *=-1;504 D->already_computed_flux[ki] *=-1; 511 505 if(n>=0){ 512 already_computed_flux[nm] *=-1;506 D->already_computed_flux[nm] *=-1; 513 507 } 514 508 }else{ 515 509 // We have fixed this flux value already 516 already_computed_flux[ki] *=-1;510 D->already_computed_flux[ki] *=-1; 517 511 if(n>=0){ 518 already_computed_flux[nm] *=-1;512 D->already_computed_flux[nm] *=-1; 519 513 } 520 514 continue; … … 525 519 // NOTE: edge_timestep[ki]/timestep can be very large [so int overflows]. 526 520 // Do not pull the (int) inside the min term 527 fuf = (int)min(( edge_timestep[ki]/timestep)*notSoFast,max_flux_update_frequency*1.);521 fuf = (int)min((D->edge_timestep[ki]/timestep)*notSoFast,D->max_flux_update_frequency*1.); 528 522 // Account for neighbour 529 523 if(n>=0){ 530 fuf = min( (int)min( edge_timestep[nm]/timestep*notSoFast,max_flux_update_frequency*1.), fuf);524 fuf = min( (int)min(D->edge_timestep[nm]/timestep*notSoFast, D->max_flux_update_frequency*1.), fuf); 531 525 } 532 526 … … 536 530 } 537 531 // Deal with large fuf 538 if(fuf> max_flux_update_frequency){539 fuf = max_flux_update_frequency;532 if(fuf> D->max_flux_update_frequency){ 533 fuf = D->max_flux_update_frequency; 540 534 } 541 535 //// Deal with intermediate cases 542 536 ii=2; 543 while(ii< max_flux_update_frequency){537 while(ii< D->max_flux_update_frequency){ 544 538 // Set it to 1,2,4, 8, ... 545 539 ii2=2*ii; … … 552 546 553 547 // Set the values 554 flux_update_frequency[ki]=fuf;548 D->flux_update_frequency[ki]=fuf; 555 549 if(n>=0){ 556 flux_update_frequency[nm]= fuf;550 D->flux_update_frequency[nm]= fuf; 557 551 } 558 552 … … 567 561 // Experiences suggests this is numerically important 568 562 // (But, it can result in the same edge having different flux_update_freq) 569 for( k=0; k< number_of_elements; k++){563 for( k=0; k< D->number_of_elements; k++){ 570 564 k3=3*k; 571 ii = 1*min( flux_update_frequency[k3],572 min( flux_update_frequency[k3+1],573 flux_update_frequency[k3+2]));565 ii = 1*min(D->flux_update_frequency[k3], 566 min(D->flux_update_frequency[k3+1], 567 D->flux_update_frequency[k3+2])); 574 568 575 flux_update_frequency[k3]=min(ii,flux_update_frequency[k3]);576 flux_update_frequency[k3+1]=min(ii,flux_update_frequency[k3+1]);577 flux_update_frequency[k3+2]=min(ii,flux_update_frequency[k3+2]);569 D->flux_update_frequency[k3]=min(ii, D->flux_update_frequency[k3]); 570 D->flux_update_frequency[k3+1]=min(ii, D->flux_update_frequency[k3+1]); 571 D->flux_update_frequency[k3+2]=min(ii,D->flux_update_frequency[k3+2]); 578 572 579 573 } … … 585 579 // will have its flux_update_frequency updated after a few timesteps (i.e. before max_flux_update_frequency timesteps) 586 580 // OTOH, could this cause oscillations in flux_update_frequency? 587 for( k = 0; k < number_of_elements; k++){588 update_extrapolation[k]=0;581 for( k = 0; k < D->number_of_elements; k++){ 582 D->update_extrapolation[k]=0; 589 583 for( i = 0; i< 3; i++){ 590 584 ki=3*k+i; 591 585 // Account for neighbour 592 n= neighbours[ki];586 n=D->neighbours[ki]; 593 587 if(n>=0){ 594 m = neighbour_edges[ki];588 m = D->neighbour_edges[ki]; 595 589 nm = n * 3 + m; // Linear index (triangle n, edge m) 596 flux_update_frequency[ki]=min(flux_update_frequency[ki],flux_update_frequency[nm]);590 D->flux_update_frequency[ki]=min(D->flux_update_frequency[ki], D->flux_update_frequency[nm]); 597 591 } 598 592 // Do we need to update the extrapolation? 599 593 // (We do if the next flux computation will actually compute a flux!) 600 if(Mod_of_power_2((cyclic_number_of_steps+1), flux_update_frequency[ki])==0){601 update_next_flux[ki]=1;602 update_extrapolation[k]=1;594 if(Mod_of_power_2((cyclic_number_of_steps+1),D->flux_update_frequency[ki])==0){ 595 D->update_next_flux[ki]=1; 596 D->update_extrapolation[k]=1; 603 597 }else{ 604 update_next_flux[ki]=0;598 D->update_next_flux[ki]=0; 605 599 } 606 600 } … … 608 602 609 603 // Check whether the timestep can be increased in the next compute_fluxes call 610 if(cyclic_number_of_steps+1== max_flux_update_frequency){604 if(cyclic_number_of_steps+1==D->max_flux_update_frequency){ 611 605 // All fluxes will be updated on the next timestep 612 606 // We also allow the timestep to increase then 613 allow_timestep_increase[0]=1;607 D->allow_timestep_increase[0]=1; 614 608 }else{ 615 allow_timestep_increase[0]=0;609 D->allow_timestep_increase[0]=0; 616 610 } 617 611 … … 712 706 713 707 // Computational function for flux computation 714 double _compute_fluxes_central(int number_of_elements, 715 double timestep, 716 double epsilon, 717 double H0, 718 double g, 719 double* boundary_flux_sum, 720 long* neighbours, 721 long* neighbour_edges, 722 double* normals, 723 double* edgelengths, 724 double* radii, 725 double* areas, 726 long* tri_full_flag, 727 double* stage_edge_values, 728 double* xmom_edge_values, 729 double* ymom_edge_values, 730 double* bed_edge_values, 731 double* height_edge_values, 732 double* stage_boundary_values, 733 double* xmom_boundary_values, 734 double* ymom_boundary_values, 735 long* boundary_flux_type, 736 double* stage_explicit_update, 737 double* xmom_explicit_update, 738 double* ymom_explicit_update, 739 long* already_computed_flux, 740 double* max_speed_array, 741 int optimise_dry_cells, 742 int timestep_fluxcalls, 743 double* stage_centroid_values, 744 double* xmom_centroid_values, 745 double* ymom_centroid_values, 746 double* bed_centroid_values, 747 double* height_centroid_values, 748 long* edge_flux_type, 749 double* riverwall_elevation, 750 long* riverwall_rowIndex, 751 int ncol_riverwall_hydraulic_properties, 752 double* riverwall_hydraulic_properties, 753 double* edge_flux_work, 754 double* pressuregrad_work, 755 double* edge_timestep, 756 long* update_next_flux, 757 long* allow_timestep_increase) { 708 double _compute_fluxes_central(struct domain *D, double timestep){ 709 758 710 // Local variables 759 double max_speed , length, inv_area, zl, zr;711 double max_speed_local, length, inv_area, zl, zr; 760 712 double h_left, h_right, z_half ; // For andusse scheme 761 713 // FIXME: limiting_threshold is not used for DE1 762 double limiting_threshold = 10* H0;714 double limiting_threshold = 10*D->H0; 763 715 // 764 716 int k, i, m, n,j, ii; … … 781 733 // Set explicit_update to zero for all conserved_quantities. 782 734 // This assumes compute_fluxes called before forcing terms 783 memset((char*) stage_explicit_update, 0,number_of_elements * sizeof (double));784 memset((char*) xmom_explicit_update, 0,number_of_elements * sizeof (double));785 memset((char*) ymom_explicit_update, 0,number_of_elements * sizeof (double));735 memset((char*) D->stage_explicit_update, 0, D->number_of_elements * sizeof (double)); 736 memset((char*) D->xmom_explicit_update, 0, D->number_of_elements * sizeof (double)); 737 memset((char*) D->ymom_explicit_update, 0, D->number_of_elements * sizeof (double)); 786 738 787 739 … … 789 741 RiverWall_count=0; 790 742 // Which substep of the timestepping method are we on? 791 substep_count=(call-2)% timestep_fluxcalls;743 substep_count=(call-2)%D->timestep_fluxcalls; 792 744 793 745 // Fluxes are not updated every timestep, 794 746 // but all fluxes ARE updated when the following condition holds 795 if( allow_timestep_increase[0]==1){747 if(D->allow_timestep_increase[0]==1){ 796 748 // We can only increase the timestep if all fluxes are allowed to be updated 797 749 // If this is not done the timestep can't increase (since local_timestep is static) … … 800 752 801 753 // For all triangles 802 for (k = 0; k < number_of_elements; k++) {754 for (k = 0; k < D->number_of_elements; k++) { 803 755 speed_max_last=0.0; 804 756 … … 809 761 ki3 = 3*ki; 810 762 811 if (( already_computed_flux[ki] == call) || (update_next_flux[ki]!=1)) {763 if ((D->already_computed_flux[ki] == call) || (D->update_next_flux[ki]!=1)) { 812 764 // We've already computed the flux across this edge 813 765 // Check if it is a riverwall 814 if( edge_flux_type[ki]==1){766 if(D->edge_flux_type[ki]==1){ 815 767 // Update counter of riverwall edges == index of 816 768 // riverwall_elevation + riverwall_rowIndex … … 821 773 822 774 // Get left hand side values from triangle k, edge i 823 ql[0] = stage_edge_values[ki];824 ql[1] = xmom_edge_values[ki];825 ql[2] = ymom_edge_values[ki];826 zl = bed_edge_values[ki];827 hc = height_centroid_values[k];828 zc = bed_centroid_values[k];829 hle= height_edge_values[ki];775 ql[0] = D->stage_edge_values[ki]; 776 ql[1] = D->xmom_edge_values[ki]; 777 ql[2] = D->ymom_edge_values[ki]; 778 zl = D->bed_edge_values[ki]; 779 hc = D->height_centroid_values[k]; 780 zc = D->bed_centroid_values[k]; 781 hle= D->height_edge_values[ki]; 830 782 831 783 // Get right hand side values either from neighbouring triangle 832 784 // or from boundary array (Quantities at neighbour on nearest face). 833 n = neighbours[ki];785 n = D->neighbours[ki]; 834 786 hc_n = hc; 835 zc_n = bed_centroid_values[k];787 zc_n = D->bed_centroid_values[k]; 836 788 if (n < 0) { 837 789 // Neighbour is a boundary condition 838 790 m = -n - 1; // Convert negative flag to boundary index 839 791 840 qr[0] = stage_boundary_values[m];841 qr[1] = xmom_boundary_values[m];842 qr[2] = ymom_boundary_values[m];792 qr[0] = D->stage_boundary_values[m]; 793 qr[1] = D->xmom_boundary_values[m]; 794 qr[2] = D->ymom_boundary_values[m]; 843 795 zr = zl; // Extend bed elevation to boundary 844 796 hre= max(qr[0]-zr,0.);//hle; 845 797 } else { 846 798 // Neighbour is a real triangle 847 hc_n = height_centroid_values[n];848 zc_n = bed_centroid_values[n];849 m = neighbour_edges[ki];799 hc_n = D->height_centroid_values[n]; 800 zc_n = D->bed_centroid_values[n]; 801 m = D->neighbour_edges[ki]; 850 802 nm = n * 3 + m; // Linear index (triangle n, edge m) 851 803 nm3 = nm*3; 852 804 853 qr[0] = stage_edge_values[nm];854 qr[1] = xmom_edge_values[nm];855 qr[2] = ymom_edge_values[nm];856 zr = bed_edge_values[nm];857 hre = height_edge_values[nm];805 qr[0] = D->stage_edge_values[nm]; 806 qr[1] = D->xmom_edge_values[nm]; 807 qr[2] = D->ymom_edge_values[nm]; 808 zr = D->bed_edge_values[nm]; 809 hre = D->height_edge_values[nm]; 858 810 } 859 811 … … 862 814 863 815 //// Account for riverwalls 864 if( edge_flux_type[ki]==1){816 if(D->edge_flux_type[ki]==1){ 865 817 // Update counter of riverwall edges == index of 866 818 // riverwall_elevation + riverwall_rowIndex … … 868 820 869 821 // Set central bed to riverwall elevation 870 z_half=max( riverwall_elevation[RiverWall_count-1], z_half) ;822 z_half=max(D->riverwall_elevation[RiverWall_count-1], z_half) ; 871 823 872 824 } … … 881 833 h_left, h_right, 882 834 hle, hre, 883 normals[ki2],normals[ki2 + 1],884 epsilon, z_half, limiting_threshold,g,885 edgeflux, &max_speed , &pressure_flux, hc, hc_n);835 D->normals[ki2],D->normals[ki2 + 1], 836 D->epsilon, z_half, limiting_threshold, D->g, 837 edgeflux, &max_speed_local, &pressure_flux, hc, hc_n); 886 838 887 839 // Force weir discharge to match weir theory 888 if( edge_flux_type[ki]==1){889 weir_height=max( riverwall_elevation[RiverWall_count-1]-min(zl,zr), 0.); // Reference weir height840 if(D->edge_flux_type[ki]==1){ 841 weir_height=max(D->riverwall_elevation[RiverWall_count-1]-min(zl,zr), 0.); // Reference weir height 890 842 // If the weir height is zero, avoid the weir computation entirely 891 843 if(weir_height>0.){ … … 893 845 // Use first-order h's for weir -- as the 'upstream/downstream' heads are 894 846 // measured away from the weir itself 895 h_left_tmp= max( stage_centroid_values[k]-z_half,0.);847 h_left_tmp= max(D->stage_centroid_values[k]-z_half,0.); 896 848 if(n>=0){ 897 h_right_tmp= max( stage_centroid_values[n]-z_half,0.);849 h_right_tmp= max(D->stage_centroid_values[n]-z_half,0.); 898 850 }else{ 899 851 h_right_tmp= max(hc_n+zr-z_half,0.); … … 902 854 ////////////////////////////////////////////////////////////////////////////////// 903 855 // Get Qfactor index - multiply the idealised weir discharge by this constant factor 904 ii =riverwall_rowIndex[RiverWall_count-1]*ncol_riverwall_hydraulic_properties;905 Qfactor =riverwall_hydraulic_properties[ii];856 ii = D->riverwall_rowIndex[RiverWall_count-1] * D->ncol_riverwall_hydraulic_properties; 857 Qfactor = D->riverwall_hydraulic_properties[ii]; 906 858 // Get s1, submergence ratio at which we start blending with the shallow water solution 907 859 ii+=1; 908 s1= riverwall_hydraulic_properties[ii];860 s1= D->riverwall_hydraulic_properties[ii]; 909 861 // Get s2, submergence ratio at which we entirely use the shallow water solution 910 862 ii+=1; 911 s2= riverwall_hydraulic_properties[ii];863 s2= D->riverwall_hydraulic_properties[ii]; 912 864 // Get h1, tailwater head / weir height at which we start blending with the shallow water solution 913 865 ii+=1; 914 h1= riverwall_hydraulic_properties[ii];866 h1= D->riverwall_hydraulic_properties[ii]; 915 867 // Get h2, tailwater head / weir height at which we entirely use the shallow water solution 916 868 ii+=1; 917 h2= riverwall_hydraulic_properties[ii];869 h2= D->riverwall_hydraulic_properties[ii]; 918 870 919 871 // Weir flux adjustment 920 adjust_edgeflux_with_weir(edgeflux, h_left_tmp, h_right_tmp, g,872 adjust_edgeflux_with_weir(edgeflux, h_left_tmp, h_right_tmp, D->g, 921 873 weir_height, Qfactor, 922 874 s1, s2, h1, h2); … … 926 878 927 879 // Multiply edgeflux by edgelength 928 length = edgelengths[ki];880 length = D->edgelengths[ki]; 929 881 edgeflux[0] *= length; 930 882 edgeflux[1] *= length; … … 938 890 // edgeflux[1] = 0.; 939 891 // edgeflux[2] = 0.; 940 // //max_speed =0.;892 // //max_speed_local=0.; 941 893 // //pressure_flux=0.; 942 894 //} … … 946 898 // edgeflux[1] = 0.; 947 899 // edgeflux[2] = 0.; 948 // //max_speed =0.;900 // //max_speed_local=0.; 949 901 // //pressure_flux=0.; 950 902 //} 951 903 952 edge_flux_work[ki3 + 0 ] = -edgeflux[0];953 edge_flux_work[ki3 + 1 ] = -edgeflux[1];954 edge_flux_work[ki3 + 2 ] = -edgeflux[2];904 D->edge_flux_work[ki3 + 0 ] = -edgeflux[0]; 905 D->edge_flux_work[ki3 + 1 ] = -edgeflux[1]; 906 D->edge_flux_work[ki3 + 2 ] = -edgeflux[2]; 955 907 956 908 // bedslope_work contains all gravity related terms 957 bedslope_work=length*(- g*0.5*(h_left*h_left - hle*hle -(hle+hc)*(zl-zc))+pressure_flux);958 959 pressuregrad_work[ki]=bedslope_work;909 bedslope_work=length*(- D->g *0.5*(h_left*h_left - hle*hle -(hle+hc)*(zl-zc))+pressure_flux); 910 911 D->pressuregrad_work[ki]=bedslope_work; 960 912 961 already_computed_flux[ki] = call; // #k Done913 D->already_computed_flux[ki] = call; // #k Done 962 914 963 915 // Update neighbour n with same flux but reversed sign 964 916 if (n >= 0) { 965 917 966 edge_flux_work[nm3 + 0 ] = edgeflux[0];967 edge_flux_work[nm3 + 1 ] = edgeflux[1];968 edge_flux_work[nm3 + 2 ] = edgeflux[2];969 bedslope_work=length*(- g*0.5*(h_right*h_right-hre*hre-(hre+hc_n)*(zr-zc_n))+pressure_flux);970 pressuregrad_work[nm]=bedslope_work;971 972 already_computed_flux[nm] = call; // #n Done918 D->edge_flux_work[nm3 + 0 ] = edgeflux[0]; 919 D->edge_flux_work[nm3 + 1 ] = edgeflux[1]; 920 D->edge_flux_work[nm3 + 2 ] = edgeflux[2]; 921 bedslope_work=length*(- D->g *0.5*(h_right*h_right-hre*hre-(hre+hc_n)*(zr-zc_n))+pressure_flux); 922 D->pressuregrad_work[nm]=bedslope_work; 923 924 D->already_computed_flux[nm] = call; // #n Done 973 925 } 974 926 … … 979 931 980 932 // Compute the 'edge-timesteps' (useful for setting flux_update_frequency) 981 edge_timestep[ki] = radii[k] / max(max_speed,epsilon);933 D->edge_timestep[ki] = D->radii[k] / max(max_speed_local, D->epsilon); 982 934 if (n >= 0) { 983 edge_timestep[nm] = radii[n] / max(max_speed,epsilon);935 D->edge_timestep[nm] = D->radii[n] / max(max_speed_local, D->epsilon); 984 936 } 985 937 986 938 // Update the timestep 987 if (( tri_full_flag[k] == 1)) {988 989 speed_max_last=max(speed_max_last, max_speed );990 991 if (max_speed >epsilon) {939 if ((D->tri_full_flag[k] == 1)) { 940 941 speed_max_last=max(speed_max_last, max_speed_local); 942 943 if (max_speed_local > D->epsilon) { 992 944 // Apply CFL condition for triangles joining this edge (triangle k and triangle n) 993 945 994 946 // CFL for triangle k 995 local_timestep = min(local_timestep, edge_timestep[ki]);947 local_timestep = min(local_timestep, D->edge_timestep[ki]); 996 948 997 949 if (n >= 0) { 998 950 // Apply CFL condition for neigbour n (which is on the ith edge of triangle k) 999 local_timestep = min(local_timestep, edge_timestep[nm]);951 local_timestep = min(local_timestep, D->edge_timestep[nm]); 1000 952 } 1001 953 } … … 1005 957 } // End edge i (and neighbour n) 1006 958 // Keep track of maximal speeds 1007 if(substep_count==0) max_speed_array[k] = speed_max_last; //max_speed;959 if(substep_count==0) D->max_speed[k] = speed_max_last; //max_speed; 1008 960 1009 961 … … 1065 1017 1066 1018 // Now add up stage, xmom, ymom explicit updates 1067 for(k=0; k< number_of_elements; k++){1068 hc = max( stage_centroid_values[k] -bed_centroid_values[k],0.);1019 for(k=0; k<D->number_of_elements; k++){ 1020 hc = max(D->stage_centroid_values[k] - D->bed_centroid_values[k],0.); 1069 1021 1070 1022 for(i=0;i<3;i++){ … … 1073 1025 ki2=ki*2; 1074 1026 ki3 = ki*3; 1075 n= neighbours[ki];1027 n=D->neighbours[ki]; 1076 1028 1077 1029 // GD HACK 1078 1030 // Option to limit advective fluxes 1079 1031 //if(hc > H0){ 1080 stage_explicit_update[k] +=edge_flux_work[ki3+0];1081 xmom_explicit_update[k] +=edge_flux_work[ki3+1];1082 ymom_explicit_update[k] +=edge_flux_work[ki3+2];1032 D->stage_explicit_update[k] += D->edge_flux_work[ki3+0]; 1033 D->xmom_explicit_update[k] += D->edge_flux_work[ki3+1]; 1034 D->ymom_explicit_update[k] += D->edge_flux_work[ki3+2]; 1083 1035 //}else{ 1084 1036 // stage_explicit_update[k] += edge_flux_work[ki3+0]; … … 1089 1041 // condition OR a ghost cell, then add the flux to the 1090 1042 // boundary_flux_integral 1091 if( (n<0 & tri_full_flag[k]==1) | ( n>=0 && (tri_full_flag[k]==1 &tri_full_flag[n]==0)) ){1043 if( (n<0 & D->tri_full_flag[k]==1) | ( n>=0 && (D->tri_full_flag[k]==1 & D->tri_full_flag[n]==0)) ){ 1092 1044 // boundary_flux_sum is an array with length = timestep_fluxcalls 1093 1045 // For each sub-step, we put the boundary flux sum in. 1094 boundary_flux_sum[substep_count] +=edge_flux_work[ki3];1046 D->boundary_flux_sum[substep_count] += D->edge_flux_work[ki3]; 1095 1047 } 1096 1048 … … 1098 1050 // Compute bed slope term 1099 1051 //if(hc > H0){ 1100 xmom_explicit_update[k] -= normals[ki2]*pressuregrad_work[ki];1101 ymom_explicit_update[k] -= normals[ki2+1]*pressuregrad_work[ki];1052 D->xmom_explicit_update[k] -= D->normals[ki2]*D->pressuregrad_work[ki]; 1053 D->ymom_explicit_update[k] -= D->normals[ki2+1]*D->pressuregrad_work[ki]; 1102 1054 //}else{ 1103 1055 // xmom_explicit_update[k] *= 0.; … … 1110 1062 // Normalise triangle k by area and store for when all conserved 1111 1063 // quantities get updated 1112 inv_area = 1.0 / areas[k];1113 stage_explicit_update[k] *= inv_area;1114 xmom_explicit_update[k] *= inv_area;1115 ymom_explicit_update[k] *= inv_area;1064 inv_area = 1.0 / D->areas[k]; 1065 D->stage_explicit_update[k] *= inv_area; 1066 D->xmom_explicit_update[k] *= inv_area; 1067 D->ymom_explicit_update[k] *= inv_area; 1116 1068 1117 1069 } // end cell k … … 1242 1194 1243 1195 // Computational routine 1244 int _extrapolate_second_order_edge_sw(int number_of_elements, 1245 double epsilon, 1246 double minimum_allowed_height, 1247 double beta_w, 1248 double beta_w_dry, 1249 double beta_uh, 1250 double beta_uh_dry, 1251 double beta_vh, 1252 double beta_vh_dry, 1253 long* surrogate_neighbours, 1254 long* neighbour_edges, 1255 long* number_of_boundaries, 1256 double* centroid_coordinates, 1257 double* stage_centroid_values, 1258 double* xmom_centroid_values, 1259 double* ymom_centroid_values, 1260 double* elevation_centroid_values, 1261 double* height_centroid_values, 1262 double* edge_coordinates, 1263 double* stage_edge_values, 1264 double* xmom_edge_values, 1265 double* ymom_edge_values, 1266 double* elevation_edge_values, 1267 double* height_edge_values, 1268 double* stage_vertex_values, 1269 double* xmom_vertex_values, 1270 double* ymom_vertex_values, 1271 double* elevation_vertex_values, 1272 double* height_vertex_values, 1273 int optimise_dry_cells, 1274 int extrapolate_velocity_second_order, 1275 double* x_centroid_work, 1276 double* y_centroid_work, 1277 long* update_extrapolation) { 1196 //int _extrapolate_second_order_edge_sw(int number_of_elements, 1197 // double epsilon, 1198 // double minimum_allowed_height, 1199 // double beta_w, 1200 // double beta_w_dry, 1201 // double beta_uh, 1202 // double beta_uh_dry, 1203 // double beta_vh, 1204 // double beta_vh_dry, 1205 // long* surrogate_neighbours, 1206 // long* neighbour_edges, 1207 // long* number_of_boundaries, 1208 // double* centroid_coordinates, 1209 // double* stage_centroid_values, 1210 // double* xmom_centroid_values, 1211 // double* ymom_centroid_values, 1212 // double* bed_centroid_values, 1213 // double* height_centroid_values, 1214 // double* edge_coordinates, 1215 // double* stage_edge_values, 1216 // double* xmom_edge_values, 1217 // double* ymom_edge_values, 1218 // double* bed_edge_values, 1219 // double* height_edge_values, 1220 // double* stage_vertex_values, 1221 // double* xmom_vertex_values, 1222 // double* ymom_vertex_values, 1223 // double* bed_vertex_values, 1224 // double* height_vertex_values, 1225 // int optimise_dry_cells, 1226 // int extrapolate_velocity_second_order, 1227 // double* x_centroid_work, 1228 // double* y_centroid_work, 1229 // long* update_extrapolation) { 1230 int _extrapolate_second_order_edge_sw(struct domain *D){ 1278 1231 1279 1232 // Local variables … … 1287 1240 1288 1241 1289 memset((char*) x_centroid_work, 0,number_of_elements * sizeof (double));1290 memset((char*) y_centroid_work, 0,number_of_elements * sizeof (double));1291 1292 1293 if( extrapolate_velocity_second_order==1){1242 memset((char*) D->x_centroid_work, 0, D->number_of_elements * sizeof (double)); 1243 memset((char*) D->y_centroid_work, 0, D->number_of_elements * sizeof (double)); 1244 1245 1246 if(D->extrapolate_velocity_second_order==1){ 1294 1247 1295 1248 // Replace momentum centroid with velocity centroid to allow velocity 1296 1249 // extrapolation This will be changed back at the end of the routine 1297 for (k=0; k< number_of_elements; k++){1250 for (k=0; k< D->number_of_elements; k++){ 1298 1251 1299 height_centroid_values[k] = max(stage_centroid_values[k] - elevation_centroid_values[k], 0.);1300 1301 dk = height_centroid_values[k];1302 if(dk> minimum_allowed_height){1252 D->height_centroid_values[k] = max(D->stage_centroid_values[k] - D->bed_centroid_values[k], 0.); 1253 1254 dk = D->height_centroid_values[k]; 1255 if(dk> D->minimum_allowed_height){ 1303 1256 dk_inv=1.0/dk; 1304 x_centroid_work[k] =xmom_centroid_values[k];1305 xmom_centroid_values[k] =xmom_centroid_values[k]*dk_inv;1306 1307 y_centroid_work[k] =ymom_centroid_values[k];1308 ymom_centroid_values[k] =ymom_centroid_values[k]*dk_inv;1257 D->x_centroid_work[k] = D->xmom_centroid_values[k]; 1258 D->xmom_centroid_values[k] = D->xmom_centroid_values[k]*dk_inv; 1259 1260 D->y_centroid_work[k] = D->ymom_centroid_values[k]; 1261 D->ymom_centroid_values[k] = D->ymom_centroid_values[k]*dk_inv; 1309 1262 }else{ 1310 x_centroid_work[k] = 0.;1311 xmom_centroid_values[k] = 0.;1312 y_centroid_work[k] = 0.;1313 ymom_centroid_values[k] = 0.;1263 D->x_centroid_work[k] = 0.; 1264 D->xmom_centroid_values[k] = 0.; 1265 D->y_centroid_work[k] = 0.; 1266 D->ymom_centroid_values[k] = 0.; 1314 1267 1315 1268 } … … 1321 1274 // of water being trapped and unable to lose momentum, which can occur in 1322 1275 // some situations 1323 for (k=0; k< number_of_elements;k++){1276 for (k=0; k< D->number_of_elements;k++){ 1324 1277 1325 1278 k3=k*3; 1326 k0 = surrogate_neighbours[k3];1327 k1 = surrogate_neighbours[k3 + 1];1328 k2 = surrogate_neighbours[k3 + 2];1329 1330 if(( height_centroid_values[k0] <minimum_allowed_height | k0==k) &1331 ( height_centroid_values[k1] <minimum_allowed_height | k1==k) &1332 ( height_centroid_values[k2] <minimum_allowed_height | k2==k)){1279 k0 = D->surrogate_neighbours[k3]; 1280 k1 = D->surrogate_neighbours[k3 + 1]; 1281 k2 = D->surrogate_neighbours[k3 + 2]; 1282 1283 if((D->height_centroid_values[k0] < D->minimum_allowed_height | k0==k) & 1284 (D->height_centroid_values[k1] < D->minimum_allowed_height | k1==k) & 1285 (D->height_centroid_values[k2] < D->minimum_allowed_height | k2==k)){ 1333 1286 //printf("Surrounded by dry cells\n"); 1334 x_centroid_work[k] = 0.;1335 xmom_centroid_values[k] = 0.;1336 y_centroid_work[k] = 0.;1337 ymom_centroid_values[k] = 0.;1287 D->x_centroid_work[k] = 0.; 1288 D->xmom_centroid_values[k] = 0.; 1289 D->y_centroid_work[k] = 0.; 1290 D->ymom_centroid_values[k] = 0.; 1338 1291 1339 1292 } … … 1343 1296 1344 1297 // Begin extrapolation routine 1345 for (k = 0; k < number_of_elements; k++)1298 for (k = 0; k < D->number_of_elements; k++) 1346 1299 { 1347 1300 1348 1301 // Don't update the extrapolation if the flux will not be computed on the 1349 1302 // next timestep 1350 if( update_extrapolation[k]==0){1303 if(D->update_extrapolation[k]==0){ 1351 1304 continue; 1352 1305 } … … 1357 1310 k6=k*6; 1358 1311 1359 if ( number_of_boundaries[k]==3)1312 if (D->number_of_boundaries[k]==3) 1360 1313 { 1361 1314 // No neighbours, set gradient on the triangle to zero 1362 1315 1363 stage_edge_values[k3] =stage_centroid_values[k];1364 stage_edge_values[k3+1] =stage_centroid_values[k];1365 stage_edge_values[k3+2] =stage_centroid_values[k];1316 D->stage_edge_values[k3] = D->stage_centroid_values[k]; 1317 D->stage_edge_values[k3+1] = D->stage_centroid_values[k]; 1318 D->stage_edge_values[k3+2] = D->stage_centroid_values[k]; 1366 1319 1367 1320 //xmom_centroid_values[k] = 0.; 1368 1321 //ymom_centroid_values[k] = 0.; 1369 1322 1370 xmom_edge_values[k3] =xmom_centroid_values[k];1371 xmom_edge_values[k3+1] =xmom_centroid_values[k];1372 xmom_edge_values[k3+2] =xmom_centroid_values[k];1373 ymom_edge_values[k3] =ymom_centroid_values[k];1374 ymom_edge_values[k3+1] =ymom_centroid_values[k];1375 ymom_edge_values[k3+2] =ymom_centroid_values[k];1376 1377 dk = height_centroid_values[k];1378 height_edge_values[k3] = dk;1379 height_edge_values[k3+1] = dk;1380 height_edge_values[k3+2] = dk;1323 D->xmom_edge_values[k3] = D->xmom_centroid_values[k]; 1324 D->xmom_edge_values[k3+1] = D->xmom_centroid_values[k]; 1325 D->xmom_edge_values[k3+2] = D->xmom_centroid_values[k]; 1326 D->ymom_edge_values[k3] = D->ymom_centroid_values[k]; 1327 D->ymom_edge_values[k3+1] = D->ymom_centroid_values[k]; 1328 D->ymom_edge_values[k3+2] = D->ymom_centroid_values[k]; 1329 1330 dk = D->height_centroid_values[k]; 1331 D->height_edge_values[k3] = dk; 1332 D->height_edge_values[k3+1] = dk; 1333 D->height_edge_values[k3+2] = dk; 1381 1334 1382 1335 continue; … … 1388 1341 1389 1342 // Get the edge coordinates 1390 xv0 = edge_coordinates[k6];1391 yv0 = edge_coordinates[k6+1];1392 xv1 = edge_coordinates[k6+2];1393 yv1 = edge_coordinates[k6+3];1394 xv2 = edge_coordinates[k6+4];1395 yv2 = edge_coordinates[k6+5];1343 xv0 = D->edge_coordinates[k6]; 1344 yv0 = D->edge_coordinates[k6+1]; 1345 xv1 = D->edge_coordinates[k6+2]; 1346 yv1 = D->edge_coordinates[k6+3]; 1347 xv2 = D->edge_coordinates[k6+4]; 1348 yv2 = D->edge_coordinates[k6+5]; 1396 1349 1397 1350 // Get the centroid coordinates 1398 1351 coord_index = 2*k; 1399 x = centroid_coordinates[coord_index];1400 y = centroid_coordinates[coord_index+1];1352 x = D->centroid_coordinates[coord_index]; 1353 y = D->centroid_coordinates[coord_index+1]; 1401 1354 1402 1355 // Store x- and y- differentials for the edges of … … 1413 1366 1414 1367 1415 if ( number_of_boundaries[k]<=1)1368 if (D->number_of_boundaries[k]<=1) 1416 1369 { 1417 1370 //============================================== … … 1426 1379 // from this centroid and its two neighbours 1427 1380 1428 k0 = surrogate_neighbours[k3];1429 k1 = surrogate_neighbours[k3 + 1];1430 k2 = surrogate_neighbours[k3 + 2];1381 k0 = D->surrogate_neighbours[k3]; 1382 k1 = D->surrogate_neighbours[k3 + 1]; 1383 k2 = D->surrogate_neighbours[k3 + 2]; 1431 1384 1432 1385 … … 1434 1387 // (really the centroids of neighbouring triangles) 1435 1388 coord_index = 2*k0; 1436 x0 = centroid_coordinates[coord_index];1437 y0 = centroid_coordinates[coord_index+1];1389 x0 = D->centroid_coordinates[coord_index]; 1390 y0 = D->centroid_coordinates[coord_index+1]; 1438 1391 1439 1392 coord_index = 2*k1; 1440 x1 = centroid_coordinates[coord_index];1441 y1 = centroid_coordinates[coord_index+1];1393 x1 = D->centroid_coordinates[coord_index]; 1394 y1 = D->centroid_coordinates[coord_index+1]; 1442 1395 1443 1396 coord_index = 2*k2; 1444 x2 = centroid_coordinates[coord_index];1445 y2 = centroid_coordinates[coord_index+1];1397 x2 = D->centroid_coordinates[coord_index]; 1398 y2 = D->centroid_coordinates[coord_index+1]; 1446 1399 1447 1400 // Store x- and y- differentials for the vertices … … 1463 1416 1464 1417 // Isolated wet cell -- constant stage/depth extrapolation 1465 stage_edge_values[k3] =stage_centroid_values[k];1466 stage_edge_values[k3+1] =stage_centroid_values[k];1467 stage_edge_values[k3+2] =stage_centroid_values[k];1468 1469 dk= height_centroid_values[k]; //max(stage_centroid_values[k]-elevation_centroid_values[k],0.);1470 height_edge_values[k3] = dk;1471 height_edge_values[k3+1] = dk;1472 height_edge_values[k3+2] = dk;1418 D->stage_edge_values[k3] = D->stage_centroid_values[k]; 1419 D->stage_edge_values[k3+1] = D->stage_centroid_values[k]; 1420 D->stage_edge_values[k3+2] = D->stage_centroid_values[k]; 1421 1422 dk= D->height_centroid_values[k]; //max(stage_centroid_values[k]-bed_centroid_values[k],0.); 1423 D->height_edge_values[k3] = dk; 1424 D->height_edge_values[k3+1] = dk; 1425 D->height_edge_values[k3+2] = dk; 1473 1426 1474 xmom_edge_values[k3] =xmom_centroid_values[k];1475 xmom_edge_values[k3+1] =xmom_centroid_values[k];1476 xmom_edge_values[k3+2] =xmom_centroid_values[k];1477 ymom_edge_values[k3] =ymom_centroid_values[k];1478 ymom_edge_values[k3+1] =ymom_centroid_values[k];1479 ymom_edge_values[k3+2] =ymom_centroid_values[k];1427 D->xmom_edge_values[k3] = D->xmom_centroid_values[k]; 1428 D->xmom_edge_values[k3+1] = D->xmom_centroid_values[k]; 1429 D->xmom_edge_values[k3+2] = D->xmom_centroid_values[k]; 1430 D->ymom_edge_values[k3] = D->ymom_centroid_values[k]; 1431 D->ymom_edge_values[k3+1] = D->ymom_centroid_values[k]; 1432 D->ymom_edge_values[k3+2] = D->ymom_centroid_values[k]; 1480 1433 1481 1434 continue; … … 1483 1436 1484 1437 // Calculate heights of neighbouring cells 1485 hc = height_centroid_values[k];1486 h0 = height_centroid_values[k0];1487 h1 = height_centroid_values[k1];1488 h2 = height_centroid_values[k2];1438 hc = D->height_centroid_values[k]; 1439 h0 = D->height_centroid_values[k0]; 1440 h1 = D->height_centroid_values[k1]; 1441 h2 = D->height_centroid_values[k2]; 1489 1442 1490 1443 hmin = min(min(h0, min(h1, h2)), hc); … … 1507 1460 // Set hfactor to zero smothly as hmin--> minimum_allowed_height. This 1508 1461 // avoids some 'chatter' for very shallow flows 1509 hfactor=min( 1.2*max(hmin- minimum_allowed_height,0.)/(max(hmin,0.)+1.*minimum_allowed_height), hfactor);1462 hfactor=min( 1.2*max(hmin- D->minimum_allowed_height,0.)/(max(hmin,0.)+1.* D->minimum_allowed_height), hfactor); 1510 1463 1511 1464 inv_area2 = 1.0/area2; … … 1514 1467 //----------------------------------- 1515 1468 1516 beta_tmp = beta_w_dry + (beta_w -beta_w_dry) * hfactor;1469 beta_tmp = D->beta_w_dry + (D->beta_w - D->beta_w_dry) * hfactor; 1517 1470 1518 1471 if(beta_tmp>0.){ 1519 1472 // Calculate the difference between vertex 0 of the auxiliary 1520 1473 // triangle and the centroid of triangle k 1521 dq0 = stage_centroid_values[k0] -stage_centroid_values[k];1474 dq0 = D->stage_centroid_values[k0] - D->stage_centroid_values[k]; 1522 1475 1523 1476 // Calculate differentials between the vertices 1524 1477 // of the auxiliary triangle (centroids of neighbouring triangles) 1525 dq1 = stage_centroid_values[k1] -stage_centroid_values[k0];1526 dq2 = stage_centroid_values[k2] -stage_centroid_values[k0];1478 dq1 = D->stage_centroid_values[k1] - D->stage_centroid_values[k0]; 1479 dq2 = D->stage_centroid_values[k2] - D->stage_centroid_values[k0]; 1527 1480 1528 1481 // Calculate the gradient of stage on the auxiliary triangle … … 1545 1498 limit_gradient(dqv, qmin, qmax, beta_tmp); 1546 1499 1547 stage_edge_values[k3+0] =stage_centroid_values[k] + dqv[0];1548 stage_edge_values[k3+1] =stage_centroid_values[k] + dqv[1];1549 stage_edge_values[k3+2] =stage_centroid_values[k] + dqv[2];1500 D->stage_edge_values[k3+0] = D->stage_centroid_values[k] + dqv[0]; 1501 D->stage_edge_values[k3+1] = D->stage_centroid_values[k] + dqv[1]; 1502 D->stage_edge_values[k3+2] = D->stage_centroid_values[k] + dqv[2]; 1550 1503 }else{ 1551 1504 // Fast alternative when beta_tmp==0 1552 stage_edge_values[k3+0] =stage_centroid_values[k];1553 stage_edge_values[k3+1] =stage_centroid_values[k];1554 stage_edge_values[k3+2] =stage_centroid_values[k];1505 D->stage_edge_values[k3+0] = D->stage_centroid_values[k]; 1506 D->stage_edge_values[k3+1] = D->stage_centroid_values[k]; 1507 D->stage_edge_values[k3+2] = D->stage_centroid_values[k]; 1555 1508 } 1556 1509 … … 1563 1516 // Calculate the difference between vertex 0 of the auxiliary 1564 1517 // triangle and the centroid of triangle k 1565 dq0 = height_centroid_values[k0] -height_centroid_values[k];1518 dq0 = D->height_centroid_values[k0] - D->height_centroid_values[k]; 1566 1519 1567 1520 // Calculate differentials between the vertices 1568 1521 // of the auxiliary triangle (centroids of neighbouring triangles) 1569 dq1 = height_centroid_values[k1] -height_centroid_values[k0];1570 dq2 = height_centroid_values[k2] -height_centroid_values[k0];1522 dq1 = D->height_centroid_values[k1] - D->height_centroid_values[k0]; 1523 dq2 = D->height_centroid_values[k2] - D->height_centroid_values[k0]; 1571 1524 1572 1525 // Calculate the gradient of height on the auxiliary triangle … … 1593 1546 //beta_tmp = 0. + (beta_w - 0.) * hfactor; 1594 1547 1595 height_edge_values[k3+0] =height_centroid_values[k] + dqv[0];1596 height_edge_values[k3+1] =height_centroid_values[k] + dqv[1];1597 height_edge_values[k3+2] =height_centroid_values[k] + dqv[2];1548 D->height_edge_values[k3+0] = D->height_centroid_values[k] + dqv[0]; 1549 D->height_edge_values[k3+1] = D->height_centroid_values[k] + dqv[1]; 1550 D->height_edge_values[k3+2] = D->height_centroid_values[k] + dqv[2]; 1598 1551 }else{ 1599 1552 // Fast alternative when beta_tmp==0 1600 height_edge_values[k3+0] =height_centroid_values[k];1601 height_edge_values[k3+1] =height_centroid_values[k];1602 height_edge_values[k3+2] =height_centroid_values[k];1553 D->height_edge_values[k3+0] = D->height_centroid_values[k]; 1554 D->height_edge_values[k3+1] = D->height_centroid_values[k]; 1555 D->height_edge_values[k3+2] = D->height_centroid_values[k]; 1603 1556 } 1604 1557 //----------------------------------- … … 1606 1559 //----------------------------------- 1607 1560 1608 beta_tmp = beta_uh_dry + (beta_uh -beta_uh_dry) * hfactor;1561 beta_tmp = D->beta_uh_dry + (D->beta_uh - D->beta_uh_dry) * hfactor; 1609 1562 if(beta_tmp>0.){ 1610 1563 // Calculate the difference between vertex 0 of the auxiliary 1611 1564 // triangle and the centroid of triangle k 1612 dq0 = xmom_centroid_values[k0] -xmom_centroid_values[k];1565 dq0 = D->xmom_centroid_values[k0] - D->xmom_centroid_values[k]; 1613 1566 1614 1567 // Calculate differentials between the vertices 1615 1568 // of the auxiliary triangle 1616 dq1 = xmom_centroid_values[k1] -xmom_centroid_values[k0];1617 dq2 = xmom_centroid_values[k2] -xmom_centroid_values[k0];1569 dq1 = D->xmom_centroid_values[k1] - D->xmom_centroid_values[k0]; 1570 dq2 = D->xmom_centroid_values[k2] - D->xmom_centroid_values[k0]; 1618 1571 1619 1572 // Calculate the gradient of xmom on the auxiliary triangle … … 1641 1594 for (i=0; i < 3; i++) 1642 1595 { 1643 xmom_edge_values[k3+i] =xmom_centroid_values[k] + dqv[i];1596 D->xmom_edge_values[k3+i] = D->xmom_centroid_values[k] + dqv[i]; 1644 1597 } 1645 1598 }else{ … … 1647 1600 for (i=0; i < 3; i++) 1648 1601 { 1649 xmom_edge_values[k3+i] =xmom_centroid_values[k];1602 D->xmom_edge_values[k3+i] = D->xmom_centroid_values[k]; 1650 1603 } 1651 1604 } … … 1655 1608 //----------------------------------- 1656 1609 1657 beta_tmp = beta_vh_dry + (beta_vh -beta_vh_dry) * hfactor;1610 beta_tmp = D->beta_vh_dry + (D->beta_vh - D->beta_vh_dry) * hfactor; 1658 1611 1659 1612 if(beta_tmp>0.){ 1660 1613 // Calculate the difference between vertex 0 of the auxiliary 1661 1614 // triangle and the centroid of triangle k 1662 dq0 = ymom_centroid_values[k0] -ymom_centroid_values[k];1615 dq0 = D->ymom_centroid_values[k0] - D->ymom_centroid_values[k]; 1663 1616 1664 1617 // Calculate differentials between the vertices 1665 1618 // of the auxiliary triangle 1666 dq1 = ymom_centroid_values[k1] -ymom_centroid_values[k0];1667 dq2 = ymom_centroid_values[k2] -ymom_centroid_values[k0];1619 dq1 = D->ymom_centroid_values[k1] - D->ymom_centroid_values[k0]; 1620 dq2 = D->ymom_centroid_values[k2] - D->ymom_centroid_values[k0]; 1668 1621 1669 1622 // Calculate the gradient of xmom on the auxiliary triangle … … 1691 1644 for (i=0;i<3;i++) 1692 1645 { 1693 ymom_edge_values[k3 + i] =ymom_centroid_values[k] + dqv[i];1646 D->ymom_edge_values[k3 + i] = D->ymom_centroid_values[k] + dqv[i]; 1694 1647 } 1695 1648 }else{ … … 1697 1650 for (i=0;i<3;i++) 1698 1651 { 1699 ymom_edge_values[k3 + i] =ymom_centroid_values[k];1652 D->ymom_edge_values[k3 + i] = D->ymom_centroid_values[k]; 1700 1653 } 1701 1654 … … 1718 1671 // k2 indexes the edges of triangle k 1719 1672 1720 if ( surrogate_neighbours[k2] != k)1673 if (D->surrogate_neighbours[k2] != k) 1721 1674 { 1722 1675 break; … … 1731 1684 } 1732 1685 1733 k1 = surrogate_neighbours[k2];1686 k1 = D->surrogate_neighbours[k2]; 1734 1687 1735 1688 // The coordinates of the triangle are already (x,y). 1736 1689 // Get centroid of the neighbour (x1,y1) 1737 1690 coord_index = 2*k1; 1738 x1 = centroid_coordinates[coord_index];1739 y1 = centroid_coordinates[coord_index + 1];1691 x1 = D->centroid_coordinates[coord_index]; 1692 y1 = D->centroid_coordinates[coord_index + 1]; 1740 1693 1741 1694 // Compute x- and y- distances between the centroid of … … 1761 1714 1762 1715 // Compute differentials 1763 dq1 = stage_centroid_values[k1] -stage_centroid_values[k];1716 dq1 = D->stage_centroid_values[k1] - D->stage_centroid_values[k]; 1764 1717 1765 1718 // Calculate the gradient between the centroid of triangle k … … 1786 1739 1787 1740 // Limit the gradient 1788 limit_gradient(dqv, qmin, qmax, beta_w);1789 1790 stage_edge_values[k3] =stage_centroid_values[k] + dqv[0];1791 stage_edge_values[k3 + 1] =stage_centroid_values[k] + dqv[1];1792 stage_edge_values[k3 + 2] =stage_centroid_values[k] + dqv[2];1741 limit_gradient(dqv, qmin, qmax, D->beta_w); 1742 1743 D->stage_edge_values[k3] = D->stage_centroid_values[k] + dqv[0]; 1744 D->stage_edge_values[k3 + 1] = D->stage_centroid_values[k] + dqv[1]; 1745 D->stage_edge_values[k3 + 2] = D->stage_centroid_values[k] + dqv[2]; 1793 1746 1794 1747 //----------------------------------- … … 1797 1750 1798 1751 // Compute differentials 1799 dq1 = height_centroid_values[k1] -height_centroid_values[k];1752 dq1 = D->height_centroid_values[k1] - D->height_centroid_values[k]; 1800 1753 1801 1754 // Calculate the gradient between the centroid of triangle k … … 1822 1775 1823 1776 // Limit the gradient 1824 limit_gradient(dqv, qmin, qmax, beta_w);1825 1826 height_edge_values[k3] =height_centroid_values[k] + dqv[0];1827 height_edge_values[k3 + 1] =height_centroid_values[k] + dqv[1];1828 height_edge_values[k3 + 2] =height_centroid_values[k] + dqv[2];1777 limit_gradient(dqv, qmin, qmax, D->beta_w); 1778 1779 D->height_edge_values[k3] = D->height_centroid_values[k] + dqv[0]; 1780 D->height_edge_values[k3 + 1] = D->height_centroid_values[k] + dqv[1]; 1781 D->height_edge_values[k3 + 2] = D->height_centroid_values[k] + dqv[2]; 1829 1782 1830 1783 //----------------------------------- … … 1833 1786 1834 1787 // Compute differentials 1835 dq1 = xmom_centroid_values[k1] -xmom_centroid_values[k];1788 dq1 = D->xmom_centroid_values[k1] - D->xmom_centroid_values[k]; 1836 1789 1837 1790 // Calculate the gradient between the centroid of triangle k … … 1858 1811 1859 1812 // Limit the gradient 1860 limit_gradient(dqv, qmin, qmax, beta_w);1813 limit_gradient(dqv, qmin, qmax, D->beta_w); 1861 1814 1862 1815 for (i = 0; i < 3;i++) 1863 1816 { 1864 xmom_edge_values[k3 + i] =xmom_centroid_values[k] + dqv[i];1817 D->xmom_edge_values[k3 + i] = D->xmom_centroid_values[k] + dqv[i]; 1865 1818 } 1866 1819 … … 1870 1823 1871 1824 // Compute differentials 1872 dq1 = ymom_centroid_values[k1] -ymom_centroid_values[k];1825 dq1 = D->ymom_centroid_values[k1] - D->ymom_centroid_values[k]; 1873 1826 1874 1827 // Calculate the gradient between the centroid of triangle k … … 1895 1848 1896 1849 // Limit the gradient 1897 limit_gradient(dqv, qmin, qmax, beta_w);1850 limit_gradient(dqv, qmin, qmax, D->beta_w); 1898 1851 1899 1852 for (i=0;i<3;i++) 1900 1853 { 1901 ymom_edge_values[k3 + i] =ymom_centroid_values[k] + dqv[i];1854 D->ymom_edge_values[k3 + i] = D->ymom_centroid_values[k] + dqv[i]; 1902 1855 } 1903 1856 } // else [number_of_boundaries==2] … … 1906 1859 1907 1860 // Compute vertex values of quantities 1908 for (k=0; k< number_of_elements; k++){1909 if( extrapolate_velocity_second_order==1){1861 for (k=0; k< D->number_of_elements; k++){ 1862 if(D->extrapolate_velocity_second_order==1){ 1910 1863 //Convert velocity back to momenta at centroids 1911 xmom_centroid_values[k] =x_centroid_work[k];1912 ymom_centroid_values[k] =y_centroid_work[k];1864 D->xmom_centroid_values[k] = D->x_centroid_work[k]; 1865 D->ymom_centroid_values[k] = D->y_centroid_work[k]; 1913 1866 } 1914 1867 1915 1868 // Don't proceed if we didn't update the edge/vertex values 1916 if( update_extrapolation[k]==0){1869 if(D->update_extrapolation[k]==0){ 1917 1870 continue; 1918 1871 } … … 1921 1874 1922 1875 // Compute stage vertex values 1923 stage_vertex_values[k3] = stage_edge_values[k3+1] + stage_edge_values[k3+2] -stage_edge_values[k3] ;1924 stage_vertex_values[k3+1] = stage_edge_values[k3] + stage_edge_values[k3+2]-stage_edge_values[k3+1];1925 stage_vertex_values[k3+2] = stage_edge_values[k3] + stage_edge_values[k3+1]-stage_edge_values[k3+2];1876 D->stage_vertex_values[k3] = D->stage_edge_values[k3+1] + D->stage_edge_values[k3+2] - D->stage_edge_values[k3] ; 1877 D->stage_vertex_values[k3+1] = D->stage_edge_values[k3] + D->stage_edge_values[k3+2]- D->stage_edge_values[k3+1]; 1878 D->stage_vertex_values[k3+2] = D->stage_edge_values[k3] + D->stage_edge_values[k3+1]- D->stage_edge_values[k3+2]; 1926 1879 1927 1880 // Compute height vertex values 1928 height_vertex_values[k3] = height_edge_values[k3+1] + height_edge_values[k3+2] -height_edge_values[k3] ;1929 height_vertex_values[k3+1] = height_edge_values[k3] + height_edge_values[k3+2]-height_edge_values[k3+1];1930 height_vertex_values[k3+2] = height_edge_values[k3] + height_edge_values[k3+1]-height_edge_values[k3+2];1881 D->height_vertex_values[k3] = D->height_edge_values[k3+1] + D->height_edge_values[k3+2] - D->height_edge_values[k3] ; 1882 D->height_vertex_values[k3+1] = D->height_edge_values[k3] + D->height_edge_values[k3+2]- D->height_edge_values[k3+1]; 1883 D->height_vertex_values[k3+2] = D->height_edge_values[k3] + D->height_edge_values[k3+1]- D->height_edge_values[k3+2]; 1931 1884 1932 1885 // If needed, convert from velocity to momenta 1933 if( extrapolate_velocity_second_order==1){1886 if(D->extrapolate_velocity_second_order==1){ 1934 1887 // Re-compute momenta at edges 1935 1888 for (i=0; i<3; i++){ 1936 dk= height_edge_values[k3+i];1937 xmom_edge_values[k3+i]=xmom_edge_values[k3+i]*dk;1938 ymom_edge_values[k3+i]=ymom_edge_values[k3+i]*dk;1889 dk= D->height_edge_values[k3+i]; 1890 D->xmom_edge_values[k3+i] = D->xmom_edge_values[k3+i]*dk; 1891 D->ymom_edge_values[k3+i] = D->ymom_edge_values[k3+i]*dk; 1939 1892 } 1940 1893 } 1941 1894 // Compute momenta at vertices 1942 xmom_vertex_values[k3] = xmom_edge_values[k3+1] + xmom_edge_values[k3+2] -xmom_edge_values[k3] ;1943 xmom_vertex_values[k3+1] = xmom_edge_values[k3] + xmom_edge_values[k3+2]-xmom_edge_values[k3+1];1944 xmom_vertex_values[k3+2] = xmom_edge_values[k3] + xmom_edge_values[k3+1]-xmom_edge_values[k3+2];1945 ymom_vertex_values[k3] = ymom_edge_values[k3+1] + ymom_edge_values[k3+2] -ymom_edge_values[k3] ;1946 ymom_vertex_values[k3+1] = ymom_edge_values[k3] + ymom_edge_values[k3+2]-ymom_edge_values[k3+1];1947 ymom_vertex_values[k3+2] = ymom_edge_values[k3] + ymom_edge_values[k3+1]-ymom_edge_values[k3+2];1895 D->xmom_vertex_values[k3] = D->xmom_edge_values[k3+1] + D->xmom_edge_values[k3+2] - D->xmom_edge_values[k3] ; 1896 D->xmom_vertex_values[k3+1] = D->xmom_edge_values[k3] + D->xmom_edge_values[k3+2]- D->xmom_edge_values[k3+1]; 1897 D->xmom_vertex_values[k3+2] = D->xmom_edge_values[k3] + D->xmom_edge_values[k3+1]- D->xmom_edge_values[k3+2]; 1898 D->ymom_vertex_values[k3] = D->ymom_edge_values[k3+1] + D->ymom_edge_values[k3+2] - D->ymom_edge_values[k3] ; 1899 D->ymom_vertex_values[k3+1] = D->ymom_edge_values[k3] + D->ymom_edge_values[k3+2]- D->ymom_edge_values[k3+1]; 1900 D->ymom_vertex_values[k3+2] = D->ymom_edge_values[k3] + D->ymom_edge_values[k3+1]- D->ymom_edge_values[k3+2]; 1948 1901 1949 1902 // Compute new bed elevation 1950 elevation_edge_values[k3]=stage_edge_values[k3]-height_edge_values[k3];1951 elevation_edge_values[k3+1]=stage_edge_values[k3+1]-height_edge_values[k3+1];1952 elevation_edge_values[k3+2]=stage_edge_values[k3+2]-height_edge_values[k3+2];1953 elevation_vertex_values[k3] = elevation_edge_values[k3+1] + elevation_edge_values[k3+2] -elevation_edge_values[k3] ;1954 elevation_vertex_values[k3+1] = elevation_edge_values[k3] + elevation_edge_values[k3+2]-elevation_edge_values[k3+1];1955 elevation_vertex_values[k3+2] = elevation_edge_values[k3] + elevation_edge_values[k3+1]-elevation_edge_values[k3+2];1903 D->bed_edge_values[k3]= D->stage_edge_values[k3]- D->height_edge_values[k3]; 1904 D->bed_edge_values[k3+1]= D->stage_edge_values[k3+1]- D->height_edge_values[k3+1]; 1905 D->bed_edge_values[k3+2]= D->stage_edge_values[k3+2]- D->height_edge_values[k3+2]; 1906 D->bed_vertex_values[k3] = D->bed_edge_values[k3+1] + D->bed_edge_values[k3+2] - D->bed_edge_values[k3] ; 1907 D->bed_vertex_values[k3+1] = D->bed_edge_values[k3] + D->bed_edge_values[k3+2] - D->bed_edge_values[k3+1]; 1908 D->bed_vertex_values[k3+2] = D->bed_edge_values[k3] + D->bed_edge_values[k3+1] - D->bed_edge_values[k3+2]; 1956 1909 } 1957 1910 … … 1984 1937 is converted to a timestep that must not be exceeded. The minimum of 1985 1938 those is computed as the next overall timestep. 1986 1987 Python call:1988 domain.timestep = compute_fluxes(timestep,1989 domain.epsilon,1990 domain.H0,1991 domain.g,1992 domain.neighbours,1993 domain.neighbour_edges,1994 domain.normals,1995 domain.edgelengths,1996 domain.radii,1997 domain.areas,1998 tri_full_flag,1999 Stage.edge_values,2000 Xmom.edge_values,2001 Ymom.edge_values,2002 Bed.edge_values,2003 Stage.boundary_values,2004 Xmom.boundary_values,2005 Ymom.boundary_values,2006 Stage.explicit_update,2007 Xmom.explicit_update,2008 Ymom.explicit_update,2009 already_computed_flux,2010 optimise_dry_cells,2011 stage.centroid_values,2012 bed.centroid_values,2013 domain.riverwall_elevation)2014 2015 2016 Post conditions:2017 domain.explicit_update is reset to computed flux values2018 domain.timestep is set to the largest step satisfying all volumes.2019 2020 2021 1939 */ 2022 2023 2024 PyArrayObject *boundary_flux_sum, *neighbours, *neighbour_edges, 2025 *normals, *edgelengths, *radii, *areas, 2026 *tri_full_flag, 2027 *stage_edge_values, 2028 *xmom_edge_values, 2029 *ymom_edge_values, 2030 *bed_edge_values, 2031 *height_edge_values, 2032 *stage_boundary_values, 2033 *xmom_boundary_values, 2034 *ymom_boundary_values, 2035 *boundary_flux_type, 2036 *stage_explicit_update, 2037 *xmom_explicit_update, 2038 *ymom_explicit_update, 2039 *already_computed_flux, //Tracks whether the flux across an edge has already been computed 2040 *max_speed_array, //Keeps track of max speeds for each triangle 2041 *stage_centroid_values, 2042 *xmom_centroid_values, 2043 *ymom_centroid_values, 2044 *bed_centroid_values, 2045 *height_centroid_values, 2046 *bed_vertex_values, 2047 *edge_flux_type, 2048 *riverwall_elevation, 2049 *riverwall_rowIndex, 2050 *riverwall_hydraulic_properties, 2051 *edge_flux_work, 2052 *pressuregrad_work, 2053 *edge_timestep, 2054 *update_next_flux, 2055 *allow_timestep_increase; 1940 struct domain D; 1941 PyObject *domain; 1942 1943 1944 double timestep; 1945 1946 if (!PyArg_ParseTuple(args, "Od", &domain, ×tep)) { 1947 report_python_error(AT, "could not parse input arguments"); 1948 return NULL; 1949 } 2056 1950 2057 double timestep, epsilon, H0, g; 2058 int optimise_dry_cells, timestep_fluxcalls, ncol_riverwall_hydraulic_properties; 2059 2060 2061 // Convert Python arguments to C 2062 if (!PyArg_ParseTuple(args, "ddddOOOOOOOOOOOOOOOOOOOOOOiiOOOOOOOOiOOOOOO", 2063 ×tep, 2064 &epsilon, 2065 &H0, 2066 &g, 2067 &boundary_flux_sum, 2068 &neighbours, 2069 &neighbour_edges, 2070 &normals, 2071 &edgelengths, &radii, &areas, 2072 &tri_full_flag, 2073 &stage_edge_values, 2074 &xmom_edge_values, 2075 &ymom_edge_values, 2076 &bed_edge_values, 2077 &height_edge_values, 2078 &stage_boundary_values, 2079 &xmom_boundary_values, 2080 &ymom_boundary_values, 2081 &boundary_flux_type, 2082 &stage_explicit_update, 2083 &xmom_explicit_update, 2084 &ymom_explicit_update, 2085 &already_computed_flux, 2086 &max_speed_array, 2087 &optimise_dry_cells, 2088 ×tep_fluxcalls, 2089 &stage_centroid_values, 2090 &xmom_centroid_values, 2091 &ymom_centroid_values, 2092 &bed_centroid_values, 2093 &height_centroid_values, 2094 //&bed_vertex_values, 2095 &edge_flux_type, 2096 &riverwall_elevation, 2097 &riverwall_rowIndex, 2098 &ncol_riverwall_hydraulic_properties, 2099 &riverwall_hydraulic_properties, 2100 &edge_flux_work, 2101 &pressuregrad_work, 2102 &edge_timestep, 2103 &update_next_flux, 2104 &allow_timestep_increase 2105 )) { 2106 report_python_error(AT, "could not parse input arguments"); 2107 return NULL; 2108 } 2109 2110 // check that numpy array objects arrays are C contiguous memory 2111 CHECK_C_CONTIG(neighbours); 2112 CHECK_C_CONTIG(neighbour_edges); 2113 CHECK_C_CONTIG(normals); 2114 CHECK_C_CONTIG(edgelengths); 2115 CHECK_C_CONTIG(radii); 2116 CHECK_C_CONTIG(areas); 2117 CHECK_C_CONTIG(tri_full_flag); 2118 CHECK_C_CONTIG(stage_edge_values); 2119 CHECK_C_CONTIG(xmom_edge_values); 2120 CHECK_C_CONTIG(ymom_edge_values); 2121 CHECK_C_CONTIG(bed_edge_values); 2122 CHECK_C_CONTIG(height_edge_values); 2123 CHECK_C_CONTIG(stage_boundary_values); 2124 CHECK_C_CONTIG(xmom_boundary_values); 2125 CHECK_C_CONTIG(ymom_boundary_values); 2126 CHECK_C_CONTIG(boundary_flux_type); 2127 CHECK_C_CONTIG(stage_explicit_update); 2128 CHECK_C_CONTIG(xmom_explicit_update); 2129 CHECK_C_CONTIG(ymom_explicit_update); 2130 CHECK_C_CONTIG(already_computed_flux); 2131 CHECK_C_CONTIG(max_speed_array); 2132 CHECK_C_CONTIG(stage_centroid_values); 2133 CHECK_C_CONTIG(xmom_centroid_values); 2134 CHECK_C_CONTIG(ymom_centroid_values); 2135 CHECK_C_CONTIG(bed_centroid_values); 2136 CHECK_C_CONTIG(height_centroid_values); 2137 //CHECK_C_CONTIG(bed_vertex_values); 2138 CHECK_C_CONTIG(edge_flux_type); 2139 CHECK_C_CONTIG(riverwall_elevation); 2140 CHECK_C_CONTIG(riverwall_rowIndex); 2141 CHECK_C_CONTIG(riverwall_hydraulic_properties); 2142 CHECK_C_CONTIG(edge_flux_work); 2143 CHECK_C_CONTIG(pressuregrad_work); 2144 CHECK_C_CONTIG(edge_timestep); 2145 CHECK_C_CONTIG(update_next_flux); 2146 CHECK_C_CONTIG(allow_timestep_increase); 2147 2148 int number_of_elements = stage_edge_values -> dimensions[0]; 2149 2150 // Call underlying flux computation routine and update 2151 // the explicit update arrays 2152 timestep = _compute_fluxes_central(number_of_elements, 2153 timestep, 2154 epsilon, 2155 H0, 2156 g, 2157 (double*) boundary_flux_sum -> data, 2158 (long*) neighbours -> data, 2159 (long*) neighbour_edges -> data, 2160 (double*) normals -> data, 2161 (double*) edgelengths -> data, 2162 (double*) radii -> data, 2163 (double*) areas -> data, 2164 (long*) tri_full_flag -> data, 2165 (double*) stage_edge_values -> data, 2166 (double*) xmom_edge_values -> data, 2167 (double*) ymom_edge_values -> data, 2168 (double*) bed_edge_values -> data, 2169 (double*) height_edge_values -> data, 2170 (double*) stage_boundary_values -> data, 2171 (double*) xmom_boundary_values -> data, 2172 (double*) ymom_boundary_values -> data, 2173 (long*) boundary_flux_type -> data, 2174 (double*) stage_explicit_update -> data, 2175 (double*) xmom_explicit_update -> data, 2176 (double*) ymom_explicit_update -> data, 2177 (long*) already_computed_flux -> data, 2178 (double*) max_speed_array -> data, 2179 optimise_dry_cells, 2180 timestep_fluxcalls, 2181 (double*) stage_centroid_values -> data, 2182 (double*) xmom_centroid_values -> data, 2183 (double*) ymom_centroid_values -> data, 2184 (double*) bed_centroid_values -> data, 2185 (double*) height_centroid_values -> data, 2186 //(double*) bed_vertex_values -> data, 2187 (long*) edge_flux_type-> data, 2188 (double*) riverwall_elevation-> data, 2189 (long*) riverwall_rowIndex-> data, 2190 ncol_riverwall_hydraulic_properties, 2191 (double*) riverwall_hydraulic_properties ->data, 2192 (double*) edge_flux_work-> data, 2193 (double*) pressuregrad_work->data, 2194 (double*) edge_timestep->data, 2195 (long*) update_next_flux->data, 2196 (long*) allow_timestep_increase->data 2197 ); 1951 get_python_domain(&D,domain); 1952 1953 timestep=_compute_fluxes_central(&D,timestep); 1954 2198 1955 // Return updated flux timestep 2199 1956 return Py_BuildValue("d", timestep); … … 2324 2081 2325 2082 PyObject *compute_flux_update_frequency(PyObject *self, PyObject *args) { 2326 /*Compute how often we should update fluxes and extrapolations (not every timestep) 2327 2328 python_call 2329 compute_flux_update_frequency_ext( 2330 self.timestep, 2331 self.neighbours, 2332 self.neighbour_edges, 2333 self.already_computed_flux, 2334 self.edge_timestep, 2335 self.flux_update_frequency, 2336 self.update_extrapolation, 2337 self.max_flux_update_frequency, 2338 self.update_next_flux) 2339 2340 2083 /* 2084 2085 Compute how often we should update fluxes and extrapolations (perhaps not every timestep) 2341 2086 2342 2087 */ 2343 2088 2344 2345 PyArrayObject *neighbours, *neighbour_edges, 2346 *already_computed_flux, //Tracks whether the flux across an edge has already been computed 2347 *edge_timestep, 2348 *flux_update_frequency, 2349 *update_extrapolation, 2350 *update_next_flux, 2351 *allow_timestep_increase; 2089 struct domain D; 2090 PyObject *domain; 2091 2352 2092 2353 2093 double timestep; 2354 2094 int max_flux_update_frequency; 2355 2095 2096 if (!PyArg_ParseTuple(args, "Od", &domain, ×tep)) { 2097 report_python_error(AT, "could not parse input arguments"); 2098 return NULL; 2099 } 2356 2100 2357 // Convert Python arguments to C 2358 if (!PyArg_ParseTuple(args, "dOOOOOOiOO", 2359 ×tep, 2360 &neighbours, 2361 &neighbour_edges, 2362 &already_computed_flux, 2363 &edge_timestep, 2364 &flux_update_frequency, 2365 &update_extrapolation, 2366 &max_flux_update_frequency, 2367 &update_next_flux, 2368 &allow_timestep_increase 2369 )) { 2370 report_python_error(AT, "could not parse input arguments"); 2371 return NULL; 2372 } 2373 2374 // check that numpy array objects arrays are C contiguous memory 2375 CHECK_C_CONTIG(neighbours); 2376 CHECK_C_CONTIG(neighbour_edges); 2377 CHECK_C_CONTIG(already_computed_flux); 2378 CHECK_C_CONTIG(edge_timestep); 2379 CHECK_C_CONTIG(flux_update_frequency); 2380 CHECK_C_CONTIG(update_extrapolation); 2381 CHECK_C_CONTIG(update_next_flux); 2382 CHECK_C_CONTIG(allow_timestep_increase); 2383 2384 int number_of_elements = update_extrapolation -> dimensions[0]; 2385 // flux_update_frequency determined by rounding edge_timestep/timestep*notSoFast 2386 // So notSoFast<1 might increase the number of flux calls a cell has to do, but 2387 // can be useful for increasing numerical stability 2388 double notSoFast=1.00; 2389 2390 // Call underlying flux computation routine and update 2391 // the explicit update arrays 2392 _compute_flux_update_frequency(number_of_elements, 2393 (long*) neighbours->data, 2394 (long*) neighbour_edges->data, 2395 (long*) already_computed_flux->data, 2396 max_flux_update_frequency, 2397 (double*) edge_timestep->data, 2398 timestep, 2399 notSoFast, 2400 (long*) flux_update_frequency->data, 2401 (long*) update_extrapolation->data, 2402 (long*) update_next_flux->data, 2403 (long*) allow_timestep_increase->data 2404 ); 2101 get_python_domain(&D,domain); 2102 2103 _compute_flux_update_frequency(&D, timestep); 2104 2405 2105 // Return 2406 2106 return Py_BuildValue(""); … … 2412 2112 on each triangle 2413 2113 2414 Python call:2415 extrapolate_second_order_sw(domain.surrogate_neighbours,2416 domain.number_of_boundaries2417 domain.centroid_coordinates,2418 Stage.centroid_values2419 Xmom.centroid_values2420 Ymom.centroid_values2421 domain.edge_coordinates,2422 Stage.edge_values,2423 Xmom.edge_values,2424 Ymom.edge_values)2425 2426 2114 Post conditions: 2427 2115 The edges of each triangle have values from a … … 2430 2118 2431 2119 */ 2432 PyArrayObject *surrogate_neighbours, 2433 *neighbour_edges, 2434 *number_of_boundaries, 2435 *centroid_coordinates, 2436 *stage_centroid_values, 2437 *xmom_centroid_values, 2438 *ymom_centroid_values, 2439 *elevation_centroid_values, 2440 *height_centroid_values, 2441 *edge_coordinates, 2442 *stage_edge_values, 2443 *xmom_edge_values, 2444 *ymom_edge_values, 2445 *elevation_edge_values, 2446 *height_edge_values, 2447 *stage_vertex_values, 2448 *xmom_vertex_values, 2449 *ymom_vertex_values, 2450 *elevation_vertex_values, 2451 *height_vertex_values, 2452 *x_centroid_work, 2453 *y_centroid_work, 2454 *update_extrapolation; 2455 2120 2121 struct domain D; 2456 2122 PyObject *domain; 2457 2123 2458 2459 double beta_w, beta_w_dry, beta_uh, beta_uh_dry, beta_vh, beta_vh_dry; 2460 double minimum_allowed_height, epsilon; 2461 int optimise_dry_cells, number_of_elements, extrapolate_velocity_second_order, e, e2; 2462 2463 // Convert Python arguments to C 2464 if (!PyArg_ParseTuple(args, "OOOOOOOOOOOOOOOOOOOOOiiOOO", 2465 &domain, 2466 &surrogate_neighbours, 2467 &neighbour_edges, 2468 &number_of_boundaries, 2469 ¢roid_coordinates, 2470 &stage_centroid_values, 2471 &xmom_centroid_values, 2472 &ymom_centroid_values, 2473 &elevation_centroid_values, 2474 &height_centroid_values, 2475 &edge_coordinates, 2476 &stage_edge_values, 2477 &xmom_edge_values, 2478 &ymom_edge_values, 2479 &elevation_edge_values, 2480 &height_edge_values, 2481 &stage_vertex_values, 2482 &xmom_vertex_values, 2483 &ymom_vertex_values, 2484 &elevation_vertex_values, 2485 &height_vertex_values, 2486 &optimise_dry_cells, 2487 &extrapolate_velocity_second_order, 2488 &x_centroid_work, 2489 &y_centroid_work, 2490 &update_extrapolation)) { 2491 2492 report_python_error(AT, "could not parse input arguments"); 2493 return NULL; 2494 } 2495 2496 // check that numpy array objects arrays are C contiguous memory 2497 CHECK_C_CONTIG(surrogate_neighbours); 2498 CHECK_C_CONTIG(neighbour_edges); 2499 CHECK_C_CONTIG(number_of_boundaries); 2500 CHECK_C_CONTIG(centroid_coordinates); 2501 CHECK_C_CONTIG(stage_centroid_values); 2502 CHECK_C_CONTIG(xmom_centroid_values); 2503 CHECK_C_CONTIG(ymom_centroid_values); 2504 CHECK_C_CONTIG(elevation_centroid_values); 2505 CHECK_C_CONTIG(height_centroid_values); 2506 CHECK_C_CONTIG(edge_coordinates); 2507 CHECK_C_CONTIG(stage_edge_values); 2508 CHECK_C_CONTIG(xmom_edge_values); 2509 CHECK_C_CONTIG(ymom_edge_values); 2510 CHECK_C_CONTIG(elevation_edge_values); 2511 CHECK_C_CONTIG(height_edge_values); 2512 CHECK_C_CONTIG(stage_vertex_values); 2513 CHECK_C_CONTIG(xmom_vertex_values); 2514 CHECK_C_CONTIG(ymom_vertex_values); 2515 CHECK_C_CONTIG(elevation_vertex_values); 2516 CHECK_C_CONTIG(height_vertex_values); 2517 CHECK_C_CONTIG(x_centroid_work); 2518 CHECK_C_CONTIG(y_centroid_work); 2519 CHECK_C_CONTIG(update_extrapolation); 2520 2521 // Get the safety factor beta_w, set in the config.py file. 2522 // This is used in the limiting process 2523 2524 2525 beta_w = get_python_double(domain,"beta_w"); 2526 beta_w_dry = get_python_double(domain,"beta_w_dry"); 2527 beta_uh = get_python_double(domain,"beta_uh"); 2528 beta_uh_dry = get_python_double(domain,"beta_uh_dry"); 2529 beta_vh = get_python_double(domain,"beta_vh"); 2530 beta_vh_dry = get_python_double(domain,"beta_vh_dry"); 2531 2532 minimum_allowed_height = get_python_double(domain,"minimum_allowed_height"); 2533 epsilon = get_python_double(domain,"epsilon"); 2534 2535 number_of_elements = stage_centroid_values -> dimensions[0]; 2536 2537 //printf("In C before Extrapolate"); 2538 //e=1; 2539 // Call underlying computational routine 2540 e = _extrapolate_second_order_edge_sw(number_of_elements, 2541 epsilon, 2542 minimum_allowed_height, 2543 beta_w, 2544 beta_w_dry, 2545 beta_uh, 2546 beta_uh_dry, 2547 beta_vh, 2548 beta_vh_dry, 2549 (long*) surrogate_neighbours -> data, 2550 (long*) neighbour_edges -> data, 2551 (long*) number_of_boundaries -> data, 2552 (double*) centroid_coordinates -> data, 2553 (double*) stage_centroid_values -> data, 2554 (double*) xmom_centroid_values -> data, 2555 (double*) ymom_centroid_values -> data, 2556 (double*) elevation_centroid_values -> data, 2557 (double*) height_centroid_values -> data, 2558 (double*) edge_coordinates -> data, 2559 (double*) stage_edge_values -> data, 2560 (double*) xmom_edge_values -> data, 2561 (double*) ymom_edge_values -> data, 2562 (double*) elevation_edge_values -> data, 2563 (double*) height_edge_values -> data, 2564 (double*) stage_vertex_values -> data, 2565 (double*) xmom_vertex_values -> data, 2566 (double*) ymom_vertex_values -> data, 2567 (double*) elevation_vertex_values -> data, 2568 (double*) height_vertex_values -> data, 2569 optimise_dry_cells, 2570 extrapolate_velocity_second_order, 2571 (double*) x_centroid_work -> data, 2572 (double*) y_centroid_work -> data, 2573 (long*) update_extrapolation -> data); 2124 int e; 2125 2126 if (!PyArg_ParseTuple(args, "O", &domain)) { 2127 report_python_error(AT, "could not parse input arguments"); 2128 return NULL; 2129 } 2130 2131 get_python_domain(&D, domain); 2132 2133 // Call underlying flux computation routine and update 2134 // the explicit update arrays 2135 e = _extrapolate_second_order_edge_sw(&D); 2574 2136 2575 2137 if (e == -1) { … … 2582 2144 2583 2145 }// extrapolate_second-order_edge_sw 2146 2584 2147 //======================================================================== 2585 2148 // Protect -- to prevent the water level from falling below the minimum -
trunk/anuga_core/source/anuga/shallow_water/sw_domain.h
r8813 r9306 21 21 double minimum_allowed_height; 22 22 23 long timestep_fluxcalls; 24 23 25 double beta_w; 24 26 double beta_w_dry; … … 28 30 double beta_vh_dry; 29 31 32 long max_flux_update_frequency; 33 long ncol_riverwall_hydraulic_properties; 30 34 31 35 // Changing values in these arrays will change the values in the python object … … 38 42 double* areas; 39 43 40 44 long* edge_flux_type; 41 45 42 46 long* tri_full_flag; … … 53 57 double* ymom_edge_values; 54 58 double* bed_edge_values; 59 double* height_edge_values; 55 60 56 61 double* stage_centroid_values; … … 58 63 double* ymom_centroid_values; 59 64 double* bed_centroid_values; 65 double* height_centroid_values; 60 66 61 67 double* stage_vertex_values; … … 63 69 double* ymom_vertex_values; 64 70 double* bed_vertex_values; 71 double* height_vertex_values; 65 72 66 73 … … 73 80 double* xmom_explicit_update; 74 81 double* ymom_explicit_update; 82 83 long* flux_update_frequency; 84 long* update_next_flux; 85 long* update_extrapolation; 86 double* edge_timestep; 87 double* edge_flux_work; 88 double* pressuregrad_work; 89 double* x_centroid_work; 90 double* y_centroid_work; 91 double* boundary_flux_sum; 92 93 long* allow_timestep_increase; 94 95 double* riverwall_elevation; 96 long* riverwall_rowIndex; 97 double* riverwall_hydraulic_properties; 75 98 }; 76 99 … … 152 175 *radii, 153 176 *areas, 177 *edge_flux_type, 154 178 *tri_full_flag, 155 179 *already_computed_flux, … … 159 183 *number_of_boundaries, 160 184 *surrogate_neighbours, 161 *max_speed; 185 *max_speed, 186 *flux_update_frequency, 187 *update_next_flux, 188 *update_extrapolation, 189 *allow_timestep_increase, 190 *edge_timestep, 191 *edge_flux_work, 192 *pressuregrad_work, 193 *x_centroid_work, 194 *y_centroid_work, 195 *boundary_flux_sum, 196 *riverwall_elevation, 197 *riverwall_rowIndex, 198 *riverwall_hydraulic_properties; 162 199 163 200 PyObject *quantities; 201 PyObject *riverwallData; 164 202 165 203 D->number_of_elements = get_python_integer(domain, "number_of_elements"); … … 170 208 D->evolve_max_timestep = get_python_double(domain, "evolve_max_timestep"); 171 209 D->minimum_allowed_height = get_python_double(domain, "minimum_allowed_height"); 210 D->timestep_fluxcalls = get_python_integer(domain,"timestep_fluxcalls"); 211 172 212 173 213 D->extrapolate_velocity_second_order = get_python_integer(domain, "extrapolate_velocity_second_order"); … … 180 220 D->beta_vh_dry = get_python_double(domain, "beta_vh_dry"); 181 221 182 222 D->max_flux_update_frequency = get_python_integer(domain,"max_flux_update_frequency"); 183 223 184 224 neighbours = get_consecutive_array(domain, "neighbours"); … … 203 243 D->areas = (double *) areas->data; 204 244 245 edge_flux_type = get_consecutive_array(domain, "edge_flux_type"); 246 D->edge_flux_type = (long *) edge_flux_type->data; 247 248 205 249 tri_full_flag = get_consecutive_array(domain, "tri_full_flag"); 206 250 D->tri_full_flag = (long *) tri_full_flag->data; … … 225 269 D->number_of_boundaries = (long *) number_of_boundaries->data; 226 270 227 271 flux_update_frequency = get_consecutive_array(domain, "flux_update_frequency"); 272 D->flux_update_frequency = (long*) flux_update_frequency->data; 273 274 update_next_flux = get_consecutive_array(domain, "update_next_flux"); 275 D->update_next_flux = (long*) update_next_flux->data; 276 277 update_extrapolation = get_consecutive_array(domain, "update_extrapolation"); 278 D->update_extrapolation = (long*) update_extrapolation->data; 279 280 allow_timestep_increase = get_consecutive_array(domain, "allow_timestep_increase"); 281 D->allow_timestep_increase = (long*) allow_timestep_increase->data; 282 283 edge_timestep = get_consecutive_array(domain, "edge_timestep"); 284 D->edge_timestep = (double*) edge_timestep->data; 285 286 edge_flux_work = get_consecutive_array(domain, "edge_flux_work"); 287 D->edge_flux_work = (double*) edge_flux_work->data; 288 289 pressuregrad_work = get_consecutive_array(domain, "pressuregrad_work"); 290 D->pressuregrad_work = (double*) pressuregrad_work->data; 291 292 x_centroid_work = get_consecutive_array(domain, "x_centroid_work"); 293 D->x_centroid_work = (double*) x_centroid_work->data; 294 295 y_centroid_work = get_consecutive_array(domain, "y_centroid_work"); 296 D->y_centroid_work = (double*) y_centroid_work->data; 297 298 boundary_flux_sum = get_consecutive_array(domain, "boundary_flux_sum"); 299 D->boundary_flux_sum = (double*) boundary_flux_sum->data; 228 300 229 301 quantities = get_python_object(domain, "quantities"); … … 233 305 D->ymom_edge_values = get_python_array_data_from_dict(quantities, "ymomentum", "edge_values"); 234 306 D->bed_edge_values = get_python_array_data_from_dict(quantities, "elevation", "edge_values"); 307 D->height_edge_values = get_python_array_data_from_dict(quantities, "height", "edge_values"); 235 308 236 309 D->stage_centroid_values = get_python_array_data_from_dict(quantities, "stage", "centroid_values"); … … 238 311 D->ymom_centroid_values = get_python_array_data_from_dict(quantities, "ymomentum", "centroid_values"); 239 312 D->bed_centroid_values = get_python_array_data_from_dict(quantities, "elevation", "centroid_values"); 313 D->height_centroid_values = get_python_array_data_from_dict(quantities, "height", "centroid_values"); 240 314 241 315 D->stage_vertex_values = get_python_array_data_from_dict(quantities, "stage", "vertex_values"); … … 243 317 D->ymom_vertex_values = get_python_array_data_from_dict(quantities, "ymomentum", "vertex_values"); 244 318 D->bed_vertex_values = get_python_array_data_from_dict(quantities, "elevation", "vertex_values"); 319 D->height_vertex_values = get_python_array_data_from_dict(quantities, "height", "vertex_values"); 245 320 246 321 D->stage_boundary_values = get_python_array_data_from_dict(quantities, "stage", "boundary_values"); … … 254 329 255 330 331 riverwallData = get_python_object(domain,"riverwallData"); 332 333 riverwall_elevation = get_consecutive_array(riverwallData, "riverwall_elevation"); 334 D->riverwall_elevation = (double*) riverwall_elevation->data; 335 336 riverwall_rowIndex = get_consecutive_array(riverwallData, "hydraulic_properties_rowIndex"); 337 D->riverwall_rowIndex = (long*) riverwall_rowIndex->data; 338 339 D->ncol_riverwall_hydraulic_properties = get_python_integer(riverwallData, "ncol_hydraulic_properties"); 340 341 riverwall_hydraulic_properties = get_consecutive_array(riverwallData, "hydraulic_properties"); 342 D->riverwall_hydraulic_properties = (double*) riverwall_hydraulic_properties->data; 343 256 344 Py_DECREF(quantities); 345 Py_DECREF(riverwallData); 257 346 258 347 Py_DECREF(neighbours); … … 263 352 Py_DECREF(radii); 264 353 Py_DECREF(areas); 354 Py_DECREF(edge_flux_type); 265 355 Py_DECREF(tri_full_flag); 266 356 Py_DECREF(already_computed_flux); … … 270 360 Py_DECREF(max_speed); 271 361 Py_DECREF(number_of_boundaries); 362 Py_DECREF(flux_update_frequency); 363 Py_DECREF(update_next_flux); 364 Py_DECREF(update_extrapolation); 365 Py_DECREF(edge_timestep); 366 Py_DECREF(edge_flux_work); 367 Py_DECREF(pressuregrad_work); 368 Py_DECREF(x_centroid_work); 369 Py_DECREF(y_centroid_work); 370 Py_DECREF(boundary_flux_sum); 371 Py_DECREF(allow_timestep_increase); 272 372 273 373 return D; … … 322 422 printf("D->ymom_vertex_values %p \n", D->ymom_vertex_values); 323 423 printf("D->bed_vertex_values %p \n", D->bed_vertex_values); 424 printf("D->height_vertex_values %p \n", D->height_vertex_values); 324 425 printf("D->stage_boundary_values %p \n", D->stage_boundary_values); 325 426 printf("D->xmom_boundary_values %p \n", D->xmom_boundary_values);
Note: See TracChangeset
for help on using the changeset viewer.