Changeset 3510
- Timestamp:
- Aug 21, 2006, 10:03:42 AM (18 years ago)
- Location:
- development/pyvolution-1d
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
development/pyvolution-1d/domain.py
r3425 r3510 22 22 23 23 self.beta = 1.0 24 #self.limiter = "minmod_kurganov" 25 #self.limiter_type = "steven" 26 self.fluxfunc = "unsplit" 27 24 28 #Store Points 25 29 self.coordinates = array(coordinates) -
development/pyvolution-1d/quantity.py
r3425 r3510 51 51 #self.edge_values = zeros((N, 2), Float) 52 52 #edge values are values of the ends of each interval 53 54 #does oe dimension need edge values??? 55 53 56 54 #Intialise centroid values 57 55 self.interpolate() … … 414 412 self.centroid_values += timestep*self.explicit_update 415 413 414 #SECOND ORDER RUNGE_KUTTA 415 #Re-evaluate source term with updated centroid values 416 #and update conserved quantities accordingly 417 """ 418 self.explicit_update = zeros(N, Float) 419 self.domain.compute_forcing_terms() 420 self.centroid_values += 0.5*timestep*(explicit_update 421 """ 422 416 423 ## #Semi implicit updates 417 424 ## denominator = ones(N, Float)-timestep*self.semi_implicit_update … … 679 686 """ 680 687 681 def limit(self):682 """Limit slopes for each volume to eliminate artificial variance688 """def limit(self): 689 Limit slopes for each volume to eliminate artificial variance 683 690 introduced by e.g. second order extrapolator 684 691 … … 690 697 postcondition: 691 698 vertex values are updated 692 """ 693 699 694 700 from Numeric import zeros, Float 695 701 696 702 N = self.domain.number_of_elements 697 #beta = self.beta698 beta = 0.8703 beta = self.beta 704 #beta = 0.8 699 705 700 706 qc = self.centroid_values … … 741 747 qv[k,i] = qc[k] + phi*dq[k,i] 742 748 743 744 749 """ 750 751 752 def limit(self): 753 """Limit slopes for each volume to eliminate artificial variance 754 introduced by e.g. second order extrapolator 755 756 This is an unsophisticated limiter as it does not take into 757 account dependencies among quantities. 758 759 precondition: 760 vertex values are estimated from gradient 761 postcondition: 762 vertex values are updated 763 764 """ 765 import sys 766 from Numeric import zeros, Float 767 from util import minmod, minmod_kurganov, maxmod, vanleer 768 769 N = self.domain.number_of_elements 770 limiter = self.domain.limiter 771 limiter_type = self.domain.limiter_type 772 773 qc = self.centroid_values 774 qv = self.vertex_values 775 776 #Find min and max of this and neighbour's centroid values 777 beta_p = zeros(N,Float) 778 beta_m = zeros(N,Float) 779 beta_x = zeros(N,Float) 780 C = self.domain.centroids 781 X = self.domain.vertices 782 783 for k in range(N): 784 785 n0 = self.domain.neighbours[k,0] 786 n1 = self.domain.neighbours[k,1] 787 if limiter_type == "slope": 788 if ( n0 >= 0) & (n1 >= 0): 789 #SLOPE DERIVATIVE LIMIT 790 beta_p[k] = (qc[k]-qc[k-1])/(C[k]-C[k-1]) 791 beta_m[k] = (qc[k+1]-qc[k])/(C[k+1]-C[k]) 792 beta_x[k] = (qc[k+1]-qc[k-1])/(C[k+1]-C[k-1]) 793 elif limiter_type == "flux": 794 if (n0 >= 0) & (n1 >= 0): 795 # Check denominator not zero 796 if (qc[k+1]-qc[k]) == 0.0: 797 beta_p[k] = float(sys.maxint) 798 beta_m[k] = float(sys.maxint) 799 else: 800 #STEVE LIMIT 801 beta_p[k] = (qc[k]-qc[k-1])/(qc[k+1]-qc[k]) 802 beta_m[k] = (qc[k+2]-qc[k+1])/(qc[k+1]-qc[k]) 803 804 #Deltas between vertex and centroid values 805 dq = zeros(qv.shape, Float) 806 for i in range(2): 807 dq[:,i] =self.domain.vertices[:,i]-self.domain.centroids 808 809 #Phi limiter 810 for k in range(N): 811 if limiter_type == "slope": 812 if limiter == "minmod": 813 phi = minmod(beta_p[k],beta_m[k]) 814 815 elif limiter == "minmod_kurganov": 816 # Also known as monotonized central difference limiter 817 # if theta = 2.0 818 theta = 2.0 819 phi = minmod_kurganov(theta*beta_p[k],theta*beta_m[k],beta_x[k]) 820 elif limiter == "superbee": 821 slope1 = minmod(beta_m[k],2.0*beta_p[k]) 822 slope2 = minmod(2.0*beta_m[k],beta_p[k]) 823 phi = maxmod(slope1,slope2) 824 #phi = max(0.0,min(1.0,2.0*beta_m[k]),min(2.0,beta_m[k]))+max(0.0,min(1.0,2.0*beta_p[k]),min(2.0,beta_p[k]))-1.0 825 826 elif limiter == "vanleer": 827 phi = vanleer(beta_p[k],beta_m[k]) 828 829 830 elif limiter == "muscl": 831 832 #MINMOD 833 #phi = minmod(1.0,beta_m[k]) 834 #SUPERBEE 835 #phi = max(0.0,min(2.0*beta_m[k],1.0),min(beta_m[k],2.0)) 836 #VAN LEER 837 phi = (beta_m[k]+abs(beta_m[k]))/(1.0+abs(beta_m[k])) 838 839 for i in range(2): 840 qv[k,i] = qc[k] + phi*dq[k,i] 841 842 elif limiter_type == "flux": 843 phi = 0.0 844 if limiter == "flux_minmod": 845 #FLUX MINMOD 846 phi = minmod_kurganov(1.0,beta_m[k],beta_p[k]) 847 elif limiter == "flux_superbee": 848 #FLUX SUPERBEE 849 phi = max(0.0,min(1.0,2.0*beta_m[k]),min(2.0,beta_m[k]))+max(0.0,min(1.0,2.0*beta_p[k]),min(2.0,beta_p[k]))-1.0 850 elif limiter == "flux_muscl": 851 #FLUX MUSCL 852 phi = max(0.0,min(2.0,2.0*beta_m[k],2.0*beta_p[k],0.5*(beta_m[k]+beta_p[k]))) 853 elif limiter == "flux_vanleer": 854 #FLUX VAN LEER 855 phi = (beta_m[k]+abs(beta_m[k]))/(1.0+abs(beta_m[k]))+(beta_p[k]+abs(beta_p[k]))/(1.0+abs(beta_p[k]))-1.0 856 857 #Then update using phi limiter 858 n = self.domain.neighbours[k,1] 859 if n>=0: 860 #qv[k,0] = qc[k] - 0.5*phi*(qc[k+1]-qc[k]) 861 #qv[k,1] = qc[k] + 0.5*phi*(qc[k+1]-qc[k]) 862 qv[k,0] = qc[k] + 0.5*phi*(qv[k,0]-qc[k]) 863 qv[k,1] = qc[k] + 0.5*phi*(qv[k,1]-qc[k]) 864 else: 865 qv[k,i] = qc[k] 866 867 745 868 def newLinePlot(title='Simple Plot'): 746 869 import Gnuplot -
development/pyvolution-1d/shallow_water_1d.py
r3425 r3510 64 64 #forcing terms not included in 1d domain ?WHy? 65 65 self.forcing_terms.append(gravity) 66 self.forcing_terms.append(manning_friction)66 #self.forcing_terms.append(manning_friction) 67 67 #print "\nI have Removed forcing terms line 64 1dsw" 68 68 … … 283 283 284 284 285 # Flux computation 286 #def flux_function(normal, ql, qr, zl, zr): 287 def flux_function(normal, ql, qr, zl, zr): 285 def flux_function_unsplit(normal, ql, qr, zl, zr): 288 286 """Compute fluxes between volumes for the shallow water wave equation 289 287 cast in terms of w = h+z using the 'central scheme' as described in … … 376 374 377 375 return edgeflux, max_speed 376 377 def flux_function_split(normal, ql, qr, zl, zr): 378 from config import g, epsilon 379 from math import sqrt 380 from Numeric import array 381 382 #print 'ql',ql 383 384 #Align momentums with x-axis 385 #q_left = rotate(ql, normal, direction = 1) 386 #q_right = rotate(qr, normal, direction = 1) 387 q_left = ql 388 q_left[1] = q_left[1]*normal 389 q_right = qr 390 q_right[1] = q_right[1]*normal 391 392 #z = (zl+zr)/2 #Take average of field values 393 z = 0.5*(zl+zr) #Take average of field values 394 395 w_left = q_left[0] #w=h+z 396 h_left = w_left-z 397 uh_left = q_left[1] 398 399 if h_left < epsilon: 400 u_left = 0.0 #Could have been negative 401 h_left = 0.0 402 else: 403 u_left = uh_left/h_left 404 405 406 w_right = q_right[0] #w=h+z 407 h_right = w_right-z 408 uh_right = q_right[1] 409 410 411 if h_right < epsilon: 412 u_right = 0.0 #Could have been negative 413 h_right = 0.0 414 else: 415 u_right = uh_right/h_right 416 417 #vh_left = q_left[2] 418 #vh_right = q_right[2] 419 420 #soundspeed_left = sqrt(g*h_left) 421 #soundspeed_right = sqrt(g*h_right) 422 423 #Maximal wave speed 424 #s_max = max(u_left+soundspeed_left, u_right+soundspeed_right, 0) 425 s_max = max(u_left, u_right, 0) 426 427 #Minimal wave speed 428 #s_min = min(u_left-soundspeed_left, u_right-soundspeed_right, 0) 429 s_min = min(u_left, u_right, 0) 430 431 #Flux computation 432 433 #flux_left = array([u_left*h_left, 434 # u_left*uh_left + 0.5*g*h_left*h_left]) 435 #flux_right = array([u_right*h_right, 436 # u_right*uh_right + 0.5*g*h_right*h_right]) 437 flux_left = array([u_left*h_left, 438 u_left*uh_left])# + 0.5*g*h_left*h_left]) 439 flux_right = array([u_right*h_right, 440 u_right*uh_right])# + 0.5*g*h_right*h_right]) 441 442 denom = s_max-s_min 443 if denom == 0.0: 444 edgeflux = array([0.0, 0.0]) 445 max_speed = 0.0 446 else: 447 edgeflux = (s_max*flux_left - s_min*flux_right)/denom 448 edgeflux += s_max*s_min*(q_right-q_left)/denom 449 450 edgeflux[1] = edgeflux[1]*normal 451 452 max_speed = max(abs(s_max), abs(s_min)) 453 454 return edgeflux, max_speed 455 378 456 379 457 def compute_fluxes(domain): … … 471 549 #print 'qr',qr 472 550 473 edgeflux, max_speed = flux_function(normal, ql, qr, zl, zr) 551 552 if domain.fluxfunc == "unsplit": 553 edgeflux, max_speed = flux_function_unsplit(normal, ql, qr, zl, zr) 554 elif domain.fluxfunc == "split": 555 edgeflux, max_speed = flux_function_split(normal, ql, qr, zl, zr) 474 556 #print 'edgeflux', edgeflux 475 557 … … 480 562 try: 481 563 #timestep = min(timestep, 0.5*domain.radii[k]/max_speed) 482 #timestep = 0.01483 484 564 timestep = min(timestep, domain.cfl*0.5*domain.areas[k]/max_speed) 485 if (timestep < 1e-6) & (enter == True):486 #print "domain.order", domain.order487 #domain.write_time()488 print "cell number", k489 print "timestep", timestep490 print 'max_speed', max_speed491 s = domain.quantities['stage']492 s = s.centroid_values493 xm = domain.quantities['xmomentum']494 xm = xm.centroid_values495 print 'h', s[k]496 print 'xm', xm[k]497 print 'u', xm[k]/s[k]498 enter = False499 500 565 except ZeroDivisionError: 501 566 pass … … 504 569 #quantities get updated 505 570 flux /= domain.areas[k] 506 # ADD ABOVE LINE AGAIN 571 507 572 Stage.explicit_update[k] = flux[0] 508 573 Xmom.explicit_update[k] = flux[1] … … 608 673 609 674 #Remove very thin layers of water 610 ##protect_against_infinitesimal_and_negative_heights(domain)675 protect_against_infinitesimal_and_negative_heights(domain) 611 676 612 677 #Extrapolate all conserved quantities … … 1001 1066 #h = Stage.edge_values - Elevation.edge_values 1002 1067 h = Stage.vertex_values - Elevation.vertex_values 1003 v = Elevation.vertex_values 1068 b = Elevation.vertex_values 1069 w = Stage.vertex_values 1004 1070 1005 1071 x = domain.get_vertex_coordinates() … … 1014 1080 x0, x1 = x[k,:] 1015 1081 #z0, z1, z2 = v[k,:] 1016 z0, z1 = v[k,:] 1082 b0, b1 = b[k,:] 1083 1084 w0, w1 = w[k,:] 1085 wx = gradient(x0, x1, w0, w1) 1017 1086 1018 1087 #zx, zy = gradient(x0, y0, x1, y1, x2, y2, z0, z1, z2) 1019 zx = gradient(x0, x1, z0, z1)1088 bx = gradient(x0, x1, b0, b1) 1020 1089 1021 1090 #Update momentum 1022 xmom[k] += -g*zx*avg_h 1091 if domain.fluxfunc == "unsplit": 1092 xmom[k] += -g*bx*avg_h 1093 elif domain.fluxfunc == "split": 1094 xmom[k] += -g*wx*avg_h 1023 1095 # ymom[k] += -g*zy*avg_h 1024 1096
Note: See TracChangeset
for help on using the changeset viewer.