Changeset 9292
- Timestamp:
- Aug 12, 2014, 12:10:51 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/generic_domain.py
r9282 r9292 1622 1622 1623 1623 self.number_of_steps += 1 1624 1624 1625 if self._order_ == 1: 1625 1626 self.number_of_first_order_steps += 1 … … 1678 1679 # Update timestep to fit yieldstep and finaltime 1679 1680 self.update_timestep(yieldstep, finaltime) 1681 1682 if self.max_flux_update_frequency is not 1: 1683 # Update flux_update_frequency using the new timestep 1684 self.compute_flux_update_frequency() 1680 1685 1681 1686 # Update conserved quantities -
trunk/anuga_core/source/anuga/advection/advection.py
r8124 r9292 80 80 81 81 self.smooth = True 82 self.max_flux_update_frequency=1 82 83 83 84 def check_integrity(self): -
trunk/anuga_core/source/anuga/shallow_water/shallow_water_domain.py
r9290 r9292 291 291 self.boundary_flux_integral=boundary_flux_integral_operator(self) 292 292 # Make an integer counting how many times we call compute_fluxes_central -- so we know which substep we are on 293 self.call=1293 #self.call=1 294 294 295 295 # List to store the volumes we computed before … … 297 297 298 298 # Work arrays [avoid allocate statements in compute_fluxes or extrapolate_second_order] 299 self.edge_flux_work=num.zeros(len(self.edge_coordinates[:,0])*3) 300 self.pressuregrad_work=num.zeros(len(self.edge_coordinates[:,0])) 301 self.x_centroid_work=num.zeros(len(self.edge_coordinates[:,0])/3) 299 self.edge_flux_work=num.zeros(len(self.edge_coordinates[:,0])*3) # Advective fluxes 300 self.pressuregrad_work=num.zeros(len(self.edge_coordinates[:,0])) # Gravity related terms 301 self.x_centroid_work=num.zeros(len(self.edge_coordinates[:,0])/3) 302 302 self.y_centroid_work=num.zeros(len(self.edge_coordinates[:,0])/3) 303 304 ############################################################################ 305 ## Local-timestepping information 306 # 307 # Fluxes can be updated every 1, 2, 4, 8, .. max_flux_update_frequency timesteps 308 # The global timestep is not allowed to increase except when 309 # number_of_timesteps%max_flux_update_frequency==0 310 self.max_flux_update_frequency=2**0 # Must be a power of 2. 311 312 # flux_update_frequency. The edge flux terms are re-computed only when 313 # number_of_timesteps%flux_update_frequency[myEdge]==0 314 self.flux_update_frequency=num.zeros(len(self.edge_coordinates[:,0])).astype(int)+1 315 # Flag: should we update the flux on the next compute fluxes call? 316 self.update_next_flux=num.zeros(len(self.edge_coordinates[:,0])).astype(int)+1 317 # Flag: should we update the extrapolation on the next extrapolation call? 318 # (Only do this if one or more of the fluxes on that triangle will be computed on 319 # the next timestep, assuming only the flux computation uses edge/vertex values) 320 self.update_extrapolation=num.zeros(len(self.edge_coordinates[:,0])/3).astype(int)+1 321 322 # edge_timestep [wavespeed/radius] -- not updated every timestep 323 self.edge_timestep=num.zeros(len(self.edge_coordinates[:,0]))+1.0e+100 324 325 # Do we allow the timestep to increase (not every time if local 326 # extrapolation/flux updating is used) 327 self.allow_timestep_increase=num.zeros(1).astype(int)+1 303 328 304 329 def _set_defaults(self): … … 841 866 842 867 843 868 def set_local_extrapolation_and_flux_updating(self,nlevels=8): 869 """ 870 Use local flux and extrapolation updating 871 872 nlevels == number of flux_update_frequency levels > 1 873 874 For example, to allow flux updating every 1,2,4,8 875 timesteps, do: 876 877 domain.set_local_extrapolation_and_flux_updating(nlevels=3) 878 879 (since 2**3==8) 880 """ 881 882 self.max_flux_update_frequency=2**nlevels 883 884 if(self.max_flux_update_frequency is not 1): 885 if self.timestepping_method is not 'euler': 886 raise Exception, 'Local extrapolation and flux updating only supported with euler timestepping' 887 if self.compute_fluxes_method is not 'DE': 888 raise Exception, 'Local extrapolation and flux updating only supported for discontinuous flow algorithms' 844 889 845 890 … … 1668 1713 height = self.quantities['height'] 1669 1714 1670 timestep = float(sys.maxint) 1671 1672 # Keep track of number of calls to compute_fluxes_ext 1673 # Note that in ANUGA, all sub-steps within an rk2/rk3 timestep have the same timestep 1674 self.call+=1 1715 timestep = self.evolve_max_timestep 1716 1675 1717 flux_timestep = compute_fluxes_ext(timestep, 1676 1718 self.epsilon, … … 1706 1748 Bed.centroid_values, 1707 1749 height.centroid_values, 1708 #Bed.vertex_values,1709 1750 self.edge_flux_type, 1710 1751 self.riverwallData.riverwall_elevation, … … 1713 1754 self.riverwallData.hydraulic_properties, 1714 1755 self.edge_flux_work, 1715 self.pressuregrad_work) 1756 self.pressuregrad_work, 1757 self.edge_timestep, 1758 self.update_next_flux, 1759 self.allow_timestep_increase) 1716 1760 1717 1761 self.flux_timestep = flux_timestep … … 1821 1865 int(self.extrapolate_velocity_second_order), 1822 1866 self.x_centroid_work, 1823 self.y_centroid_work) 1867 self.y_centroid_work, 1868 self.update_extrapolation) 1824 1869 else: 1825 1870 # Code for original method … … 2580 2625 return message 2581 2626 2627 def compute_flux_update_frequency(self): 2628 """ 2629 Update the 'flux_update_frequency' and 'update_extrapolate' variables 2630 Used to control updating of fluxes / extrapolation for 'local-time-stepping' 2631 """ 2632 from swDE1_domain_ext import compute_flux_update_frequency \ 2633 as compute_flux_update_frequency_ext 2634 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) 2646 2582 2647 def report_water_volume_statistics(self, verbose=True, returnStats=False): 2583 2648 """ -
trunk/anuga_core/source/anuga/shallow_water/swDE1_domain_ext.c
r9289 r9292 28 28 29 29 const double pi = 3.14159265358979; 30 31 // Trick to compute n modulo 2 when d is a power of 2 32 unsigned int Mod_of_power_2(unsigned int n, unsigned int d) 33 { 34 return ( n & (d-1) ); 35 } 36 30 37 31 38 // Computational function for rotation … … 111 118 double *edgeflux, double *max_speed, 112 119 double *pressure_flux, double hc, 113 double hc_n , double speed_max_last)120 double hc_n) 114 121 { 115 122 … … 285 292 double *edgeflux, double *max_speed, 286 293 double *pressure_flux, double hc, 287 double hc_n , double speed_max_last)294 double hc_n) 288 295 { 289 296 … … 441 448 return 0; 442 449 } 450 451 //////////////////////////////////////////////////////////////// 452 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){ 462 // Compute the 'flux_update_frequency' for each edge. 463 // 464 // This determines how regularly we need 465 // to update the flux computation (not every timestep) 466 // 467 // Allowed values are 1,2,4,8,... max_flux_update_frequency. 468 // 469 // For example, an edge with flux_update_frequency = 4 would 470 // only have the flux updated every 4 timesteps 471 // 472 // 473 // Local variables 474 int k, i, k3, ki, m, n, nm, ii, j, ii2; 475 long fuf; 476 static int cyclic_number_of_steps=-1; 477 478 // QUICK EXIT 479 if(max_flux_update_frequency==1){ 480 return 0; 481 } 482 483 // Count the steps 484 cyclic_number_of_steps++; 485 if(cyclic_number_of_steps==max_flux_update_frequency){ 486 // The flux was just updated in every cell 487 cyclic_number_of_steps=0; 488 } 489 490 491 // PART 1: ONLY OCCURS FOLLOWING FLUX UPDATE 492 493 for ( k = 0; k < number_of_elements; k++){ 494 for ( i = 0; i < 3; i++){ 495 ki = k*3 + i; 496 if((Mod_of_power_2(cyclic_number_of_steps, flux_update_frequency[ki])==0)){ 497 // The flux was just updated, along with the edge_timestep 498 // So we better recompute the flux_update_frequency 499 n=neighbours[ki]; 500 if(n>=0){ 501 m = neighbour_edges[ki]; 502 nm = n * 3 + m; // Linear index (triangle n, edge m) 503 } 504 505 // Check if we have already done this edge 506 // (Multiply already_computed_flux by -1 on the first update, 507 // and again on the 2nd) 508 if(already_computed_flux[ki] > 0 ){ 509 // We have not fixed this flux value yet 510 already_computed_flux[ki] *=-1; 511 if(n>=0){ 512 already_computed_flux[nm] *=-1; 513 } 514 }else{ 515 // We have fixed this flux value already 516 already_computed_flux[ki] *=-1; 517 if(n>=0){ 518 already_computed_flux[nm] *=-1; 519 } 520 continue; 521 } 522 523 // Basically int( edge_ki_timestep/timestep ) with upper limit + tweaks 524 // notSoFast is ideally = 1.0, but in practice values < 1.0 can enhance stability 525 // NOTE: edge_timestep[ki]/timestep can be very large [so int overflows]. 526 // Do not pull the (int) inside the min term 527 fuf = (int)min((edge_timestep[ki]/timestep)*notSoFast,max_flux_update_frequency*1.); 528 // Account for neighbour 529 if(n>=0){ 530 fuf = min( (int)min(edge_timestep[nm]/timestep*notSoFast, max_flux_update_frequency*1.), fuf); 531 } 532 533 // Deal with notSoFast<1.0 534 if(fuf<1){ 535 fuf=1; 536 } 537 // Deal with large fuf 538 if(fuf>max_flux_update_frequency){ 539 fuf = max_flux_update_frequency; 540 } 541 //// Deal with intermediate cases 542 ii=2; 543 while(ii<max_flux_update_frequency){ 544 // Set it to 1,2,4, 8, ... 545 ii2=2*ii; 546 if((fuf>ii) && (fuf<ii2)){ 547 fuf = ii; 548 continue; 549 } 550 ii=ii2; 551 } 552 553 // Set the values 554 flux_update_frequency[ki]=fuf; 555 if(n>=0){ 556 flux_update_frequency[nm]= fuf; 557 } 558 559 } 560 } 561 } 562 563 //// PART 2 -- occcurs every timestep 564 565 // At this point, both edges have the same flux_update_frequency. 566 // Next, ensure that flux_update_frequency varies within a constant over each triangle 567 // Experiences suggests this is numerically important 568 // (But, it can result in the same edge having different flux_update_freq) 569 for( k=0; k<number_of_elements; k++){ 570 k3=3*k; 571 ii = 1*min(flux_update_frequency[k3], 572 min(flux_update_frequency[k3+1], 573 flux_update_frequency[k3+2])); 574 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]); 578 579 } 580 581 // Now enforce the same flux_update_frequency on each edge 582 // (Could have been broken above when we limited the variation on each triangle) 583 // This seems to have nice behaviour. Notice how an edge 584 // with a large flux_update_frequency, near an edge with a small flux_update_frequency, 585 // will have its flux_update_frequency updated after a few timesteps (i.e. before max_flux_update_frequency timesteps) 586 // OTOH, could this cause oscillations in flux_update_frequency? 587 for( k = 0; k < number_of_elements; k++){ 588 update_extrapolation[k]=0; 589 for( i = 0; i< 3; i++){ 590 ki=3*k+i; 591 // Account for neighbour 592 n=neighbours[ki]; 593 if(n>=0){ 594 m = neighbour_edges[ki]; 595 nm = n * 3 + m; // Linear index (triangle n, edge m) 596 flux_update_frequency[ki]=min(flux_update_frequency[ki], flux_update_frequency[nm]); 597 } 598 // Do we need to update the extrapolation? 599 // (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; 603 }else{ 604 update_next_flux[ki]=0; 605 } 606 } 607 } 608 609 // Check whether the timestep can be increased in the next compute_fluxes call 610 if(cyclic_number_of_steps+1==max_flux_update_frequency){ 611 // All fluxes will be updated on the next timestep 612 // We also allow the timestep to increase then 613 allow_timestep_increase[0]=1; 614 }else{ 615 allow_timestep_increase[0]=0; 616 } 617 618 return 0; 619 } 620 443 621 444 622 double adjust_edgeflux_with_weir(double* edgeflux, … … 574 752 double* riverwall_hydraulic_properties, 575 753 double* edge_flux_work, 576 double* pressuregrad_work) { 754 double* pressuregrad_work, 755 double* edge_timestep, 756 long* update_next_flux, 757 long* allow_timestep_increase) { 577 758 // Local variables 578 759 double max_speed, length, inv_area, zl, zr; … … 582 763 // 583 764 int k, i, m, n,j, ii; 584 int ki, nm = 0, ki2,ki3, nm3; // Index shorthands765 int ki,k3, nm = 0, ki2,ki3, nm3; // Index shorthands 585 766 // Workspace (making them static actually made function slightly slower (Ole)) 586 767 double ql[3], qr[3], edgeflux[3]; // Work array for summing up fluxes 587 768 double stage_edges[3];//Work array 588 double bedslope_work, local_timestep; 769 double bedslope_work; 770 static double local_timestep; 589 771 int neighbours_wet[3];//Work array 590 intRiverWall_count, substep_count;772 long RiverWall_count, substep_count; 591 773 double hle, hre, zc, zc_n, Qfactor, s1, s2, h1, h2; 592 double stage_edge_lim, outgoing_mass_edges, bedtop, bedbot,pressure_flux, hc, hc_n, tmp, tmp2;774 double stage_edge_lim, outgoing_mass_edges, pressure_flux, hc, hc_n, tmp, tmp2; 593 775 double h_left_tmp, h_right_tmp; 594 776 static long call = 1; // Static local variable flagging already computed flux 595 double speed_max_last, vol, smooth, local_speed,weir_height;777 double speed_max_last, vol, weir_height; 596 778 597 779 call++; // Flag 'id' of flux calculation for this timestep … … 602 784 memset((char*) xmom_explicit_update, 0, number_of_elements * sizeof (double)); 603 785 memset((char*) ymom_explicit_update, 0, number_of_elements * sizeof (double)); 604 memset((char*) edge_flux_work, 0, 9*number_of_elements * sizeof (double)); 605 memset((char*) pressuregrad_work, 0, 3*number_of_elements * sizeof (double)); 606 607 local_timestep=timestep; 786 787 788 // Counter for riverwall edges 608 789 RiverWall_count=0; 790 // Which substep of the timestepping method are we on? 609 791 substep_count=(call-2)%timestep_fluxcalls; 610 792 793 // Fluxes are not updated every timestep, 794 // but all fluxes ARE updated when the following condition holds 795 if(allow_timestep_increase[0]==1){ 796 // We can only increase the timestep if all fluxes are allowed to be updated 797 // If this is not done the timestep can't increase (since local_timestep is static) 798 local_timestep=1.0e+100; 799 } 611 800 612 801 // For all triangles 613 802 for (k = 0; k < number_of_elements; k++) { 614 803 speed_max_last=0.0; 804 615 805 // Loop through neighbours and compute edge flux for each 616 806 for (i = 0; i < 3; i++) { … … 619 809 ki3 = 3*ki; 620 810 621 if ( already_computed_flux[ki] == call) {811 if ((already_computed_flux[ki] == call) || (update_next_flux[ki]!=1)) { 622 812 // We've already computed the flux across this edge 623 813 // Check if it is a riverwall … … 693 883 normals[ki2], normals[ki2 + 1], 694 884 epsilon, z_half, limiting_threshold, g, 695 edgeflux, &max_speed, &pressure_flux, hc, hc_n, 696 speed_max_last); 885 edgeflux, &max_speed, &pressure_flux, hc, hc_n); 697 886 698 887 // Force weir discharge to match weir theory … … 701 890 // If the weir height is zero, avoid the weir computation entirely 702 891 if(weir_height>0.){ 892 //////////////////////////////////////////////////////////////////////////////////// 893 // Use first-order h's for weir -- as the 'upstream/downstream' heads are 894 // measured away from the weir itself 895 h_left_tmp= max(stage_centroid_values[k]-z_half,0.); 896 if(n>=0){ 897 h_right_tmp= max(stage_centroid_values[n]-z_half,0.); 898 }else{ 899 h_right_tmp= max(hc_n+zr-z_half,0.); 900 } 901 902 ////////////////////////////////////////////////////////////////////////////////// 703 903 // Get Qfactor index - multiply the idealised weir discharge by this constant factor 704 904 ii=riverwall_rowIndex[RiverWall_count-1]*ncol_riverwall_hydraulic_properties; … … 717 917 h2=riverwall_hydraulic_properties[ii]; 718 918 719 // Use first-order h's for weir -- as the 'upstream/downstream' heads are 720 // measured away from the weir itself 721 h_left_tmp= max(stage_centroid_values[k]-z_half,0.); 722 if(n>=0){ 723 h_right_tmp= max(stage_centroid_values[n]-z_half,0.); 724 }else{ 725 h_right_tmp= max(hc_n+zr-z_half,0.); 726 } 727 919 // Weir flux adjustment 728 920 adjust_edgeflux_with_weir(edgeflux, h_left_tmp, h_right_tmp, g, 729 921 weir_height, Qfactor, … … 782 974 783 975 // Update timestep based on edge i and possibly neighbour n 784 // NOTE: We should only change the timestep between rk2 or rk3 785 // steps, NOT within them (since a constant timestep is used within 786 // each rk2/rk3 sub-step) 787 if ((tri_full_flag[k] == 1) & (substep_count==0)) { 788 789 speed_max_last=max(speed_max_last, max_speed); 790 791 if (max_speed > epsilon) { 792 // Apply CFL condition for triangles joining this edge (triangle k and triangle n) 793 794 // CFL for triangle k 795 local_timestep = min(local_timestep, radii[k] / max_speed); 796 797 if (n >= 0) { 798 // Apply CFL condition for neigbour n (which is on the ith edge of triangle k) 799 local_timestep = min(local_timestep, radii[n] / max_speed); 976 // NOTE: We should only change the timestep on the 'first substep' 977 // of the timestepping method [substep_count==0] 978 if(substep_count==0){ 979 980 // Compute the 'edge-timesteps' (useful for setting flux_update_frequency) 981 edge_timestep[ki] = radii[k] / max(max_speed, epsilon); 982 if (n >= 0) { 983 edge_timestep[nm] = radii[n] / max(max_speed, epsilon); 984 } 985 986 // 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) { 992 // Apply CFL condition for triangles joining this edge (triangle k and triangle n) 993 994 // CFL for triangle k 995 local_timestep = min(local_timestep, edge_timestep[ki]); 996 997 if (n >= 0) { 998 // Apply CFL condition for neigbour n (which is on the ith edge of triangle k) 999 local_timestep = min(local_timestep, edge_timestep[nm]); 1000 } 800 1001 } 801 802 1002 } 803 1003 } 804 1004 805 1005 } // End edge i (and neighbour n) 806 1006 // Keep track of maximal speeds … … 809 1009 810 1010 } // End triangle k 811 1011 812 1012 //// Limit edgefluxes, for mass conservation near wet/dry cells 813 1013 //// This doesn't seem to be needed anymore … … 867 1067 for(k=0; k<number_of_elements; k++){ 868 1068 hc = max(stage_centroid_values[k] - bed_centroid_values[k],0.); 869 stage_explicit_update[k]=0.;870 xmom_explicit_update[k]=0.;871 ymom_explicit_update[k]=0.;872 1069 873 1070 for(i=0;i<3;i++){ 1071 // FIXME: Make use of neighbours to efficiently set things 874 1072 ki=3*k+i; 875 1073 ki2=ki*2; … … 906 1104 // ymom_explicit_update[k] *= 0.; 907 1105 //} 1106 908 1107 909 1108 } // end edge i … … 920 1119 // Ensure we only update the timestep on the first call within each rk2/rk3 step 921 1120 if(substep_count==0) timestep=local_timestep; 922 1121 923 1122 return timestep; 924 1123 } … … 1075 1274 int extrapolate_velocity_second_order, 1076 1275 double* x_centroid_work, 1077 double* y_centroid_work) { 1276 double* y_centroid_work, 1277 long* update_extrapolation) { 1078 1278 1079 1279 // Local variables … … 1122 1322 // some situations 1123 1323 for (k=0; k<number_of_elements;k++){ 1124 1324 1125 1325 k3=k*3; 1126 1326 k0 = surrogate_neighbours[k3]; … … 1145 1345 for (k = 0; k < number_of_elements; k++) 1146 1346 { 1347 1348 // Don't update the extrapolation if the flux will not be computed on the 1349 // next timestep 1350 if(update_extrapolation[k]==0){ 1351 continue; 1352 } 1353 1147 1354 1148 1355 // Useful indices … … 1223 1430 k2 = surrogate_neighbours[k3 + 2]; 1224 1431 1432 1225 1433 // Get the auxiliary triangle's vertex coordinates 1226 1434 // (really the centroids of neighbouring triangles) … … 1264 1472 height_edge_values[k3+2] = dk; 1265 1473 1266 //stage_edge_values[k3] = elevation_centroid_values[k]+dk;1267 //stage_edge_values[k3+1] = elevation_centroid_values[k]+dk;1268 //stage_edge_values[k3+2] = elevation_centroid_values[k]+dk;1269 //stage_edge_values[k3] = elevation_edge_values[k3]+dk;1270 //stage_edge_values[k3+1] = elevation_edge_values[k3+1]+dk;1271 //stage_edge_values[k3+2] = elevation_edge_values[k3+2]+dk;1272 1273 //xmom_centroid_values[k]=0.;1274 //ymom_centroid_values[k]=0.;1275 //x_centroid_work[k] = 0.;1276 //y_centroid_work[k] = 0.;1277 1278 1474 xmom_edge_values[k3] = xmom_centroid_values[k]; 1279 1475 xmom_edge_values[k3+1] = xmom_centroid_values[k]; … … 1711 1907 // Compute vertex values of quantities 1712 1908 for (k=0; k<number_of_elements; k++){ 1909 if(extrapolate_velocity_second_order==1){ 1910 //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]; 1913 } 1914 1915 // Don't proceed if we didn't update the edge/vertex values 1916 if(update_extrapolation[k]==0){ 1917 continue; 1918 } 1919 1713 1920 k3=3*k; 1714 1921 1715 1922 // Compute stage vertex values 1716 1923 stage_vertex_values[k3] = stage_edge_values[k3+1] + stage_edge_values[k3+2] -stage_edge_values[k3] ; … … 1725 1932 // If needed, convert from velocity to momenta 1726 1933 if(extrapolate_velocity_second_order==1){ 1727 //Convert velocity back to momenta at centroids1728 xmom_centroid_values[k] = x_centroid_work[k];1729 ymom_centroid_values[k] = y_centroid_work[k];1730 1731 1934 // Re-compute momenta at edges 1732 1935 for (i=0; i<3; i++){ … … 1847 2050 *riverwall_hydraulic_properties, 1848 2051 *edge_flux_work, 1849 *pressuregrad_work; 2052 *pressuregrad_work, 2053 *edge_timestep, 2054 *update_next_flux, 2055 *allow_timestep_increase; 1850 2056 1851 2057 double timestep, epsilon, H0, g; 1852 2058 int optimise_dry_cells, timestep_fluxcalls, ncol_riverwall_hydraulic_properties; 2059 1853 2060 1854 2061 // Convert Python arguments to C 1855 if (!PyArg_ParseTuple(args, "ddddOOOOOOOOOOOOOOOOOOOOOOiiOOOOOOOOiOOO ",2062 if (!PyArg_ParseTuple(args, "ddddOOOOOOOOOOOOOOOOOOOOOOiiOOOOOOOOiOOOOOO", 1856 2063 ×tep, 1857 2064 &epsilon, … … 1892 2099 &riverwall_hydraulic_properties, 1893 2100 &edge_flux_work, 1894 &pressuregrad_work 2101 &pressuregrad_work, 2102 &edge_timestep, 2103 &update_next_flux, 2104 &allow_timestep_increase 1895 2105 )) { 1896 2106 report_python_error(AT, "could not parse input arguments"); … … 1932 2142 CHECK_C_CONTIG(edge_flux_work); 1933 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); 1934 2147 1935 2148 int number_of_elements = stage_edge_values -> dimensions[0]; … … 1978 2191 (double*) riverwall_hydraulic_properties ->data, 1979 2192 (double*) edge_flux_work-> data, 1980 (double*) pressuregrad_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 ); 1981 2198 // Return updated flux timestep 1982 2199 return Py_BuildValue("d", timestep); … … 2029 2246 &pressure_flux, 2030 2247 ((double*) normal -> data)[0], 2031 ((double*) normal -> data)[1],2032 2248 ((double*) normal -> data)[1] 2033 2249 ); … … 2107 2323 } 2108 2324 2325 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 2341 2342 */ 2343 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; 2352 2353 double timestep; 2354 int max_flux_update_frequency; 2355 2356 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 ); 2405 // Return 2406 return Py_BuildValue(""); 2407 } 2408 2109 2409 2110 2410 PyObject *extrapolate_second_order_edge_sw(PyObject *self, PyObject *args) { … … 2151 2451 *height_vertex_values, 2152 2452 *x_centroid_work, 2153 *y_centroid_work; 2453 *y_centroid_work, 2454 *update_extrapolation; 2154 2455 2155 2456 PyObject *domain; … … 2161 2462 2162 2463 // Convert Python arguments to C 2163 if (!PyArg_ParseTuple(args, "OOOOOOOOOOOOOOOOOOOOOiiOO ",2464 if (!PyArg_ParseTuple(args, "OOOOOOOOOOOOOOOOOOOOOiiOOO", 2164 2465 &domain, 2165 2466 &surrogate_neighbours, … … 2186 2487 &extrapolate_velocity_second_order, 2187 2488 &x_centroid_work, 2188 &y_centroid_work)) { 2489 &y_centroid_work, 2490 &update_extrapolation)) { 2189 2491 2190 2492 report_python_error(AT, "could not parse input arguments"); … … 2215 2517 CHECK_C_CONTIG(x_centroid_work); 2216 2518 CHECK_C_CONTIG(y_centroid_work); 2519 CHECK_C_CONTIG(update_extrapolation); 2217 2520 2218 2521 // Get the safety factor beta_w, set in the config.py file. … … 2267 2570 extrapolate_velocity_second_order, 2268 2571 (double*) x_centroid_work -> data, 2269 (double*) y_centroid_work -> data); 2572 (double*) y_centroid_work -> data, 2573 (long*) update_extrapolation -> data); 2270 2574 2271 2575 if (e == -1) { … … 2346 2650 {"flux_function_central", flux_function_central, METH_VARARGS, "Print out"}, 2347 2651 {"extrapolate_second_order_edge_sw", extrapolate_second_order_edge_sw, METH_VARARGS, "Print out"}, 2652 {"compute_flux_update_frequency", compute_flux_update_frequency, METH_VARARGS, "Print out"}, 2348 2653 {"protect", protect, METH_VARARGS | METH_KEYWORDS, "Print out"}, 2349 2654 {NULL, NULL, 0, NULL} -
trunk/anuga_work/development/gareth/tests/dam_break/dam_break.py
r9007 r9292 14 14 from numpy import zeros, float 15 15 from time import localtime, strftime, gmtime 16 from bal_and import *16 #from bal_and import * 17 17 #from anuga_tsunami import * 18 18 … … 42 42 points, vertices, boundary = anuga.rectangular_cross(int(L/dx), int(W/dy), L, W, (0.0, -W/2)) 43 43 44 #domain = anuga.Domain(points, vertices, boundary)45 domain = Domain(points, vertices, boundary)44 domain = anuga.Domain(points, vertices, boundary) 45 #domain = Domain(points, vertices, boundary) 46 46 47 47 domain.set_name(output_file) … … 56 56 print domain.get_timestepping_method() 57 57 58 domain.set_flow_algorithm('DE0') 59 #domain.set_local_extrapolation_and_flux_updating(nlevels=8) 58 60 #domain.use_edge_limiter = True 59 61 #domain.use_edge_limiter = False -
trunk/anuga_work/development/gareth/tests/dam_break/plotme.py
r9038 r9292 4 4 """ 5 5 from anuga.utilities import plot_utils as util 6 from bal_and import plot_utils as util27 6 from matplotlib import pyplot as pyplot 8 7 9 p_st = util.get_output('dam_break_201 20305_124724/dam_break.sww')8 p_st = util.get_output('dam_break_20140811_130209/dam_break.sww') 10 9 p2_st=util.get_centroids(p_st) 11 10 12 11 13 p_dev = util 2.get_output('dam_break_20131204_145613/dam_break.sww', 0.001)14 p2_dev=util 2.get_centroids(p_dev, velocity_extrapolation=True)12 p_dev = util.get_output('dam_break_20140811_130049/dam_break.sww', 0.001) 13 p2_dev=util.get_centroids(p_dev, velocity_extrapolation=True) 15 14 16 15 pyplot.clf() -
trunk/anuga_work/development/gareth/tests/runup_sinusoid/runup_sinusoid.py
r9260 r9292 20 20 domain.set_name('runup_sinusoid_v2') # Output to file runup.sww 21 21 #domain.set_store_centroids(True) 22 domain.set_flow_algorithm('DE 1')22 domain.set_flow_algorithm('DE0') 23 23 domain.set_quantities_to_be_stored({'stage': 2, 'xmomentum': 2, 24 24 'ymomentum': 2, 'elevation': 2}) … … 42 42 bumpiness=50. # Higher = shorter wavelength oscillations in topography 43 43 tstep=0.2 44 lasttime= 90.44 lasttime=30. 45 45 46 46 #domain.minimum_allowed_height=domain.minimum_allowed_height*scale_me # Seems needed to make the algorithms behave … … 110 110 print 'Their difference is:', vol-flux_integral 111 111 #print 'Volume less flux int', sum(dd_raw*domain.areas) - domain.boundary_flux_integral 112 112 print 'Update_next_flux range:' 113 print domain.update_extrapolation.min(), domain.update_extrapolation.max() 114 print 'Flux_update_frequency range:' 115 print domain.flux_update_frequency.min(), domain.flux_update_frequency.max() 113 116 114 117 vel_final_inds=(vv>1.0e-01).nonzero()
Note: See TracChangeset
for help on using the changeset viewer.