Advertisement
Guest User

Artificial Viscosity Smoothening

a guest
Jul 15th, 2019
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. dimension Q(100,100),R(100,100),RTranspose(100,100),RTransposeR(100,100),RTransposeRInverse(100,100),RTransposeQ(100,100),U(100,100)
  2.     integer qrow,qcol,rrow,rcol
  3.     real epsilon_i_plus_1by2,epsilon_i_minus_1by2,nu_i,nu_i_plus_1,K,tmp !variables for artificial smoothening
  4.     K=3.5 !trial artificial viscosity for smoothening. change until the unit hydrograph is smooth enough
  5.    
  6.     qrow=16 !16 non-zero DRH ordinates
  7.     qcol=1
  8.     rrow=16 !16 rows of Rainfall matrix
  9.     rcol=14 !14 rows of Rainfall matrix (qrow-(no. of ERH ordinates-1)) = 16-(3-1) = 16-2 = 14
  10.     open(5,file='Q.txt')
  11.     do i=1,qrow
  12.         read (5,*)(Q(i,j),j=1,qcol)
  13.     end do
  14.     open(5,file='R.txt')
  15.     do i=1,rrow
  16.         read (5,*)(R(i,j),j=1,rcol)
  17.     end do
  18.    
  19.     call Transpose(R,RTranspose,rrow,rcol)
  20.     call MatMul(RTranspose,R,RTransposeR,rcol,rrow,rrow,rcol)
  21.     call Inverse(RTransposeR,RTransposeRInverse,rcol)
  22.     call MatMul(RTranspose,Q,RTransposeQ,rcol,rrow,qrow,qcol)
  23.     call MatMul(RTransposeRInverse,RTransposeQ,U,rcol,rcol,rcol,1)
  24.  
  25.     open(5,file='U.txt')
  26.     do i=1,rcol !U vector has a size of rcol
  27.        
  28.         !this mess inside the if block below is for artificial smoothening
  29.         if(i.GT.10) then !filter the UH ordinates that you want to smoothen(here, UH ordinates above the 10th)
  30.             if(i.NE.rcol) then !if not the last value
  31.                 nu_i_plus_1=abs(U(i+1,1)-2*U(i,1)+U(i-1,1))/(abs(U(i+1,1))+2*abs(U(i,1))+abs(U(i-1,1)))
  32.                 nu_i=abs(U(i,1)-2*U(i-1,1)+U(i-2,1))/(abs(U(i,1))+2*abs(U(i-1,1))+abs(U(i-2,1)))
  33.                 nu_i_minus_1=abs(U(i-1,1)-2*U(i-2,1)+U(i-3,1))/(abs(U(i-1,1))+2*abs(U(i-2,1))+abs(U(i-3,1)))
  34.             else !if last value
  35.                 nu_i_plus_1=abs(U(i,1)+U(i-1,1))/(abs(U(i,1))+abs(U(i-1,1)))
  36.                 nu_i=abs(U(i-1,1)+U(i-2,1))/(abs(U(i-1,1))+abs(U(i-2,1)))
  37.                 nu_i_minus_1=abs(U(i-2,1)+U(i-3,1))/(abs(U(i-2,1))+abs(U(i-3,1)))
  38.             endif
  39.            
  40.             if(nu_i_plus_1.GT.nu_i) then
  41.                 tmp=nu_i_plus_1
  42.             else
  43.                 tmp=nu_i
  44.             endif
  45.             epsilon_i_plus_1by2=K*tmp
  46.            
  47.             if(nu_i_minus_1.GT.nu_i) then
  48.                 tmp=nu_i_minus_1
  49.             else
  50.                 tmp=nu_i
  51.             endif
  52.             epsilon_i_minus_1by2=K*tmp
  53.            
  54.             U(i,1)=U(i,1)+epsilon_i_plus_1by2*(U(i+1,1)-U(i,1))-epsilon_i_minus_1by2*(U(i,1)-U(i-1,1))  
  55.         endif
  56.        
  57.         write (5,*) U(i,1)
  58.     end do
  59.    
  60.     end program
  61.    
  62.    
  63. subroutine Transpose(A,R,rows,cols) !rows,cols = of A
  64. integer rows,cols
  65. dimension A(100,100),R(100,100) !CAUTION: This declaration is crucial
  66.     do i=1,cols !i goes from 1 to cols
  67.         do j=1,rows !and j from 1 to rows because transpose should have the dimension: cols x rows
  68.             R(i,j)=A(j,i) !fills from column of A to row of R
  69.         end do
  70.     end do
  71.     return
  72. end subroutine Transpose
  73.    
  74.    
  75. subroutine MatMul(A,B,C,arow,acol,brow,bcol)
  76. integer arow,acol,brow,bcol
  77. !To see how this works, try writing the elements of the product matrix in sigma notation
  78. dimension A(100,100),B(100,100),C(100,100) !CAUTION: This declaration is crucial
  79. do k=1,arow !k runs from 1 to arow
  80.     do l=1,bcol !and l from 1 to bcol because that's the output matrix dimension and we _have_ to populate each element of it
  81.         sum=0
  82.         do i=1,acol !this loop is the essence of the aforementioned sigma notation for the (k,l) element of the product matrix
  83.             sum=sum+A(k,i)*B(i,l)
  84.         end do
  85.         C(k,l)=sum
  86.     end do
  87. end do
  88. return
  89. end subroutine MatMul
  90.    
  91. subroutine Inverse(X,XI,size)
  92. dimension X(100,100),XI(100,100)
  93. integer rowindex,colindex,size,tmpi,tmpj,i,j
  94. real pivotelement
  95.  
  96. do i=1,size
  97.     do j=1,size
  98.         if(i.EQ.j) then
  99.             XI(i,j)=1
  100.         endif
  101.     end do
  102. end do
  103.  
  104.  
  105. do rowindex=1,size !loop over rows of X
  106.    
  107.     pivotelement=X(rowindex,rowindex) !this is crucial!
  108.    
  109.     !divide the row by pivot element
  110.     do colindex=1,size
  111.         X(rowindex,colindex)=X(rowindex,colindex)/pivotelement
  112.     end do
  113.     do colindex=1,size
  114.         XI(rowindex,colindex)=XI(rowindex,colindex)/pivotelement
  115.     end do
  116.    
  117.    
  118.     !perform row operations to make non-pivot elements of this column zero
  119.     do i=1,size !i gives the row number being manipulated
  120.         pivotelement=X(i,rowindex) !pivot element for the currently manipulated row. this i crucial
  121.        
  122.         if(i.NE.rowindex) then !row operations are for non-current rows only
  123.            
  124.             do j=1,size !column index for ith row of X matrix
  125.                 X(i,j)=X(i,j)-pivotelement*X(rowindex,j)
  126.             end do
  127.             do j=1,size !column index for ith row of XI matrix
  128.                 XI(i,j)=XI(i,j)-pivotelement*XI(rowindex,j)
  129.             end do
  130.            
  131.            
  132.         endif
  133.     end do
  134.    
  135.    
  136.    
  137. end do
  138.  
  139.  
  140. end subroutine
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement