DryWetGas.Rmd
Examples
Example 1: Dry Gas Reservoir
(Ikoku, Chi, 1984)
Part I: History Match
library(Rmbal) library(Rrelperm) library(pracma) library(minpack.lm) library(ggplot2) library(dplyr) #> #> Attaching package: 'dplyr' #> The following objects are masked from 'package:stats': #> #> filter, lag #> The following objects are masked from 'package:base': #> #> intersect, setdiff, setequal, union library(magrittr) #> #> Attaching package: 'magrittr' #> The following objects are masked from 'package:pracma': #> #> and, mod, or p_pvt <- c(1798, 1680, 1540, 1428, 1335) # psia Bg <- c(0.00152, 0.00163, 0.00179, 0.00196, 0.00210) # RB/SCF Bo <- rep(0, length(p_pvt)) # RB/STB Rv <- rep(0, length(p_pvt)) # STB/SCF Rs <- rep(1e8, length(p_pvt)) # SCF/STB Bw <- rep(1, length(p_pvt)) # RB/STB muo <- rep(0.5, length(p_pvt)) # cp muw <- rep(0.25, length(p_pvt)) # cp mug <- rep(0.015, length(p_pvt)) # cp pvt_table <- data.frame(p = p_pvt, Bo = Bo, Rs = Rs, Rv = Rv, Bg = Bg, Bw = Bw, muo = muo, mug = mug, muw = muw) p <- c(1798, 1680, 1540, 1428, 1335) Np <- rep(0, length.out = length(p)) Gp <- c(0, 0.96, 2.12, 3.21, 3.92) * 1e9 # SCF Wp <- rep(0, length.out = length(p)) We <- rep(0, length.out = length(p)) Wi <- rep(0, length.out = length(p)) wf <- rep(1, length.out = length(p)) mbal_optim_gas_lst <- mbal_optim_param_gas(input_unit = "Field", output_unit = "Field", unknown_param = "G", aquifer_model = NULL, G = NULL, phi = 0.13, swi = 0.52, Np = Np, Gp = Gp, Wp = Wp, Wi = Wi, We = We, pd = 0, p = p, pvt = pvt_table, M = 0, cf = 3e-6, wf = wf, sgrw = 0.0) time_lst <- mbal_time(c(0, 0.5, 1.0, 1.5, 2.0), "year") # a number of plots will be automatically generated for quality check optim_results <- mbal_optim_gas(mbal_optim_gas_lst, time_lst)
glimpse(optim_results) #> List of 17 #> $ input_unit : chr "Field" #> $ output_unit: chr "Field" #> $ G : num 1.41e+10 #> $ phi : num 0.13 #> $ swi : num 0.52 #> $ pd : num 0 #> $ p : num [1:5] 1798 1680 1540 1428 1335 #> $ cf : num [1:5] 3e-06 3e-06 3e-06 3e-06 3e-06 #> $ M : num 0 #> $ pvt :'data.frame': 5 obs. of 9 variables: #> ..$ p : num [1:5] 1798 1680 1540 1428 1335 #> ..$ Bo : num [1:5] 0 0 0 0 0 #> ..$ Rs : num [1:5] 1e+08 1e+08 1e+08 1e+08 1e+08 #> ..$ Rv : num [1:5] 0 0 0 0 0 #> ..$ Bg : num [1:5] 0.00152 0.00163 0.00179 0.00196 0.0021 #> ..$ Bw : num [1:5] 1 1 1 1 1 #> ..$ muo: num [1:5] 0.5 0.5 0.5 0.5 0.5 #> ..$ mug: num [1:5] 0.015 0.015 0.015 0.015 0.015 #> ..$ muw: num [1:5] 0.25 0.25 0.25 0.25 0.25 #> $ prod :'data.frame': 5 obs. of 3 variables: #> ..$ Np: num [1:5] 0 0 0 0 0 #> ..$ Gp: num [1:5] 0.00 9.60e+08 2.12e+09 3.21e+09 3.92e+09 #> ..$ Wp: num [1:5] 0 0 0 0 0 #> $ inj :'data.frame': 5 obs. of 1 variable: #> ..$ Wi: num [1:5] 0 0 0 0 0 #> $ We : num [1:5] 0 0 0 0 0 #> $ aquifer :List of 3 #> ..$ input_unit : chr "Field" #> ..$ output_unit: chr "Field" #> ..$ We : num [1:5] 0 0 0 0 0 #> ..- attr(*, "class")= chr [1:2] "NoA" "aquifer" #> $ wf : num [1:5] 1 1 1 1 1 #> $ sgrw : num 0 #> $ p_est : num [1:5] 1798 1680 1543 1426 1335 #> - attr(*, "class")= chr [1:2] "volumetric_gas" "mbal_gas"
Part II: Reservoir Performance
mbal_results <- mbal_perform_gas(optim_results, time_lst) mbal_results #> P (psia) Eo (bbl/STB) Eg (bbl/SCF) Ew (bbl/STB) Ef (bbl/bbl) Egwf (bbl/SCF) #> 1 1798 0 0.00000 0 0.000000 0.0000000000 #> 2 1680 0 0.00011 0 0.000354 0.0001111210 #> 3 1540 0 0.00027 0 0.000774 0.0002724510 #> 4 1428 0 0.00044 0 0.001110 0.0004435150 #> 5 1335 0 0.00058 0 0.001389 0.0005843985 #> Et (bbl) F (bbl) We Igd Inwd Ifwd Iawd Itot RF_oil #> 1 0 0 0 NA NA NA NA NA 0.00000000 #> 2 1566668 1564800 0 0.9899119 0 0.010088102 0 1 0.06817239 #> 3 3841220 3794800 0 0.9910039 0 0.008996113 0 1 0.15220726 #> 4 6253009 6291600 0 0.9920747 0 0.007925324 0 1 0.22628316 #> 5 8239291 8232000 0 0.9924735 0 0.007526542 0 1 0.27828500 #> RF_gas SOg SGg SWg SOT SGT SWT qo (STB/day) qg (SCF/day) qw (STB/day) #> 1 0.00000000 0 0.48 0.52 0 0.48 0.52 0 0 0 #> 2 0.06817239 0 0.48 0.52 0 0.48 0.52 0 5260274 0 #> 3 0.15220726 0 0.48 0.52 0 0.48 0.52 0 6356164 0 #> 4 0.22628316 0 0.48 0.52 0 0.48 0.52 0 5972603 0 #> 5 0.27828500 0 0.48 0.52 0 0.48 0.52 0 3890411 0 #> fo fw GOR (SCF/STB) kro/krg #> 1 0 0 Inf 0 #> 2 0 0 Inf 0 #> 3 0 0 Inf 0 #> 4 0 0 Inf 0 #> 5 0 0 Inf 0 p1 <- mbal_results %>% ggplot(aes(`P (psia)`, `RF_gas`, color = "Forecast")) + geom_point(size = 3) + scale_color_manual(name="Data", values=c("Forecast" = "red")) + ggtitle("Gas Recovery Plot") + theme_bw() p1
Part III: Reservoir Forecast
# gas saturation above the bubble point is zero, however the mbal_forecast_param_oil() # requires a table of relative permeabilities as an input for the gas-oil system. # Therefore, an arbitrary table is generated using the 'Rrelperm' package. # The generated table does not impact the predictions above the bubble point. rel_perm <- as.data.frame(Rrelperm::kr2p_gl(SWCON = 0.52, SOIRG = 0.15, SORG = 0.15, SGCON = 0.05, SGCRIT = 0.05, KRGCL = 1, KROGCG = 1, NG = 1, NOG = 1.0, NP = 101)) colnames(rel_perm) <- c("Sg", "Sl", "Krg", "Krog") forecast_lst <- mbal_forecast_param_gas(input_unit = "Field", output_unit = "Field", G = 1.41e10, phi = 0.13, swi = 0.52, pd = 0, p = p, pvt = pvt_table, M = 0, cf = 3e-6, wf = wf, rel_perm = rel_perm) glimpse(forecast_lst) #> List of 12 #> $ input_unit : chr "Field" #> $ output_unit: chr "Field" #> $ G : num 1.41e+10 #> $ phi : num 0.13 #> $ swi : num 0.52 #> $ pd : num 0 #> $ p : num [1:5] 1798 1680 1540 1428 1335 #> $ cf : num [1:5] 3e-06 3e-06 3e-06 3e-06 3e-06 #> $ M : num 0 #> $ pvt :'data.frame': 5 obs. of 9 variables: #> ..$ p : num [1:5] 1798 1680 1540 1428 1335 #> ..$ Bo : num [1:5] 0 0 0 0 0 #> ..$ Rs : num [1:5] 1e+08 1e+08 1e+08 1e+08 1e+08 #> ..$ Rv : num [1:5] 0 0 0 0 0 #> ..$ Bg : num [1:5] 0.00152 0.00163 0.00179 0.00196 0.0021 #> ..$ Bw : num [1:5] 1 1 1 1 1 #> ..$ muo: num [1:5] 0.5 0.5 0.5 0.5 0.5 #> ..$ mug: num [1:5] 0.015 0.015 0.015 0.015 0.015 #> ..$ muw: num [1:5] 0.25 0.25 0.25 0.25 0.25 #> $ wf : num [1:5] 1 1 1 1 1 #> $ rel_perm :'data.frame': 101 obs. of 4 variables: #> ..$ Sg : num [1:101] 0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 ... #> ..$ Sl : num [1:101] 1 0.99 0.98 0.97 0.96 0.95 0.94 0.93 0.92 0.91 ... #> ..$ Krg : num [1:101] 0 0 0 0 0 ... #> ..$ Krog: num [1:101] 1 1 1 1 1 ... #> - attr(*, "class")= chr [1:2] "volumetric_forecast_gas" "forecast_gas" forecast_results <- mbal_forecast_gas(forecast_lst, time_lst) forecast_results #> P (psia) SOg SGg SWg SOT SGT SWT GOR (SCF/STB) RF_oil RF_gas #> 1 1798 0 0.48 0.52 0 0.48 0.52 Inf 0.00000000 0.00000000 #> 2 1680 0 0.48 0.52 0 0.48 0.52 Inf 0.06748466 0.06748466 #> 3 1540 0 0.48 0.52 0 0.48 0.52 Inf 0.15083799 0.15083799 #> 4 1428 0 0.48 0.52 0 0.48 0.52 Inf 0.22448980 0.22448980 #> 5 1335 0 0.48 0.52 0 0.48 0.52 Inf 0.27619048 0.27619048 #> Liq_volume Igd Inwd Ifwd Iawd Itot #> 1 0 NA NA NA NA NA #> 2 0 0.9899119 0 0.010088102 0 1 #> 3 0 0.9910039 0 0.008996113 0 1 #> 4 0 0.9920747 0 0.007925324 0 1 #> 5 0 0.9924735 0 0.007526542 0 1 p1 <- forecast_results %>% ggplot(aes(`P (psia)`, `RF_gas`, color = "Forecast")) + geom_point(size = 3) + geom_point(data = mbal_results, aes(`P (psia)`, `RF_gas`, color = "Field"))+ scale_color_manual(name="Data", values=c("Forecast" = "red", "Field" = "black")) + ggtitle("Oil Recovery Plot") + theme_bw() p1
Example 2: Dry Gas Reservoir with Aquifer
(Pletcher, 2002)
Part I: History Match
library(Rmbal) library(Rrelperm) library(pracma) library(minpack.lm) library(ggplot2) library(dplyr) library(magrittr) p_pvt <- c(6411, 5947, 5509, 5093, 4697, 4319, 3957, 3610, 3276, 2953, 2638) Bg <- c(6279, 6587, 6933, 7327, 7778, 8300, 8910, 9628, 10487, 11532, 12829) / 10000 # RB/SCF Bo <- rep(0, length(p_pvt)) # RB/STB Rv <- rep(0, length(p_pvt)) # STB/SCF Rs <- rep(1e8, length(p_pvt)) # SCF/STB Bw <- c(1.0452, 1.0467, 1.0480, 1.0493, 1.0506, 1.0517, 1.0529, 1.0540, 1.0551, 1.0560, 1.0571) # RB/STB muo <- rep(0.5, length(p_pvt)) # cp muw <- rep(0.25, length(p_pvt)) # cp mug <- rep(0.025, length(p_pvt)) # cp pvt_table <- data.frame(p = p_pvt, Bo = Bo, Rs = Rs, Rv = Rv, Bg = Bg, Bw = Bw, muo = muo, mug = mug, muw = muw) p <- c(6411, 5947, 5509, 5093, 4697, 4319, 3957, 3610, 3276, 2953, 2638) # psia Np <- rep(0, length.out = length(p)) Gp <- c(0, 5.475, 10.950, 16.425, 21.900, 27.375, 32.850, 38.325, 43.800, 49.275, 54.750) * 1e9 # SCF Wp <- c(0, 378, 1434, 3056, 5284, 8183, 11864, 16425, 22019, 28860, 37256) # STB Wi <- rep(0, length.out = length(p)) wf <- rep(1, length.out = length(p)) mbal_optim_gas_lst <- mbal_optim_param_gas(input_unit = "Field", output_unit = "Field", unknown_param = "We", aquifer_model = "pot", G = 101e9, phi = 0.15, swi = 0.15, Np = Np, Gp = Gp, Wp = Wp, Wi = Wi, We = NULL, pd = 0, p = p, pvt = pvt_table, M = 0, cf = 6e-6, wf = wf, sgrw = 0.0, phi_a = 0.15, h_a = 200, r_a = 500, r_R = 210.6, tetha = 360, cw_a = 3e-6, cf_a = 6e-6, mult_len = 2) time_lst <- mbal_time(c(1:length(p)), "year") # a number of plots will be automatically generated for quality check optim_results <- mbal_optim_gas(mbal_optim_gas_lst, time_lst)
glimpse(optim_results) #> List of 17 #> $ input_unit : chr "Field" #> $ output_unit: chr "Field" #> $ G : num 1.01e+11 #> $ phi : num 0.15 #> $ swi : num 0.15 #> $ pd : num 0 #> $ p : num [1:11] 6411 5947 5509 5093 4697 ... #> $ cf : num [1:11] 6e-06 6e-06 6e-06 6e-06 6e-06 6e-06 6e-06 6e-06 6e-06 6e-06 ... #> $ M : num 0 #> $ pvt :'data.frame': 11 obs. of 9 variables: #> ..$ p : num [1:11] 6411 5947 5509 5093 4697 ... #> ..$ Bo : num [1:11] 0 0 0 0 0 0 0 0 0 0 ... #> ..$ Rs : num [1:11] 1e+08 1e+08 1e+08 1e+08 1e+08 1e+08 1e+08 1e+08 1e+08 1e+08 ... #> ..$ Rv : num [1:11] 0 0 0 0 0 0 0 0 0 0 ... #> ..$ Bg : num [1:11] 0.628 0.659 0.693 0.733 0.778 ... #> ..$ Bw : num [1:11] 1.05 1.05 1.05 1.05 1.05 ... #> ..$ muo: num [1:11] 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ... #> ..$ mug: num [1:11] 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 ... #> ..$ muw: num [1:11] 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 ... #> $ prod :'data.frame': 11 obs. of 3 variables: #> ..$ Np: num [1:11] 0 0 0 0 0 0 0 0 0 0 ... #> ..$ Gp: num [1:11] 0.00 5.48e+09 1.10e+10 1.64e+10 2.19e+10 ... #> ..$ Wp: num [1:11] 0 378 1434 3056 5284 ... #> $ inj :'data.frame': 11 obs. of 1 variable: #> ..$ Wi: num [1:11] 0 0 0 0 0 0 0 0 0 0 ... #> $ We : NULL #> $ aquifer :List of 12 #> ..$ input_unit : chr "Field" #> ..$ output_unit: chr "Field" #> ..$ model : chr "pot" #> ..$ phi : num 0.15 #> ..$ h_a : num 200 #> ..$ r_a : num 63512 #> ..$ r_R : num 211 #> ..$ tetha : num 360 #> ..$ c_water : num 3e-06 #> ..$ c_rock : num 6e-06 #> ..$ pressure : num [1:11] 6411 5947 5509 5093 4697 ... #> ..$ mult_len : num 1 #> ..- attr(*, "class")= chr [1:2] "pot" "aquifer" #> $ wf : num [1:11] 1 1 1 1 1 1 1 1 1 1 ... #> $ sgrw : num 0 #> $ p_est : num [1:11] 6411 5949 5509 5092 4695 ... #> - attr(*, "class")= chr [1:2] "water_drive_gas" "mbal_gas"
Part II: Reservoir Performance
mbal_results <- mbal_perform_gas(optim_results, time_lst) mbal_results #> P (psia) Eo (bbl/STB) Eg (bbl/SCF) Ew (bbl/STB) Ef (bbl/bbl) Egwf (bbl/SCF) #> 1 6411 0 0.0000 0.0000 0.000000 0.00000000 #> 2 5947 0 0.0308 0.0015 0.002784 0.03301558 #> 3 5509 0 0.0654 0.0028 0.005412 0.06969472 #> 4 5093 0 0.1048 0.0041 0.007908 0.11107634 #> 5 4697 0 0.1499 0.0054 0.010284 0.15806933 #> 6 4319 0 0.2021 0.0065 0.012552 0.21206133 #> 7 3957 0 0.2631 0.0077 0.014724 0.27479301 #> 8 3610 0 0.3349 0.0088 0.016806 0.34824761 #> 9 3276 0 0.4208 0.0099 0.018810 0.43574460 #> 10 2953 0 0.5253 0.0108 0.020748 0.54177162 #> 11 2638 0 0.6550 0.0119 0.022638 0.67298439 #> Et (bbl) F (bbl) We Igd Inwd Ifwd #> 1 0 0 0 NA NA NA #> 2 3617316708 3606382896 282743700 0.8599745 0.07816393 0.06186171 #> 3 7588808773 7591636503 549644004 0.8704133 0.07242823 0.05715868 #> 4 12021845864 12034600707 803138356 0.8804638 0.06680658 0.05272990 #> 5 17009441970 17033825551 1044445479 0.8900880 0.06140387 0.04850847 #> 6 22692969573 22721258606 1274784097 0.8994900 0.05617529 0.04433506 #> 7 29249454812 29269362492 1495372932 0.9084990 0.05112481 0.04037663 #> 8 36879813117 36899327312 1706821346 0.9171657 0.04628064 0.03655412 #> 9 45920529098 45933083232 1910348062 0.9255294 0.04160118 0.03286992 #> 10 56826075082 56823960476 2107171801 0.9336436 0.03708107 0.02927589 #> 11 70270504750 70238814383 2299120650 0.9414334 0.03271815 0.02584902 #> Iawd Itot RF_oil RF_gas SOg SGg SWg SOT SGT #> 1 NA NA 0.00000000 0.00000000 0 0.85 0.15 0 0.8500000 #> 2 -1.093774e-07 1 0.05437227 0.05437227 0 0.85 0.15 0 0.8462103 #> 3 -1.980327e-07 1 0.10837548 0.10837548 0 0.85 0.15 0 0.8426331 #> 4 -2.667361e-07 1 0.16245145 0.16245145 0 0.85 0.15 0 0.8392355 #> 5 -3.263699e-07 1 0.21652136 0.21652136 0 0.85 0.15 0 0.8360012 #> 6 -3.792391e-07 1 0.27070225 0.27070225 0 0.85 0.15 0 0.8329140 #> 7 -4.270714e-07 1 0.32502645 0.32502645 0 0.85 0.15 0 0.8299575 #> 8 -4.694153e-07 1 0.37925495 0.37925495 0 0.85 0.15 0 0.8271234 #> 9 -5.059229e-07 1 0.43354506 0.43354506 0 0.85 0.15 0 0.8243956 #> 10 -5.363059e-07 1 0.48788970 0.48788970 0 0.85 0.15 0 0.8217577 #> 11 -5.604530e-07 1 0.54232409 0.54232409 0 0.85 0.15 0 0.8191851 #> SWT qo (STB/day) qg (SCF/day) qw (STB/day) fo fw #> 1 0.1500000 0 0.0e+00 0.000000 0 0.000000e+00 #> 2 0.1537897 0 1.5e+07 1.035616 0 1.097090e-07 #> 3 0.1573669 0 1.5e+07 2.893151 0 2.915545e-07 #> 4 0.1607645 0 1.5e+07 4.443836 0 4.242678e-07 #> 5 0.1639988 0 1.5e+07 6.104110 0 5.496678e-07 #> 6 0.1670860 0 1.5e+07 7.942466 0 6.709306e-07 #> 7 0.1700425 0 1.5e+07 10.084932 0 7.944943e-07 #> 8 0.1728766 0 1.5e+07 12.495890 0 9.119690e-07 #> 9 0.1756044 0 1.5e+07 15.326027 0 1.027970e-06 #> 10 0.1782423 0 1.5e+07 18.742466 0 1.144180e-06 #> 11 0.1808149 0 1.5e+07 23.002740 0 1.263604e-06 #> GOR (SCF/STB) kro/krg #> 1 Inf 0 #> 2 Inf 0 #> 3 Inf 0 #> 4 Inf 0 #> 5 Inf 0 #> 6 Inf 0 #> 7 Inf 0 #> 8 Inf 0 #> 9 Inf 0 #> 10 Inf 0 #> 11 Inf 0 p1 <- mbal_results %>% ggplot(aes(`P (psia)`, `RF_gas`, color = "Forecast")) + geom_point(size = 3) + scale_color_manual(name="Data", values=c("Forecast" = "red")) + ggtitle("Gas Recovery Plot") + theme_bw() p1
Example 3: Wet Gas Reservoir
(Walsh & Lake, 2003)
Part I: Reservoir Forecast
library(Rmbal) library(Rrelperm) library(pracma) library(minpack.lm) library(ggplot2) library(dplyr) library(magrittr) p_pvt <- c(10300, 9800, 9300, 8800, 8300, 7800, 7300, 6800, 6300, 5800, 5300, 4800, 4300, 3800, 3300, 2800, 2300, 1800, 1300, 1050, 800, 738, 300) # psia Bg <- c(0.5, 0.51, 0.52, 0.532, 0.545, 0.560, 0.577, 0.597, 0.621, 0.648, 0.668, 0.72, 0.77, 0.83, 0.92, 1.06, 1.27, 1.63, 2.26, 2.925, 3.59, 4.19, 8.39) / 1000 # RB/SCF Bo <- c(18.62, 18.97, 19.36, 19.8, 20.20, 20.85, 21.49, 22.23, 23.11, 24.15, 25.31, 26.80, 28.66, 30.89, 34.24, 39.45, 47.26, 60.66, 84.11, 108.86, 133.60, 155.93, 312.24) # RB/STB Rv <- rep(26.9, length(p_pvt)) / 1e6 # STB/SCF Rs <- rep(37216, length(p_pvt)) # SCF/STB cw <- 2e-6 Bwi <- 1.0 Bw <- Bwi * exp(cw * (p_pvt[1] - p_pvt)) # RB/STB muo <- rep(0.5, length(p_pvt)) # cp muw <- rep(0.25, length(p_pvt)) # cp mug <- c(0.047, 0.0455, 0.044, 0.0425, 0.041, 0.00395, 0.0379, 0.0363, 0.0347, 0.033, 0.0311, 0.0289, 0.02267, 0.0243, 0.0220, 0.0197, 0.0177, 0.0160, 0.0147, 0.0142, 0.0138, 0.0136, 0.0128) # cp pvt_table <- data.frame(p = p_pvt, Bo = Bo, Rs = Rs, Rv = Rv, Bg = Bg, Bw = Bw, muo = muo, mug = mug, muw = muw) p <- p_pvt wf <- rep(1,length(p)) # in-situ oil saturation is zero, however the mbal_forecast_param_gas() # requires a table of relative permeabilities as an input for the gas-oil system. # Therefore, an arbitrary table is generated using the 'Rrelperm' package. # The generated table does not impact the predictions. rel_perm <- as.data.frame(Rrelperm::kr2p_gl(SWCON = 0.2, SOIRG = 0.15, SORG = 0.15, SGCON = 0.05, SGCRIT = 0.05, KRGCL = 1, KROGCG = 1, NG = 2.0, NOG = 2.0, NP = 101)) colnames(rel_perm) <- c("Sg", "Sl", "Krg", "Krog") forecast_lst <- mbal_forecast_param_gas(input_unit = "Field", output_unit = "Field", G = 69.48e9, phi = 0.1, swi = 0.2, pd = 0, p = p, pvt = pvt_table, cf = 3e-6, M = 0, wf = wf, rel_perm = rel_perm) time_lst <- mbal_time(1:length(p_pvt), "year") glimpse(forecast_lst) #> List of 12 #> $ input_unit : chr "Field" #> $ output_unit: chr "Field" #> $ G : num 6.95e+10 #> $ phi : num 0.1 #> $ swi : num 0.2 #> $ pd : num 0 #> $ p : num [1:23] 10300 9800 9300 8800 8300 7800 7300 6800 6300 5800 ... #> $ cf : num [1:23] 3e-06 3e-06 3e-06 3e-06 3e-06 3e-06 3e-06 3e-06 3e-06 3e-06 ... #> $ M : num 0 #> $ pvt :'data.frame': 23 obs. of 9 variables: #> ..$ p : num [1:23] 10300 9800 9300 8800 8300 7800 7300 6800 6300 5800 ... #> ..$ Bo : num [1:23] 18.6 19 19.4 19.8 20.2 ... #> ..$ Rs : num [1:23] 37216 37216 37216 37216 37216 ... #> ..$ Rv : num [1:23] 2.69e-05 2.69e-05 2.69e-05 2.69e-05 2.69e-05 2.69e-05 2.69e-05 2.69e-05 2.69e-05 2.69e-05 ... #> ..$ Bg : num [1:23] 0.0005 0.00051 0.00052 0.000532 0.000545 0.00056 0.000577 0.000597 0.000621 0.000648 ... #> ..$ Bw : num [1:23] 1 1 1 1 1 ... #> ..$ muo: num [1:23] 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ... #> ..$ mug: num [1:23] 0.047 0.0455 0.044 0.0425 0.041 0.00395 0.0379 0.0363 0.0347 0.033 ... #> ..$ muw: num [1:23] 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 ... #> $ wf : num [1:23] 1 1 1 1 1 1 1 1 1 1 ... #> $ rel_perm :'data.frame': 101 obs. of 4 variables: #> ..$ Sg : num [1:101] 0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 ... #> ..$ Sl : num [1:101] 1 0.99 0.98 0.97 0.96 0.95 0.94 0.93 0.92 0.91 ... #> ..$ Krg : num [1:101] 0 0 0 0 0 ... #> ..$ Krog: num [1:101] 1 1 1 1 1 ... #> - attr(*, "class")= chr [1:2] "volumetric_forecast_gas" "forecast_gas" forecast_results <- mbal_forecast_gas(forecast_lst, time_lst) forecast_results #> P (psia) SOg SGg SWg SOT SGT SWT GOR (SCF/STB) RF_oil RF_gas #> 1 10300 0 0.8 0.2 0 0.8 0.2 37174.72 0.00000000 0.00000000 #> 2 9800 0 0.8 0.2 0 0.8 0.2 37174.72 0.01960784 0.01960784 #> 3 9300 0 0.8 0.2 0 0.8 0.2 37174.72 0.03846154 0.03846154 #> 4 8800 0 0.8 0.2 0 0.8 0.2 37174.72 0.06015038 0.06015038 #> 5 8300 0 0.8 0.2 0 0.8 0.2 37174.72 0.08256881 0.08256881 #> 6 7800 0 0.8 0.2 0 0.8 0.2 37174.72 0.10714286 0.10714286 #> 7 7300 0 0.8 0.2 0 0.8 0.2 37174.72 0.13344887 0.13344887 #> 8 6800 0 0.8 0.2 0 0.8 0.2 37174.72 0.16247906 0.16247906 #> 9 6300 0 0.8 0.2 0 0.8 0.2 37174.72 0.19484702 0.19484702 #> 10 5800 0 0.8 0.2 0 0.8 0.2 37174.72 0.22839506 0.22839506 #> 11 5300 0 0.8 0.2 0 0.8 0.2 37174.72 0.25149701 0.25149701 #> 12 4800 0 0.8 0.2 0 0.8 0.2 37174.72 0.30555556 0.30555556 #> 13 4300 0 0.8 0.2 0 0.8 0.2 37174.72 0.35064935 0.35064935 #> 14 3800 0 0.8 0.2 0 0.8 0.2 37174.72 0.39759036 0.39759036 #> 15 3300 0 0.8 0.2 0 0.8 0.2 37174.72 0.45652174 0.45652174 #> 16 2800 0 0.8 0.2 0 0.8 0.2 37174.72 0.52830189 0.52830189 #> 17 2300 0 0.8 0.2 0 0.8 0.2 37174.72 0.60629921 0.60629921 #> 18 1800 0 0.8 0.2 0 0.8 0.2 37174.72 0.69325153 0.69325153 #> 19 1300 0 0.8 0.2 0 0.8 0.2 37174.72 0.77876106 0.77876106 #> 20 1050 0 0.8 0.2 0 0.8 0.2 37174.72 0.82905983 0.82905983 #> 21 800 0 0.8 0.2 0 0.8 0.2 37174.72 0.86072423 0.86072423 #> 22 738 0 0.8 0.2 0 0.8 0.2 37174.72 0.88066826 0.88066826 #> 23 300 0 0.8 0.2 0 0.8 0.2 37174.72 0.94040524 0.94040524 #> Liq_volume Igd Inwd Ifwd Iawd Itot #> 1 0 NA NA NA NA NA #> 2 0 0.9039497 0 0.096050307 0 1 #> 3 0 0.9039446 0 0.096055419 0 1 #> 4 0 0.9093993 0 0.090600698 0 1 #> 5 0 0.9136870 0 0.086312993 0 1 #> 6 0 0.9186383 0 0.081361727 0 1 #> 7 0 0.9235133 0 0.076486741 0 1 #> 8 0 0.9287579 0 0.071242140 0 1 #> 9 0 0.9343340 0 0.065666002 0 1 #> 10 0 0.9392795 0 0.060720472 0 1 #> 11 0 0.9404848 0 0.059515172 0 1 #> 12 0 0.9495238 0 0.050476211 0 1 #> 13 0 0.9548766 0 0.045123354 0 1 #> 14 0 0.9597959 0 0.040204128 0 1 #> 15 0 0.9657674 0 0.034232564 0 1 #> 16 0 0.9723039 0 0.027696133 0 1 #> 17 0 0.9783790 0 0.021621014 0 1 #> 18 0 0.9842514 0 0.015748602 0 1 #> 19 0 0.9892390 0 0.010760994 0 1 #> 20 0 0.9919508 0 0.008049230 0 1 #> 21 0 0.9935020 0 0.006498019 0 1 #> 22 0 0.9945174 0 0.005482582 0 1 #> 23 0 0.9973108 0 0.002689221 0 1 p1 <- forecast_results %>% ggplot(aes(`P (psia)`, `RF_gas`, color = "Forecast")) + geom_point(size = 3) + scale_color_manual(name="Data", values=c("Forecast" = "red")) + ggtitle("Gas Recovery Plot") + theme_bw() p1
Example 4: Over-pressured Gas Reservoir
(Fetkovich, Reese, & Whitson, 1998)
Part I: History Match
library(Rmbal) library(Rrelperm) library(pracma) library(minpack.lm) library(ggplot2) library(dplyr) library(magrittr) # Anderson "L" gas reservoir p_pvt <- c(9507, 9292, 8970, 8595, 8332, 8009, 7603, 7406, 7002, 6721, 6535, 5764, 4766, 4295, 3750, 3247) # Psia Bg <- c(1.44, 1.418, 1.387, 1.344, 1.316, 1.282, 1.239, 1.218, 1.176, 1.147, 1.127, 1.048, 0.977, 0.928, 0.891, 0.854) * (266 + 459.67) / p_pvt / ((60 + 459.67) / 14.696) / 5.615 # RB/SCF Bo <- rep(0, length(p_pvt)) # RB/STB Rv <- rep(0, length(p_pvt)) # STB/SCF Rs <- rep(1e8, length(p_pvt)) # SCF/STB Bw <- 1.055 * exp(3e-6 * (p_pvt[1] - p_pvt)) # RB/STB muo <- rep(0.5, length(p_pvt)) # cp muw <- rep(0.25, length(p_pvt)) # cp mug <- rep(0.015, length(p_pvt)) # cp pvt_table <- data.frame(p = p_pvt, Bo = Bo, Rs = Rs, Rv = Rv, Bg = Bg, Bw = Bw, muo = muo, mug = mug, muw = muw) p <- p_pvt Gp <- c(0, 392.5, 1642.2, 3225.8, 4260.3, 5503.5, 7538.1, 8749.2, 10509.3, 11758.9, 12789.2, 17262.5, 22890.8, 28144.6, 32566.7, 36819.9) * 1e6 # SCF Np <- Rv * Gp # STB Wp <- rep(0, length.out = length(p)) We <- rep(0, length.out = length(p)) Wi <- rep(0, length.out = length(p)) wf <- rep(1, length.out = length(p)) mbal_optim_gas_lst <- mbal_optim_param_gas(input_unit = "Field", output_unit = "Field", unknown_param = "G_M", aquifer_model = NULL, G = NULL, phi = 0.22, swi = 0.35, Np = Np, Gp = Gp, Wp = Wp, Wi = Wi, We = We, pd = 0, p = p, pvt = pvt_table, M = NULL, cf = 3.2e-6, wf = wf, sgrw = 0.0) time_lst <- mbal_time(c(0:15), "month") # a number of plots will be automatically generated for quality check optim_results <- mbal_optim_gas(mbal_optim_gas_lst, time_lst)
glimpse(optim_results) #> List of 17 #> $ input_unit : chr "Field" #> $ output_unit: chr "Field" #> $ G : num 7.63e+10 #> $ phi : num 0.22 #> $ swi : num 0.35 #> $ pd : num 0 #> $ p : num [1:16] 9507 9292 8970 8595 8332 ... #> $ cf : num [1:16] 3.2e-06 3.2e-06 3.2e-06 3.2e-06 3.2e-06 3.2e-06 3.2e-06 3.2e-06 3.2e-06 3.2e-06 ... #> $ M : num 1.05 #> $ pvt :'data.frame': 16 obs. of 9 variables: #> ..$ p : num [1:16] 9507 9292 8970 8595 8332 ... #> ..$ Bo : num [1:16] 0 0 0 0 0 0 0 0 0 0 ... #> ..$ Rs : num [1:16] 1e+08 1e+08 1e+08 1e+08 1e+08 1e+08 1e+08 1e+08 1e+08 1e+08 ... #> ..$ Rv : num [1:16] 0 0 0 0 0 0 0 0 0 0 ... #> ..$ Bg : num [1:16] 0.000554 0.000558 0.000565 0.000571 0.000577 ... #> ..$ Bw : num [1:16] 1.05 1.06 1.06 1.06 1.06 ... #> ..$ muo: num [1:16] 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ... #> ..$ mug: num [1:16] 0.015 0.015 0.015 0.015 0.015 0.015 0.015 0.015 0.015 0.015 ... #> ..$ muw: num [1:16] 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 ... #> $ prod :'data.frame': 16 obs. of 3 variables: #> ..$ Np: num [1:16] 0 0 0 0 0 0 0 0 0 0 ... #> ..$ Gp: num [1:16] 0.00 3.92e+08 1.64e+09 3.23e+09 4.26e+09 ... #> ..$ Wp: num [1:16] 0 0 0 0 0 0 0 0 0 0 ... #> $ inj :'data.frame': 16 obs. of 1 variable: #> ..$ Wi: num [1:16] 0 0 0 0 0 0 0 0 0 0 ... #> $ We : num [1:16] 0 0 0 0 0 0 0 0 0 0 ... #> $ aquifer :List of 3 #> ..$ input_unit : chr "Field" #> ..$ output_unit: chr "Field" #> ..$ We : num [1:16] 0 0 0 0 0 0 0 0 0 0 ... #> ..- attr(*, "class")= chr [1:2] "NoA" "aquifer" #> $ wf : num [1:16] 1 1 1 1 1 1 1 1 1 1 ... #> $ sgrw : num 0 #> $ p_est : num [1:16] 9507 9407 9106 8678 8406 ... #> - attr(*, "class")= chr [1:2] "volumetric_gas" "mbal_gas"
Part II: Reservoir Performance
mbal_results <- mbal_perform_gas(optim_results, time_lst) mbal_results #> P (psia) Eo (bbl/STB) Eg (bbl/SCF) Ew (bbl/STB) Ef (bbl/bbl) Egwf (bbl/SCF) #> 1 9507 0 0.000000e+00 0.0000000000 0.0000000 0.000000e+00 #> 2 9292 0 4.155668e-06 0.0006806945 0.0006880 6.122769e-06 #> 3 8970 0 1.154615e-05 0.0017009748 0.0017184 1.646025e-05 #> 4 8595 0 1.791807e-05 0.0028904323 0.0029184 2.626564e-05 #> 5 8332 0 2.367540e-05 0.0037254372 0.0037600 3.443188e-05 #> 6 8009 0 3.144052e-05 0.0047518394 0.0047936 4.515649e-05 #> 7 7603 0 4.201038e-05 0.0060434035 0.0060928 5.944792e-05 #> 8 7406 0 4.748984e-05 0.0066706655 0.0067232 6.673380e-05 #> 9 7002 0 6.024781e-05 0.0079581904 0.0080160 8.319762e-05 #> 10 6721 0 7.014171e-05 0.0088546420 0.0089152 9.567015e-05 #> 11 6535 0 7.670890e-05 0.0094484385 0.0095104 1.039447e-04 #> 12 5764 0 1.109256e-04 0.0119133574 0.0119776 1.452424e-04 #> 13 4766 0 1.956269e-04 0.0151124827 0.0151712 2.391193e-04 #> 14 4295 0 2.360908e-04 0.0166256204 0.0166784 2.839172e-04 #> 15 3750 0 3.147957e-04 0.0183791614 0.0184224 3.676401e-04 #> 16 3247 0 4.076709e-04 0.0200001132 0.0200320 4.651495e-04 #> Et (bbl) F (bbl) We Igd Inwd Ifwd Iawd Itot RF_oil #> 1 0.0 0.0 0 NA NA NA NA NA 0.00000000 #> 2 467164.3 218911.0 0 0.6787236 0 0.3212764 0 1 0.01097792 #> 3 1255909.0 928049.1 0 0.7014563 0 0.2985437 0 1 0.02912672 #> 4 2004055.5 1843536.5 0 0.6821865 0 0.3178135 0 1 0.04595934 #> 5 2627135.3 2459278.5 0 0.6876010 0 0.3123990 0 1 0.05964763 #> 6 3445417.7 3219657.0 0 0.6962569 0 0.3037431 0 1 0.07718796 #> 7 4535846.5 4489615.2 0 0.7066754 0 0.2933246 0 1 0.09981353 #> 8 5091755.6 5258874.8 0 0.7116310 0 0.2883690 0 1 0.11102515 #> 9 6347937.2 6450894.1 0 0.7241530 0 0.2758470 0 1 0.13553916 #> 10 7299584.6 7334273.9 0 0.7331619 0 0.2668381 0 1 0.15338610 #> 11 7930925.2 8060882.8 0 0.7379783 0 0.2620217 0 1 0.16491605 #> 12 11081923.3 11471016.6 0 0.7637271 0 0.2362729 0 1 0.21857235 #> 13 18244680.9 17149932.0 0 0.8181145 0 0.1818855 0 1 0.31916344 #> 14 21662737.3 22224950.1 0 0.8315481 0 0.1684519 0 1 0.35953893 #> 15 28050756.1 28280110.1 0 0.8562605 0 0.1437395 0 1 0.42336556 #> 16 35490676.1 35393139.9 0 0.8764299 0 0.1235701 0 1 0.48390051 #> RF_gas SOg SGg SWg SOT SGT SWT qo (STB/day) qg (SCF/day) #> 1 0.00000000 0 0.65 0.35 0 0.65 0.35 0 0 #> 2 0.01097792 0 0.65 0.35 0 0.65 0.35 0 12904108 #> 3 0.02912672 0 0.65 0.35 0 0.65 0.35 0 41086023 #> 4 0.04595934 0 0.65 0.35 0 0.65 0.35 0 52063556 #> 5 0.05964763 0 0.65 0.35 0 0.65 0.35 0 34010955 #> 6 0.07718796 0 0.65 0.35 0 0.65 0.35 0 40872324 #> 7 0.09981353 0 0.65 0.35 0 0.65 0.35 0 66890952 #> 8 0.11102515 0 0.65 0.35 0 0.65 0.35 0 39816982 #> 9 0.13553916 0 0.65 0.35 0 0.65 0.35 0 57866295 #> 10 0.15338610 0 0.65 0.35 0 0.65 0.35 0 41082735 #> 11 0.16491605 0 0.65 0.35 0 0.65 0.35 0 33872873 #> 12 0.21857235 0 0.65 0.35 0 0.65 0.35 0 147067381 #> 13 0.31916344 0 0.65 0.35 0 0.65 0.35 0 185039980 #> 14 0.35953893 0 0.65 0.35 0 0.65 0.35 0 172727652 #> 15 0.42336556 0 0.65 0.35 0 0.65 0.35 0 145384094 #> 16 0.48390051 0 0.65 0.35 0 0.65 0.35 0 139831218 #> qw (STB/day) fo fw GOR (SCF/STB) kro/krg #> 1 0 0 0 Inf 0 #> 2 0 0 0 Inf 0 #> 3 0 0 0 Inf 0 #> 4 0 0 0 Inf 0 #> 5 0 0 0 Inf 0 #> 6 0 0 0 Inf 0 #> 7 0 0 0 Inf 0 #> 8 0 0 0 Inf 0 #> 9 0 0 0 Inf 0 #> 10 0 0 0 Inf 0 #> 11 0 0 0 Inf 0 #> 12 0 0 0 Inf 0 #> 13 0 0 0 Inf 0 #> 14 0 0 0 Inf 0 #> 15 0 0 0 Inf 0 #> 16 0 0 0 Inf 0 p1 <- mbal_results %>% ggplot(aes(`P (psia)`, `RF_gas`, color = "Forecast")) + geom_point(size = 3) + scale_color_manual(name="Data", values=c("Forecast" = "red")) + ggtitle("Gas Recovery Plot") + theme_bw() p1
References
Fetkovich, M. J., Reese, D. E., & Whitson, C. H. (1998). Application of a General Material Balance for High-Pressure Gas Reservoirs (includes associated paper 51360). SPE Journal, 3(01), 3–13. https://doi.org/10.2118/22921-PA
Ikoku, Chi, U. (1984). Natural Gas Reservoir Engineering (p. 503). John Wiley & Sons, Ltd.
Pletcher, J. L. (2002). Improvements to Reservoir Material-Balance Methods. SPE Reservoir Evaluation & Engineering, 5(01), 49–59. https://doi.org/10.2118/75354-PA
Walsh, M. P., & Lake, L. W. (2003). A Generalized Approach to Primary Hydrocarbon Recovery (1st ed., p. 652; M. P. Walsh & L. W. Lake, Eds.). Retrieved from https://www.elsevier.com/books/a-generalized-approach-to-primary-hydrocarbon-recovery-of-petroleum-exploration-and-production/walsh/978-0-444-50683-2