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)
library(magrittr)
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
p2 <- mbal_results %>%
tidyr::pivot_longer(cols = c("Igd", "Ifwd"), names_to = "Drive Mechanism",
values_to = "Fraction", values_drop_na = TRUE) %>%
ggplot(aes(`P (psia)`, Fraction, fill = `Drive Mechanism`)) +
geom_area() +
ggtitle("Energy Plot") +
theme_bw()
p2
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
p2 <- forecast_results %>%
tidyr::pivot_longer(cols = c("Igd", "Ifwd"), names_to = "Drive Mechanism",
values_to = "Fraction", values_drop_na = TRUE) %>%
ggplot(aes(`P (psia)`, Fraction, fill = `Drive Mechanism`)) +
geom_area() +
ggtitle("Energy Plot") +
theme_bw()
p2
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
p2 <- mbal_results %>%
tidyr::pivot_longer(cols = c("Inwd", "Igd", "Ifwd"), names_to = "Drive Mechanism",
values_to = "Fraction", values_drop_na = TRUE) %>%
ggplot(aes(`P (psia)`, Fraction, fill = `Drive Mechanism`)) +
geom_area() +
ggtitle("Energy Plot") +
theme_bw()
p2
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
p2 <- forecast_results %>%
tidyr::pivot_longer(cols = c("Igd", "Ifwd"), names_to = "Drive Mechanism",
values_to = "Fraction", values_drop_na = TRUE) %>%
ggplot(aes(`P (psia)`, Fraction, fill = `Drive Mechanism`)) +
geom_area() +
ggtitle("Energy Plot") +
theme_bw()
p2
References
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