Advertisement
Guest User

Untitled

a guest
Apr 5th, 2020
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.62 KB | None | 0 0
  1. # CELL 1 #
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4.  
  5. # Initial values
  6.  
  7. ## Constants
  8. g = -9.81              #[m/s^2]
  9.  
  10. ## Pressures
  11. p_ini = 2000000             #[Pa], 20 bar
  12. p_inj = 34000000            #[Pa], 340 bar
  13.  
  14. ## Host rock
  15. k_host = 2.043*10**(-13)  #[m^2], 207mD
  16.  
  17. ## Reservoir and well dimensions
  18. X = 20                 #[m]
  19. Y = 20                 #[m]
  20. X_well = 20                #[m]
  21. Y_well = 20                #[m]
  22. k_well = 1*10**(-13)     #[m^2]
  23.  
  24. ## Wetting (a) & Non-Wetting (b) properties
  25. Rho_a = 700             #[kg/m^3]
  26. V_a = 500
  27. Rho_b = 1400            #[kg/m^3]
  28. V_b = 1000
  29. if Rho_a == Rho_b:
  30.     print("Similair density not supported")
  31.  
  32. ## Initial saturation of (a) and (b)
  33. Saturation_a = 0
  34. Saturation_b = 1
  35. if Saturation_a + Saturation_b is not 1:
  36.     print("Total saturation >1, check input!")
  37.  
  38. ## Brooks-Corey parameters
  39. disp_p = 1325
  40. pore_size_dist = 1.68
  41.  
  42. n = 2.68      #[-]
  43. m = 1-1/n     #[-]
  44.  
  45. # CELL 2 #
  46. ## Initial absolute pressure matrix
  47. field_p = np.zeros((Y,X))
  48. field_p[:,:] = p_ini
  49. field_p[:Y_well,(X_well-1)] = p_inj
  50.  
  51. ## Initial saturation matrix
  52. Saturation_M_a = np.zeros((Y,X))
  53. Saturation_M_a[:,:] = Saturation_a
  54. Saturation_M_a[:Y_well,(X_well-1)] = Saturation_b
  55.  
  56. Saturation_M_b = np.subtract(np.ones((Y,X)),Saturation_M_a)
  57.  
  58. ## Initial partial pressure matrix
  59. field_p_a = np.multiply(Saturation_M_a, field_p)
  60. field_p_b = np.multiply(Saturation_M_b, field_p)
  61.  
  62. ## Absolute permeability matrix
  63. k_M_reservoir = np.zeros((Y,X))
  64. k_M_reservoir[:,:] = k_host
  65. k_M_reservoir[:Y_well,(X_well-1)] = k_well
  66.  
  67. ### Permeability matrices directional harmonic average
  68. k_M_left = np.copy(k_M_reservoir)
  69. for i in range(Y):
  70.     for j in range(1,X):
  71.         k_M_left[i,j] = (2*k_M_reservoir[i,j-1]*k_M_reservoir[i,j])/(k_M_reservoir[i,j-1]+k_M_reservoir[i,j])
  72. k_M_right = np.copy(k_M_reservoir)
  73. for i in range(Y):
  74.     for j in range(X-1):
  75.         k_M_right[i,j] = (2*k_M_reservoir[i,j+1]*k_M_reservoir[i,j])/(k_M_reservoir[i,j+1]+k_M_reservoir[i,j])
  76. k_M_top = np.copy(k_M_reservoir)
  77. for i in range(1,Y):
  78.     for j in range(X):
  79.         k_M_top[i,j] = (2*k_M_reservoir[i-1,j]*k_M_reservoir[i,j])/(k_M_reservoir[i-1,j]+k_M_reservoir[i,j])
  80. k_M_bottom = np.copy(k_M_reservoir)
  81. for i in range(Y-1):
  82.     for j in range(X):
  83.         k_M_bottom[i,j] = (2*k_M_reservoir[i+1,j]*k_M_reservoir[i,j])/(k_M_reservoir[i+1,j]+k_M_reservoir[i,j])
  84.        
  85. ## Relative permeability matrices
  86. Sew = np.zeros((Y,X))
  87. for i in range(X):
  88.     for j in range(Y):
  89.         cap_p = np.abs((field_p_b[i,j]-field_p_a[i,j])/(Rho_a*g))
  90.         if cap_p > disp_p:
  91.             Sew[i,j] = (disp_p/cap_p)**pore_size_dist
  92.         elif cap_p <= disp_p:
  93.             Sew[i,j] = 1
  94.            
  95. k_M_a = np.zeros((Y,X))
  96. for i in range(X):
  97.     for j in range(Y):
  98.         k_M_a[i,j] = (Sew[i,j]**(1/2))*(1-(1-Sew[i,j]**(1/m)**m))**2
  99.        
  100. k_M_b = np.zeros((Y,X))
  101. for i in range(X):
  102.     for j in range(Y):
  103.         k_M_b[i,j] = ((1-Sew[i,j])**(1/2))*(1-Sew[i,j]**(1/m))**(2*m)
  104.         if np.isnan(k_M_b[i,j]):
  105.             k_M_b[i,j] = 0
  106.  
  107. # CELL 3 #
  108. # Calculations
  109.  
  110. ## Darcy velocity
  111.  
  112. ### Total velocity
  113. vy_field = np.zeros((Y,X))
  114. for i in range(Y):
  115.     for j in range(X-1):
  116.         if i == Y-1:
  117.             vy_field[i,j+1] = -(k_M_top[i,j]*(k_M_b[i,j]/V_b+k_M_a[i,j]/V_a)*(field_p[i,j]-field_p[i-1,j]))
  118.         else:
  119.             vy_field[i,j+1] = -(k_M_bottom[i,j]*(k_M_b[i,j]/V_b+k_M_a[i,j]/V_a)*(field_p[i+1,j]-field_p[i,j]))
  120.        
  121. vx_field = np.zeros((Y,X))
  122. for i in range(Y):
  123.     for j in range(X-1):
  124.             vx_field[i,j+1] = -(k_M_right[i,j]*(k_M_b[i,j]/V_b+k_M_a[i,j]/V_a)*(field_p[i,j+1]-field_p[i,j]))
  125.    
  126. vt_field = np.hypot(vx_field, vy_field)
  127.  
  128. ### Fluid a
  129. vy_field_a = np.zeros((Y,X))
  130. for i in range(Y):
  131.     for j in range(X):
  132.         vy_field_a[i,j] = ((k_M_a[i,j]/V_a)/(k_M_a[i,j]/V_a+k_M_b[i,j]/V_b))*vy_field[i,j] \
  133.                           -((k_M_a[i,j]/V_a)/(k_M_a[i,j]/V_a+k_M_b[i,j]/V_b))*(k_M_b[i,j]/V_b) \
  134.                           *(Rho_b-Rho_a)*k_M_reservoir[i,j]*g
  135.  
  136. vx_field_a = np.zeros((Y,X))
  137. for i in range(Y):
  138.     for j in range(X):
  139.         vx_field_a[i,j] = ((k_M_a[i,j]/V_a)/(k_M_a[i,j]/V_a+k_M_b[i,j]/V_b))*vx_field[i,j]
  140.  
  141. v_field_a = np.hypot(vx_field_a, vy_field_a)
  142.        
  143. ### Fluid b
  144. vy_field_b = np.zeros((Y,X))
  145. for i in range(Y):
  146.     for j in range(X):
  147.         vy_field_b[i,j] = ((k_M_b[i,j]/V_b)/(k_M_b[i,j]/V_b+k_M_a[i,j]/V_a))*vy_field[i,j] \
  148.                           -((k_M_b[i,j]/V_b)/(k_M_b[i,j]/V_b+k_M_a[i,j]/V_a))*(k_M_a[i,j]/V_a) \
  149.                           *(Rho_a-Rho_b)*k_M_reservoir[i,j]*g
  150.  
  151. vx_field_b = np.zeros((Y,X))
  152. for i in range(Y):
  153.     for j in range(X):
  154.         vx_field_b[i,j] = ((k_M_b[i,j]/V_b)/(k_M_b[i,j]/V_b+k_M_a[i,j]/V_a))*vx_field[i,j]
  155.  
  156. v_field_b = np.hypot(vx_field_b, vy_field_b)
  157.        
  158. ## Pressure matrices
  159.  
  160. ### Total pressure matrix t+dt
  161. field_pn = np.copy(field_p)
  162. for i in range(Y):
  163.     for j in range(1,X-1):
  164.         if i == 0:
  165.             field_pn[i,j] = (k_M_left[i,j]*(k_M_a[i,j-1]/V_a+k_M_b[i,j-1]/V_b)*field_p[i,j-1] \
  166.                             +k_M_right[i,j]*(k_M_a[i,j+1]/V_a+k_M_b[i,j+1]/V_b)*field_p[i,j+1] \
  167.                             +k_M_bottom[i,j]*(k_M_a[i+1,j]/V_a+k_M_b[i+1,j]/V_b)*field_p[i+1,j] \
  168.                             -k_M_bottom[i,j]*(Rho_a*(k_M_a[i+1,j]/V_a)+Rho_b*(k_M_b[i+1,j]/V_b))*g \
  169.                             )/(k_M_left[i,j-1]*(k_M_a[i,j]/V_a+k_M_b[i,j-1]/V_b) \
  170.                             +k_M_right[i,j]*(k_M_a[i,j+1]/V_a+k_M_b[i,j+1]/V_b) \
  171.                             +k_M_bottom[i,j]*(k_M_a[i+1,j]/V_a+k_M_b[i+1,j]/V_b))
  172.         elif i == (Y-1):
  173.             field_pn[i,j] = (k_M_left[i,j]*(k_M_a[i,j-1]/V_a+k_M_b[i,j-1]/V_b)*field_p[i,j-1] \
  174.                             +k_M_right[i,j]*(k_M_a[i,j+1]/V_a+k_M_b[i,j+1]/V_b)*field_p[i,j+1] \
  175.                             +k_M_top[i,j]*(k_M_a[i-1,j]/V_a+k_M_b[i-1,j]/V_b)*field_p[i-1,j] \
  176.                             +k_M_top[i,j]*(Rho_a*(k_M_a[i-1,j]/V_a)+Rho_b*(k_M_b[i-1,j]/V_b))*g \
  177.                             )/(k_M_left[i,j]*(k_M_a[i,j-1]/V_a+k_M_b[i,j-1]/V_b) \
  178.                             +k_M_right[i,j]*(k_M_a[i,j+1]/V_a+k_M_b[i,j+1]/V_b) \
  179.                             +k_M_top[i,j]*(k_M_a[i-1,j]/V_a+k_M_b[i-1,j]/V_b))
  180.         else:
  181.             field_pn[i,j] = (k_M_left[i,j]*(k_M_a[i,j-1]/V_a+k_M_b[i,j-1]/V_b)*field_p[i,j-1] \
  182.                             +k_M_right[i,j]*(k_M_a[i,j+1]/V_a+k_M_b[i,j+1]/V_b)*field_p[i,j+1] \
  183.                             +k_M_bottom[i,j]*(k_M_a[i+1,j]/V_a+k_M_b[i+1,j]/V_b)*field_p[i+1,j] \
  184.                             -k_M_bottom[i,j]*(Rho_a*(k_M_a[i+1,j]/V_a)+Rho_b*(k_M_b[i+1,j]/V_b))*g \
  185.                             +k_M_top[i,j]*(k_M_a[i-1,j]/V_a+k_M_b[i-1,j]/V_b)*field_p[i-1,j] \
  186.                             +k_M_top[i,j]*(Rho_a*(k_M_a[i-1,j]/V_a)+Rho_b*(k_M_b[i-1,j]/V_b))*g \
  187.                             )/(k_M_left[i,j]*(k_M_a[i,j-1]/V_a+k_M_b[i,j-1]/V_b) \
  188.                             +k_M_right[i,j]*(k_M_a[i,j+1]/V_a+k_M_b[i,j+1]/V_b) \
  189.                             +k_M_bottom[i,j]*(k_M_a[i+1,j]/V_a+k_M_b[i+1,j]/V_b) \
  190.                             +k_M_top[i,j]*(k_M_a[i-1,j]/V_a+k_M_b[i-1,j]/V_b))
  191.  
  192. ### Partial pressure change matrix fluid b
  193. field_p_by = np.zeros((Y,X))
  194. for i in range(Y):
  195.     for j in range(X-1):
  196.         A = vy_field_b[i,j+1]
  197.         if i == Y-1:
  198.             B = -(k_M_top[i,j]*(k_M_b[i,j]/V_b))
  199.             if A == 0:
  200.                 field_p_by[i,j] = 0
  201.             elif B == 0:
  202.                 field_p_by[i,j] = 0
  203.             else:
  204.                 field_p_by[i,j] = A/B
  205.         else:
  206.             B = -(k_M_bottom[i,j]*(k_M_b[i,j]/V_b))
  207.             if A == 0:
  208.                 field_p_by[i,j] = 0
  209.             elif B == 0:
  210.                 field_p_by[i,j] = 0
  211.             else:
  212.                 field_p_by[i,j] = A/B
  213.        
  214. field_p_bx = np.zeros((Y,X))
  215. for i in range(Y):
  216.     for j in range(X-1):
  217.         A = vx_field_b[i,j+1]
  218.         B = -(k_M_right[i,j]*(k_M_b[i,j]/V_b))
  219.         if A == 0:
  220.             field_p_bx[i,j] = 0
  221.         elif B == 0:
  222.             field_p_bx[i,j] = 0
  223.         else:
  224.             field_p_bx[i,j] = A/B
  225.  
  226. field_pcomb_b = np.add(field_p_by, field_p_bx)
  227. field_pn_b = np.add(field_pcomb_b, field_p_b)
  228.  
  229. ### Partial pressure change matrix fluid a
  230. field_p_ay = np.zeros((Y,X))
  231. for i in range(Y):
  232.     for j in range(X-1):
  233.         A = vy_field_a[i,j+1]
  234.         if i == Y-1:
  235.             B = -(k_M_top[i,j]*(k_M_a[i,j]/V_a))
  236.             if A == 0:
  237.                 field_p_ay[i,j] = 0
  238.             elif B == 0:
  239.                 field_p_ay[i,j] = 0
  240.             else:
  241.                 field_p_ay[i,j] = A/B
  242.         else:
  243.             B = -(k_M_bottom[i,j]*(k_M_a[i,j]/V_a))
  244.             if A == 0:
  245.                 field_p_ay[i,j] = 0
  246.             elif B == 0:
  247.                 field_p_ay[i,j] = 0
  248.             else:
  249.                 field_p_ay[i,j] = A/B
  250.        
  251. field_p_ax = np.zeros((Y,X))
  252. for i in range(Y):
  253.     for j in range(X-1):
  254.         A = vx_field_a[i,j+1]
  255.         B = -(k_M_right[i,j]*(k_M_a[i,j]/V_a))
  256.         if A == 0:
  257.             field_p_ax[i,j] = 0
  258.         elif B == 0:
  259.             field_p_ax[i,j] = field_pn[i,j]-field_p[i,j]
  260.         else:
  261.             field_p_ax[i,j] = A/B
  262.  
  263. field_pcomb_a = np.add(field_p_ay, field_p_ax)
  264. field_pn_a = np.add(field_pcomb_a, field_p_a)
  265.            
  266. ### Apply changes to pressure fields
  267. field_p = np.copy(field_pn)
  268. field_p_a = np.copy(field_pn_a)
  269. field_p_b = np.copy(field_pn_b)
  270.        
  271. ## Change in relative permeability-loop
  272. Sew = np.zeros((Y,X))
  273. for i in range(X):
  274.     for j in range(Y):
  275.         cap_p = np.abs((field_p_b[i,j]-field_p_a[i,j])/(Rho_a*g))
  276.         if cap_p > disp_p:
  277.             Sew[i,j] = (disp_p/cap_p)**pore_size_dist
  278.         elif cap_p <= disp_p:
  279.             Sew[i,j] = 1
  280.            
  281. knew_M_a = np.zeros((Y,X))
  282. for i in range(X):
  283.     for j in range(Y):
  284.         knew_M_a[i,j] = (Sew[i,j]**(1/2))*(1-(1-Sew[i,j]**(1/m)**m))**2
  285. k_M_a = np.copy(knew_M_a)
  286.        
  287. knew_M_b = np.zeros((Y,X))
  288. for i in range(X):
  289.     for j in range(Y):
  290.         knew_M_b[i,j] = ((1-Sew[i,j])**(1/2))*(1-Sew[i,j]**(1/m))**(2*m)
  291.         if np.isnan(knew_M_b[i,j]):
  292.             knew_M_b[i,j] = 0
  293. k_M_b = np.copy(knew_M_b)
  294.  
  295. # Plots
  296. fig, (ax1,ax2) = plt.subplots(2,1,figsize=(15,15))        
  297. ax1.set_title("Total velocity vector field (m/s)")
  298. Mr = np.around((vt_field*3600),decimals=2)
  299. color = np.copy(vt_field)
  300. Q = ax1.quiver(vx_field, vy_field, color, units='x', pivot='tail')
  301. ax1.set(xlabel="Width [m]", ylabel="Height [m]")
  302. ax1.set_aspect('equal')
  303.  
  304. plot1 = ax2.matshow(field_p,cmap=plt.get_cmap('plasma'))
  305. ax2.set_title("Pressure field")
  306. ax2.set(xlabel="Width [m]", ylabel="Depth [m]")
  307. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement