/Interactive_Relative_Permeability

Creates Water-Oil and Gas-Liquid relative permeability curves with interactive gas relative perm parameters. Outputs relative perm tables needed for reservoir simulators.

Interactive Relative Permeability

Creates Corey relative perm curves with interactive gas relative perm parameters, and prepares tables for CMG and SLB reservoir simulators.

####################################################################################################

#Author: Mouin Almasoodi, PhD
#Objective: 3-Phase Relative Perm Model

#%%#####################################(Tools Needed for Analysis)#################################

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

#%%#####################################(INPUTS)################################

#Saturations
Swcon = Swirr =  Swcrit = 0.18   
Soirw = Sorw = 0.11
Soirg = Sorg =  0.11        
Sgcon = Sgc = 0 
    
#Max Relative Perm - endpoints          
krw_sgc = 0.6
krg_Swirr = Krgcl = 0.1
Krocw = Kro_swirr_ = Krogcg = 0.9
Krwiro = krw_sgc = 0.6

#Corey Exponents
now = 3
nw = 3
ng = 2
nog = 1.5



#%%#####################################(Equations Used)################################

# Krw = Krwiro * ((Sw - Swcrit)/(1.0 - Swcrit - Soirw)) ^ Nw				
# Krow = Krocw  * ((So - Sorw  )/(1.0 - Swcon  - Sorw )) ^ Now				
# Krog = Krogcg * ((Sl - Sorg  - Swcon)/(1.0 - Sgcon  - Sorg  - Swcon)) ^ Nog				
# Krg = Krgcl * ((Sg - Sgcrit)/(1.0 - Sgcrit - Soirg - Swcon)) ^ Ng		

#%%#####################################(Water-oil Table)################################		

#Create Water-oil Table
SWT = pd.DataFrame()

#create SW column
SWT['Sw'] = (np.linspace(0.18 ,(1-Sorw), 17, endpoint=True))
#Evaluate Krw          
SWT['Krw'] = Krwiro * ((SWT['Sw'] - Swcrit)/(1.0 - Swcrit - Soirw)) ** nw
#Evaluate So
So = 1-SWT['Sw']
#Evaluate Krow
SWT['Krow'] = Krocw  * (( So - Sorw  )/(1.0 - Swcon  - Sorw )) ** now
# Hard code 0 for the last value in Krow column to avoid null and negative values
SWT['Krow'].iloc[-1] = 0



fig, ax = plt.subplots(2,1, figsize=(7,9))
plt.subplots_adjust(left=None, bottom=0.25, right=None, top=None, wspace=0.2, hspace=0.3)

ax[0].set_title('Oil-Water Table') 
ax[0].plot( SWT['Sw'], SWT['Krw'], lw = 2, color = 'blue') 
ax[0].plot( SWT['Sw'], SWT['Krow'], lw = 2, color = 'green') 
ax[0].set_xlabel("Sw", fontsize = 12)
ax[0].set_ylabel("Krw and Krow", fontsize = 12)
ax[0].grid(which='both')

#%%#####################################(Gas-Liquid Table)################################	

#Create Gas-Liquid Table
SGT = pd.DataFrame()

# saturation of liquid
SL = (np.linspace(Swirr+Sorg ,(1-Sgc), 17, endpoint=True))
#Saturation of gas
SGT['Sg'] = (np.linspace(Sgc ,(1-(Swirr+Sorg)), 17, endpoint=True))	
#Evaluate Krg
SGT['Krg'] = Krgcl * ((SGT['Sg'] - Sgc)/(1.0 - Sgc - Soirg - Swcon)) ** ng
#Evaluate Krog
SGT['Krog'] = Krogcg * ((SL - Sorg  - Swcon)/(1.0 - Sgcon  - Sorg  - Swcon)) ** nog
#Reverse Krog Values to use in SGT table	
SGT['Krog'] = SGT['Krog'].values[::-1]


ax[1].set_title('Liquid-Gas Table') 
 
#ax[1].plot( SGT['Sg'], SGT['Krg'], '--r', lw = 2) 
ax[1].plot( SGT['Sg'], SGT['Krog'], lw = 2, color = 'green') 
ax[1].set_xlabel("Sg", fontsize = 12)
ax[1].set_ylabel("Krg and Krog", fontsize = 12)
ax[1].grid(which='both')


#%%######## Creating Krg Interactive Plot #################################


#Define function for Krg to use in the interactive plot
def Krg(Krgcl, ng):
    Krg_temp = Krgcl * ((SGT['Sg'] - Sgc)/(1.0 - Sgc - Soirg - Swcon)) ** ng
    return Krg_temp

#Call the function
Krg(Krgcl, ng)


#Initial plot using the function 
line0, = ax[1].plot( SGT['Sg'], Krg(Krgcl, ng), lw = 2, color = 'red')


#set the color for the slider
axis_color = 'lightgoldenrodyellow'

# Define an axes area and draw a slider in it
Krgcl_slider_ax  = fig.add_axes([0.2, 0.15, 0.65, 0.03], facecolor=axis_color)
Krgcl_slider = Slider(Krgcl_slider_ax, 'Krg', 0.01, 1, valinit=krg_Swirr)

# Draw another slider
Ng_slider_ax = fig.add_axes([0.2, 0.1, 0.65, 0.03], facecolor=axis_color)
Ng_slider = Slider(Ng_slider_ax, 'ng', 1, 5, valinit=ng)


# Define an action for modifying the line when any slider's value changes
def sliders_on_changed(val):
    line0.set_ydata(Krg(Krgcl_slider.val, Ng_slider.val))
    fig.canvas.draw_idle()
Krgcl_slider.on_changed(sliders_on_changed)
Ng_slider.on_changed(sliders_on_changed)




###Bonus
#%%#####################################(Multiple Krg Plot)################################	
fig, ax2 = plt.subplots( )
ax2.set_title('Krg Vs. Gas Saturation') 
ax2.set_xlabel("Sg", fontsize = 12)
ax2.set_ylabel("Krg", fontsize = 12)
ax2.grid(which='both')


Krgcl = [0.6, 1]
ng = [1.5, 1.5]
linestyle = ['solid','dashed']

#loop to evalute and plot multiple Krg curves
for i,j,k in zip(Krgcl, ng, linestyle):

    SGT['Krg'] = i * ((SGT['Sg'] - Sgc)/(1.0 - Sgc - Soirg - Swcon)) ** j
    ax2.plot( SGT['Sg'], SGT['Krg'], lw = 2, color = 'red', linestyle = k) 

 

alt text