Changeset 901 for inundation/ga/storm_surge/pyvolution
- Timestamp:
- Feb 16, 2005, 10:18:23 PM (20 years ago)
- Location:
- inundation/ga/storm_surge/pyvolution
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/flatbed.py
r773 r901 14 14 from Numeric import array 15 15 from util import Polygon_function, read_polygon 16 from config import data_dir 16 17 17 18 18 #Create basic mesh … … 24 24 domain.store = True 25 25 domain.set_name('polygons') 26 print "Output being written to " + d ata_dir+ sep + \26 print "Output being written to " + domain.get_datadir() + sep + \ 27 27 domain.filename + "_size%d." %len(domain) + domain.format 28 28 -
inundation/ga/storm_surge/pyvolution/netherlands.py
r773 r901 97 97 N = 60 98 98 99 N = 140 99 #N = 140 100 101 N = 15 100 102 101 103 print 'Creating domain' -
inundation/ga/storm_surge/pyvolution/shallow_water.py
r851 r901 595 595 596 596 597 def balance_deep_and_shallow (domain):597 def balance_deep_and_shallow_old(domain): 598 598 """Compute linear combination between stage as computed by 599 599 gradient-limiters and stage computed as constant height above bed. … … 633 633 hmin = min( hv[k,:] ) 634 634 635 636 635 #Create alpha in [0,1], where alpha==0 means using shallow 637 636 #first order scheme and alpha==1 means using the stage w as … … 647 646 alpha = 1.0 648 647 649 650 648 #Weighted balance between stage parallel to bed elevation 651 649 #(wvi = zvi + hc) and stage as computed by 1st or 2nd … … 664 662 665 663 664 #Momentums at centroids 665 xmomc = domain.quantities['xmomentum'].centroid_values 666 ymomc = domain.quantities['ymomentum'].centroid_values 667 668 #Momentums at vertices 669 xmomv = domain.quantities['xmomentum'].vertex_values 670 ymomv = domain.quantities['ymomentum'].vertex_values 671 672 # Update momentum as a linear combination of 673 # xmomc and ymomc (shallow) and momentum 674 # from extrapolator xmomv and ymomv (deep). 675 xmomv[k,:] = (1-alpha)*xmomc[k] + alpha*xmomv[k,:] 676 ymomv[k,:] = (1-alpha)*ymomc[k] + alpha*ymomv[k,:] 677 678 679 def limit_on_h(domain): 680 """Limit slopes for each volume to eliminate artificial variance 681 introduced by e.g. second order extrapolator 682 683 limit on h = w-z 684 """ 685 686 from Numeric import zeros, Float 687 688 N = domain.number_of_elements 689 beta = domain.beta 690 691 #Shortcuts 692 wc = domain.quantities['stage'].centroid_values 693 zc = domain.quantities['elevation'].centroid_values 694 hc = wc - zc 695 696 wv = domain.quantities['stage'].vertex_values 697 zv = domain.quantities['elevation'].vertex_values 698 hv = wv-zv 699 700 hvbar = zeros(hv.shape, Float) #h-limited values 701 702 #Find min and max of this and neighbour's centroid values 703 hmax = zeros(hc.shape, Float) 704 hmin = zeros(hc.shape, Float) 705 706 for k in range(N): 707 hmax[k] = hmin[k] = hc[k] 708 for i in range(3): 709 n = domain.neighbours[k,i] 710 if n >= 0: 711 hn = hc[n] #Neighbour's centroid value 712 713 hmin[k] = min(hmin[k], hn) 714 hmax[k] = max(hmax[k], hn) 715 716 717 #Diffences between centroids and maxima/minima 718 dhmax = hmax - hc 719 dhmin = hmin - hc 720 721 #Deltas between vertex and centroid values 722 dh = zeros(hv.shape, Float) 723 for i in range(3): 724 dh[:,i] = hv[:,i] - hc 725 726 #Phi limiter 727 for k in range(N): 728 729 #Find the gradient limiter (phi) across vertices 730 phi = 1.0 731 for i in range(3): 732 r = 1.0 733 if (dh[k,i] > 0): r = dhmax[k]/dh[k,i] 734 if (dh[k,i] < 0): r = dhmin[k]/dh[k,i] 735 736 phi = min( min(r*beta, 1), phi ) 737 738 #Then update using phi limiter 739 for i in range(3): 740 hvbar[k,i] = hc[k] + phi*dh[k,i] 741 742 return hvbar 743 744 745 def balance_deep_and_shallow(domain): 746 """Compute linear combination between stage as computed by 747 gradient-limiters limiting using w, and stage computed as 748 constant height above bed and limited using h. 749 The former takes precedence when heights are large compared to the 750 bed slope while the latter takes precedence when heights are 751 relatively small. Anything in between is computed as a balanced 752 linear combination in order to avoid numerical disturbances which 753 would otherwise appear as a result of hard switching between 754 modes. 755 """ 756 757 #New idea. 758 # 759 # In the presence and near of bedslope it is necessary to 760 # limit slopes based on differences in h rather than w 761 # (which is what is needed away from the bed). 762 # 763 # So whether extrapolation was first order or second order, 764 # it will need to be balanced with a h-limited gradient. 765 # 766 # For this we will use the quantity alpha as before 767 # 768 769 #Shortcuts 770 wc = domain.quantities['stage'].centroid_values 771 zc = domain.quantities['elevation'].centroid_values 772 hc = wc - zc 773 774 wv = domain.quantities['stage'].vertex_values 775 zv = domain.quantities['elevation'].vertex_values 776 hv = wv-zv 777 778 for k in range(domain.number_of_elements): 779 #Compute maximal variation in bed elevation 780 # This quantitiy is 781 # dz = max_i abs(z_i - z_c) 782 # and it is independent of dimension 783 # In the 1d case zc = (z0+z1)/2 784 # In the 2d case zc = (z0+z1+z2)/3 785 786 dz = max(abs(zv[k,0]-zc[k]), 787 abs(zv[k,1]-zc[k]), 788 abs(zv[k,2]-zc[k])) 789 790 791 hmin = min( hv[k,:] ) 792 793 #Create alpha in [0,1], where alpha==0 means using shallow 794 #first order scheme and alpha==1 means using the stage w as 795 #computed by the gradient limiter (1st or 2nd order) 796 # 797 #If hmin > dz/2 then alpha = 1 and the bed will have no effect 798 #If hmin < 0 then alpha = 0 reverting to constant height above bed. 799 800 if dz > 0.0: 801 alpha = max( min( 2*hmin/dz, 1.0), 0.0 ) 802 else: 803 #Flat bed 804 alpha = 1.0 805 806 #Let 807 # 808 # wvi- be the h-limited state (wvi- = zvi + hvi-) 809 # wvi~ be the w-limited stage (wvi~ = zvi + hvi~) 810 # 811 # 812 #where i=0,1,2 denotes the vertex ids 813 # 814 #Weighted balance between w-limited and h-limited stage is 815 # 816 # wvi := (1-alpha)*(zvi+hvi-) + alpha*(zvi+hvi~) 817 # 818 #It follows that the updated wvi is 819 # wvi := zvi + (1-alpha)*hvi- + alpha*hvi~ 820 # 821 # Momentum is balanced between constant and limited ??? 822 823 #print 'Alpha = ', alpha 824 #FIXME: if alpha == 0 compute only h-limited slope, 825 #if alpha == 1 compute only w-limited slope 826 # 827 if alpha < 1: 828 829 #Limit h 830 hvbar = limit_on_h(domain) 831 832 for i in range(3): 833 wv[k,i] = zv[k,i] + (1-alpha)*hvbar[k,i] + alpha*hv[k,i] 834 666 835 #Momentums at centroids 667 836 xmomc = domain.quantities['xmomentum'].centroid_values … … 1289 1458 manning_friction = manning_friction_c 1290 1459 balance_deep_and_shallow = balance_deep_and_shallow_c 1460 #balance_deep_and_shallow = balance_deep_and_shallow_old 1291 1461 protect_against_infinitesimal_and_negative_heights = protect_against_infinitesimal_and_negative_heights_c 1292 1462 -
inundation/ga/storm_surge/pyvolution/test_shallow_water.py
r896 r901 125 125 assert allclose(flux, [0., 0.5*g*h**2, 0.]) 126 126 assert max_speed == sqrt(g*h) 127 128 #def test_flux_slope(self): 129 # #FIXME: TODO 130 # w = 2.0 131 # 132 # normal = array([1.,0]) 133 # ql = array([w, 0, 0]) 134 # qr = array([w, 0, 0]) 135 # zl = zr = 0. 136 # h = w - (zl+zr)/2 137 # 138 # flux, max_speed = flux_function(normal, ql, qr, zl, zr) 139 # 140 # assert allclose(flux, [0., 0.5*g*h**2, 0.]) 141 # assert max_speed == sqrt(g*h) 127 142 128 143 -
inundation/ga/storm_surge/pyvolution/util.py
r900 r901 263 263 for i, t in enumerate(self.T): 264 264 #Interpolate quantities at this timestep 265 print ' time step %d of %d' %(i, len(self.T))265 #print ' time step %d of %d' %(i, len(self.T)) 266 266 for name in self.quantities: 267 267 self.values[name][i, :] =\
Note: See TracChangeset
for help on using the changeset viewer.