Advertisement
Guest User

Non-linear ODE Finite DIfference

a guest
Aug 11th, 2019
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     !Discretization of du/dx + u^2 = 0 for 0<=x<=1, discretized to N-1 parts(so that x and u range from x_1 to x_N)
  2.     !=> (u_i - u_(i-1))/delX + u_i^2 = 0
  3.     !let u_i = u_gi + delu_i where, u_gi = guess for u_i and delu_i = error in guess
  4.     !so, u_i^2 = u_gi^2 + 2*delu_i*u_gi + delu_i^2. Neglecting delu_i^2 for being very small,
  5.     !u_i^2 = 2*u_gi*delu_i + u_gi^2 = 2*u_gi*(u_i - u_gi) + u_gi^2 = 2*u_i*u_gi - u_gi^2
  6.     !So, linearized(in u_i) finite difference equation:
  7.     !(2*delX*u_gi + 1)*u_i - u_(i-1) - delX*u_gi^2 = 0 ; i=2,3,4,..,N
  8.     !and u_1 = 1 (Boundary Condition)
  9.     !Matrix form:
  10.     ![1     0            0     0               0]      [u_1]               [1]
  11.     ![-1  1+2*delX*u_g2  0     0    ...        0]      [u_2]               [delX*u_g2^2]
  12.     ![0    -1   1+2*delX*u_g3  0    ...        0]      [u_3]       =       [delX*u_g3^2]
  13.     ![0     0           -1   1+2*delX*u_g4 ... 0]      [u_4]               [delX*u_g4^2]
  14.     ![..........................................]      [...]               [...]
  15.     ![0     0     0    ...   -1    1+2*delX*u_gN]_NxN  [u_N]_Nx1           [delX*u_gN^2]_Nx1
  16.     ![A][U]=[B]
  17.     !=> [U]=Inverse([A]).[B]
  18.     !guess u_gi;i=1,2,...N and find [U] vector i.e. u_i;i=1,2,...N
  19.     !update u_gi with the recently computed u_i and continue iterating till Sum(|u_i - u_gi|);i=1,2,...N is less than tolerance
  20.    
  21.     implicit none
  22.    
  23.     real A(50,50),U(50,50),B(50,50),U_guess(50,50)
  24.     real AInverse(50,50)
  25.     real error(50,50)
  26.     real sumOfErrors,tolerance
  27.    
  28.  
  29. integer N
  30. integer i,j
  31. real delX
  32. N=4
  33. delX=1/real(N-1)
  34. U_guess=1 !fill all elements of initial guess vector with 1
  35. tolerance=0.00001
  36.  
  37. write(*,*) "N = ",N
  38.  
  39. 10 A(1,1)=1
  40. do i=2,N
  41.     do j=1,N
  42.         if(i.EQ.j) then
  43.             A(i,j)=1+2*delX*U_guess(i,1)
  44.         else if(i.EQ.j+1) then
  45.             A(i,j)=-1
  46.         else
  47.             A(i,j)=0
  48.         endif
  49.     end do
  50.     end do
  51.        
  52.     !populate the B vector
  53.     B(1,1)=1
  54.     do i=2,N
  55.         B(i,1)=delX*U_guess(i,1)**2
  56.     end do
  57.    
  58.    
  59.    
  60.  
  61.  
  62.     call Inverse(A,AInverse,N)
  63.     call matrixMul(AInverse,B,U,N,N,N,1)  
  64.    
  65.     !populate the error vector
  66.     sumOfErrors=0
  67.     do i=1,N
  68.         error(i,1) =  abs(U(i,1)  -  U_guess(i,1))
  69.         sumOfErrors=sumOfErrors+error(i,1)
  70.     end do
  71.    
  72.     write(*,*) "U guess = ",(U_guess(i,1),i=1,N)
  73.     write(*,*) "U       = ",(U(i,1),i=1,N)
  74.     write(*,*)
  75.    
  76.     U_guess=U !update guess vector with solution of current iteration
  77.    
  78.     if(sumOfErrors.GT.tolerance) then
  79.         goto 10
  80.     endif
  81.    
  82.     open(5,file="output.txt")
  83.     do i=1,N
  84.         write(5,*) U(i,1)
  85.     end do
  86.     close(5)
  87.    
  88.     end program
  89.    
  90.    
  91.    
  92.    
  93. subroutine matrixMul(A,B,C,arow,acol,brow,bcol)
  94. integer arow,acol,brow,bcol
  95. !To see how this works, try writing the elements of the product matrix in sigma notation
  96. dimension A(50,50),B(50,50),C(50,50) !CAUTION: This declaration is crucial
  97. do k=1,arow !k runs from 1 to arow
  98.     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
  99.         sum=0
  100.         do i=1,acol !this loop is the essence of the aforementioned sigma notation for the (k,l) element of the product matrix
  101.             sum=sum+A(k,i)*B(i,l)
  102.         end do
  103.         C(k,l)=sum
  104.     end do
  105. end do
  106. return
  107. end subroutine matrixMul
  108.    
  109. subroutine Inverse(X,XI,size)
  110. dimension X(50,50),XI(50,50),originalX(50,50)
  111. integer rowindex,colindex,size,tmpi,tmpj,i,j
  112. real pivotelement
  113.  
  114. originalX=X
  115.  
  116. do i=1,size
  117.     do j=1,size
  118.         if(i.EQ.j) then
  119.             XI(i,j)=1
  120.         else
  121.             XI(i,j)=0 !this is for good measure coz by default, XI may have been changed by the caller itself though it is 0 by default
  122.         endif
  123.     end do
  124. end do
  125.  
  126.  
  127. do rowindex=1,size !loop over rows of X
  128.    
  129.     pivotelement=X(rowindex,rowindex) !this is crucial!
  130.    
  131.     !divide the row by pivot element
  132.     do colindex=1,size
  133.         X(rowindex,colindex)=X(rowindex,colindex)/pivotelement
  134.     end do
  135.     do colindex=1,size
  136.         XI(rowindex,colindex)=XI(rowindex,colindex)/pivotelement
  137.     end do
  138.    
  139.    
  140.     !perform row operations to make non-pivot elements of this column zero
  141.     do i=1,size !i gives the row number being manipulated
  142.         pivotelement=X(i,rowindex) !pivot element for the currently manipulated row. this i crucial
  143.        
  144.         if(i.NE.rowindex) then !row operations are for non-current rows only
  145.            
  146.             do j=1,size !column index for ith row of X matrix
  147.                 X(i,j)=X(i,j)-pivotelement*X(rowindex,j)
  148.             end do
  149.             do j=1,size !column index for ith row of XI matrix
  150.                 XI(i,j)=XI(i,j)-pivotelement*XI(rowindex,j)
  151.             end do
  152.            
  153.            
  154.         endif
  155.     end do
  156.    
  157.  
  158.    
  159. end do
  160.  
  161. !restore X to original X since upon inversion completion, X has been reduced to an Identity matrix. good practice
  162. X=originalX
  163.  
  164. end subroutine
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement