knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
Rdca
Rdca
is a Decline Curve Analysis (DCA) package for oil and gas reservoirs. It generates a table of rate, cumulative, nominal decline rate, and derivative of loss-ratio over time in a data frame format. It also provides an optimization tool to fit a DCA model on production data. The package currently supports Arps 'exponential', 'harmonic', 'hyperbolic', and 'modified_hyperbolic' models [@Arps1945; @Robertson1988].
DCA predictions are generated using three different functions: decline_param()
, decline_time()
, and decline_predict()
. There are two more functions for the curve fitting exercises: decline_fit_param()
, and decline_fit()
.
decline_param() arguments
input_unit
: A unit system for input parameters, either 'Field' or 'SI'.output_unit
: A unit system for output predictions, either 'Field' or 'SI'.fluid
: Type of fluid, either 'gas' or 'oil'.model
: Arps DCA model.qi
: Arps model parameter, initial rate.Di
: Arps model parameter, nominal decline rate.b
: Arps model parameter, decline constant.Dt
: Arps modified_hyperbolic model parameter, terminal nominal decline rate.q_abnd
: Abandonment rate, an optional input parameter. If assigned a value, the model predicts time to reach to the abandonment rate, and also the estimated ultimate recovery (EUR).decline_time() arguments
x
: A vector or sequence of times/dates.unit
: A unit system for input vector x.decline_predict() arguments
decline_lst
: A list of decline parameters of class 'decline'.time_lst
: A list of decline time of class 'time/date'.decline_fit_param() arguments
input_unit
: A unit system for input parameters, either 'Field' or 'SI'.output_unit
: A unit system for output predictions, either 'Field' or 'SI'.fluid
: Type of fluid, either 'gas' or 'oil'.model
: Arps DCA model.fit_data
: Fitting data, either 'rate' or 'cum'.prod_data
: A numeric vector of fitting data.initial_param
: A vector of initial estimates for the Arps DCA model parameters.lower
: A vector of lower bounds for the Arps DCA model parameters, optional. See package minpack.lm
for more information. upper
: A vector of upper bounds for the Arps DCA model parameters, optional. See package minpack.lm
for more information. control
: An optional list of control settings in the optimization toolbox. See package minpack.lm
for more information. decline_fit() arguments
decline_fit_lst
: A list of decline fit parameters of class 'decline_fit'.time_lst
: A list of decline time of class 'time/date'.Units
for input parametersThe input_unit is either 'SI' or 'Field'. Depending on the input_unit system, the following units are used for the input parameters:
qi
: Arp's decline parameter, a numeric value. Depending on the 'input_unit', 'fluid' type, and also the decline_time() 'unit' parameter, it has different units. 'm3/day' for gas production in 'SI' unit with daily data, 'm3/month' for gas production in 'SI' unit with monthly data, 'MSCF/day' for gas production in 'Field' unit with daily data, 'MSCF/month' for gas production in 'Field' unit with monthly data, 'm3/day' for oil production in 'SI' unit with daily data, 'm3/month' for oil production in 'SI' unit with monthly data, 'bbl/day' for oil production in 'Field' unit with daily data, and 'bbl/month' for oil production in 'Field' unit with monthly data.Di
: Arp's nominal decline parameter, a numeric value in '1/day', '1/month', or '1/year' depending on the decline_time() 'unit' parameter.b
: Arp's decline parameter. It is zero for the 'exponential' model, one for the 'harmonic' model, and a value between zero and one for the 'hyperbolic' model. For unconventional reservoirs, b values more than one are also reported.Dt
: Arp's 'modified_hyperbolic' nominal terminal decline parameter, a numeric value in '1/day', '1/month', or '1/year' depending on the decline_time() 'unit' input.q_abnd
: Abandonment rate, a numeric value defaulted to NULL. If present, the model predicts the time to reach to the abandonment rate and also the estimated ultimate recovery (EUR) till the abandonment time. It has the same unit as 'qi'.unit
: time/date unit for the x vector. For a vector of time values, the unit is 'day', 'month', or 'year'. For a sequence of dates, the unit is 'date'. Daily parameters must be used with the 'date' unit in the DCA.Date
: DateTime
: Timeq
: Production rateQ
: Cumulative productionD
: Nominal decline rate (1/loss-ratio)Beta
: Loss-ratio derivative wrt timetime_abnd
: Time to reach to the abandonment rate (if 'abnd_rate' is provided)EUR
: Estimated ultimate recovery at abandonment rate (if 'abnd_rate' is provided)Di
Arps Di
parameter is the nominal decline rate in '1/day', '1/month', or '1/year'. It represents the rate of decline at a specific time. However, the rate of decline is often expressed for a particular period (usually one year) and is called the effective decline rate (di)
in '1/year'. The relationship between Di
and di
for Arps models are as follows:
$$D_{i} = \frac{-log(1 - d_{i})}{365}\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\: \frac{1}{day}$$
$$D_{i} = \frac{-log(1 - d_{i})}{12}\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\: \frac{1}{month}$$
$$D_{i} = -log(1 - d_{i}) \:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\: \frac{1}{year}$$
$$D_{i} = \frac{d_{i}}{(1 - d_{i}) . 365}\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\: \frac{1}{day}$$
$$D_{i} = \frac{d_{i}}{(1 - d_{i}) . 12}\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\: \frac{1}{month}$$
$$D_{i} = \frac{d_{i}}{(1 - d_{i})}\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\: \frac{1}{year}$$
$$D_{i} = \frac{1}{b}.\frac{[(1 - d_{i})^{-b} - 1]}{365}\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\: \frac{1}{day}$$
$$D_{i} = \frac{1}{b}.\frac{[(1 - d_{i})^{-b} - 1]}{12}\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\: \frac{1}{month}$$
$$D_{i} = \frac{1}{b}.[(1 - d_{i})^{-b} - 1]\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\: \frac{1}{year}$$
Installation
The Rdca
can be installed from CRAN with:
install.packages("Rdca")
Arps Exponential Examples
library(Rdca) library(magrittr) library(ggplot2) library(ggpubr) dcl_param_exp <- decline_param(input_unit = "Field", output_unit = "Field", fluid = "oil", model = "exponential", qi = 1000, Di = 0.0015, b = 0, q_abnd = NULL) dcl_param_exp decline_time_exp <- decline_time(c(1:7300), unit = "day") str(decline_time_exp) decline_predict_exp <- decline_predict(dcl_param_exp, decline_time_exp) head(decline_predict_exp, 10) p1 <- decline_predict_exp %>% ggplot(aes(x = `Time_(day)`, y = `q_(bbl/day)`)) + geom_point(color = "green4") + theme_bw() p2 <- decline_predict_exp %>% ggplot(aes(x = `Time_(day)`, y = `Q_(bbl)`)) + geom_point(color = "green4") + theme_bw() exp_plots <- ggarrange(p1, p2, ncol = 1, nrow = 2, align = "v") exp_plots
library(Rdca) library(ggplot2) library(ggpubr) dcl_param_exp <- decline_param(input_unit = "Field", output_unit = "SI", fluid = "gas", model = "exponential", qi = 75000, Di = 0.03, b = 0, q_abnd = 1000) dcl_param_exp decline_time_exp <- decline_time(c(1:360), unit = "month") str(decline_time_exp) decline_predict_exp <- decline_predict(dcl_param_exp, decline_time_exp) head(decline_predict_exp, 10) time_abnd <- decline_predict_exp$`time_abnd_(months)`[1] EUR <- decline_predict_exp$`EUR_(m3)`[1] p1 <- decline_predict_exp %>% ggplot(aes(x = `Time_(month)`, y = `q_(m3/month)`)) + geom_point(color = "red") + geom_vline(aes(xintercept = `time_abnd_(months)`), linetype = 2) + annotate(geom = "text", x = time_abnd + 10, y = 5e5, label = "time_abnd", angle = 90, color = "blue") + geom_hline(aes(yintercept = 1e6 / 35.3147), linetype = 2) + annotate(geom = "text", x = 50, y = 3e6 / 35.3147, label = "rate_abnd", color = "blue") + theme_bw() p2 <- decline_predict_exp %>% ggplot(aes(x = `Time_(month)`, y = `Q_(m3)`)) + geom_point(color = "red") + geom_vline(aes(xintercept = `time_abnd_(months)`), linetype = 2) + annotate(geom = "text", x = time_abnd + 10, y = 6e7, label = "time_abnd", angle = 90, color = "blue") + geom_hline(aes(yintercept = `EUR_(m3)`), linetype = 2) + annotate(geom = "text", x = 50, y = 1.02 * EUR, label = "EUR", color = "blue") + theme_bw() exp_plots <- ggarrange(p1, p2, ncol = 1, nrow = 2, align = "v") exp_plots
library(Rdca) library(ggplot2) dcl_time_exp <- decline_time(1:1000, unit = "day") set.seed(123) prod_data <- 3000 * exp(-0.00234 * dcl_time_exp$t) + 50 * rnorm(1000) field_data <- data.frame(time = dcl_time_exp$t, q = prod_data) dcl_fit_param_exp <- decline_fit_param(input_unit = "Field", output_unit = "Field", fluid = "oil", model = "exponential", fit_data = "rate", prod_data = prod_data, initial_param = c(3000, 0.001, 0), lower = NULL, upper = NULL) tibble::glimpse(dcl_fit_param_exp) dcl_fit_exp <- decline_fit(dcl_fit_param_exp, dcl_time_exp) tibble::glimpse(dcl_fit_exp) names(attr(dcl_fit_exp, which = "nls.out")) attr(dcl_fit_exp, which = "nls.out")$par attr(dcl_fit_exp, which = "nls.out")$info attr(dcl_fit_exp, which = "nls.out")$niter attr(dcl_fit_exp, which = "nls.out")$deviance dcl_predict_exp <- decline_predict(dcl_fit_exp, dcl_time_exp) field_data %>% ggplot(aes(x = time, y = q)) + geom_point(color = "blue", shape = 21, size = 3) + geom_line(aes(x = `Time_(day)`, y = `q_(bbl/day)`), data = dcl_predict_exp, color = "red", size = 1) + labs(x = "Time (days)", y = "Rate (bbl/day)") + theme_bw()
Arps Harmonic Examples
library(Rdca) library(ggplot2) library(ggpubr) dcl_param_harm <- decline_param(input_unit = "SI", output_unit = "SI", fluid = "oil", model = "harmonic", qi = 1000, Di = 0.075, b = 1, q_abnd = 50) dcl_param_harm decline_time_harm <- decline_time(c(1:360), unit = "month") str(decline_time_harm) decline_predict_harm <- decline_predict(dcl_param_harm, decline_time_harm) head(decline_predict_harm, 10) time_abnd <- decline_predict_harm$`time_abnd_(months)`[1] EUR <- decline_predict_harm$`EUR_(m3)`[1] p1 <- decline_predict_harm %>% ggplot(aes(x = `Time_(month)`, y = `q_(m3/month)`)) + geom_point(color = "green4") + geom_vline(aes(xintercept = `time_abnd_(months)`), linetype = 2) + annotate(geom = "text", x = time_abnd + 10, y = 250, label = "time_abnd", angle = 90, color = "blue") + geom_hline(aes(yintercept = 50), linetype = 2) + annotate(geom = "text", x = 50, y = 80, label = "rate_abnd", color = "blue") + theme_bw() p2 <- decline_predict_harm %>% ggplot(aes(x = `Time_(month)`, y = `Q_(m3)`)) + geom_point(color = "green4") + geom_vline(aes(xintercept = `time_abnd_(months)`), linetype = 2) + annotate(geom = "text", x = time_abnd + 10, y = 35000, label = "time_abnd", angle = 90, color = "blue") + geom_hline(aes(yintercept = `EUR_(m3)`), linetype = 2) + annotate(geom = "text", x = 50, y = 1.04 * EUR, label = "EUR", color = "blue") + theme_bw() harm_plots <- ggarrange(p1, p2, ncol = 1, nrow = 2, align = "v") harm_plots
library(Rdca) library(ggplot2) dcl_time_harm <- decline_time(1:360, unit = "month") set.seed(1234) prod_data <- 30000 / (1 + 0.02 * dcl_time_harm$t) + 500 * rnorm(360) # rate field_data <- data.frame(time = dcl_time_harm$t, q = prod_data) field_data$Q <- cumsum(field_data$q) # cumulative dcl_fit_param_harm <- decline_fit_param(input_unit = "SI", output_unit = "SI", fluid = "gas", model = "harmonic", fit_data = "cum", prod_data = field_data$Q, initial_param = c(40000, 0.01, 1), lower = NULL, upper = NULL, control = list(maxiter = 100)) tibble::glimpse(dcl_fit_param_harm) dcl_fit_harm <- decline_fit(dcl_fit_param_harm, dcl_time_harm) tibble::glimpse(dcl_fit_harm) names(attr(dcl_fit_harm, which = "nls.out")) attr(dcl_fit_harm, which = "nls.out")$par attr(dcl_fit_harm, which = "nls.out")$info attr(dcl_fit_harm, which = "nls.out")$niter attr(dcl_fit_harm, which = "nls.out")$deviance dcl_predict_harm <- decline_predict(dcl_fit_harm, dcl_time_harm) p_cum <- field_data %>% ggplot(aes(x = time, y = Q)) + geom_point(color = "blue", shape = 21, size = 3) + geom_line(aes(x = `Time_(month)`, y = `Q_(m3)`), data = dcl_predict_harm, color = "red", size = 1) + labs(x = "Time (months)", y = "Cumulative Production (m3)") + theme_bw() p_cum p_rate <- field_data %>% ggplot(aes(x = time, y = q)) + geom_point(color = "blue", shape = 21, size = 3) + geom_line(aes(x = `Time_(month)`, y = `q_(m3/month)`), data = dcl_predict_harm, color = "red", size = 1) + labs(x = "Time (months)", y = "Production Rate (m3/month)") + theme_bw() p_rate
Arps Hyperbolic Examples
library(Rdca) library(ggplot2) library(ggpubr) dcl_param_hyp <- decline_param(input_unit = "Field", output_unit = "Field", fluid = "gas", model = "hyperbolic", qi = 100000, Di = 0.0055, b = 0.85, q_abnd = 2000) dcl_param_hyp decline_time_hyp <- decline_time(seq(as.Date("2000/1/1"), as.Date("2030/12/31"), "days"), unit = "date") str(decline_time_hyp) decline_predict_hyp <- decline_predict(dcl_param_hyp, decline_time_hyp) head(decline_predict_hyp, 10) time_abnd <- decline_predict_hyp$`time_abnd_(days)`[1] EUR <- decline_predict_hyp$`EUR_(MMSCF)`[1] p1 <- decline_predict_hyp %>% ggplot(aes(x = `Time_(day)`, y = `q_(MSCF/day)`)) + geom_point(color = "red") + geom_vline(aes(xintercept = `time_abnd_(days)`), linetype = 2) + annotate(geom = "text", x = time_abnd + 200, y = 25000, label = "time_abnd", angle = 90, color = "blue") + geom_hline(aes(yintercept = 2000), linetype = 2) + annotate(geom = "text", x = 7500, y = 5000, label = "rate_abnd", color = "blue") + theme_bw() p2 <- decline_predict_hyp %>% ggplot(aes(x = `Time_(day)`, y = `Q_(MMSCF)`)) + geom_point(color = "red") + geom_vline(aes(xintercept = `time_abnd_(days)`), linetype = 2) + annotate(geom = "text", x = time_abnd + 200, y = 4e4, label = "time_abnd", angle = 90, color = "blue") + geom_hline(aes(yintercept = `EUR_(MMSCF)`), linetype = 2) + annotate(geom = "text", x = 8000, y = 1.03 * EUR, label = "EUR", color = "blue") + theme_bw() hyp_plots <- ggarrange(p1, p2, ncol = 1, nrow = 2, align = "v") hyp_plots
library(Rdca) library(ggplot2) dcl_time_hyp <- decline_time(1:10000, unit = "day") set.seed(321) prod_data <- 4500 / (1 + 0.002 * 0.834 * dcl_time_hyp$t) ^ (1 / 0.834) + 25 * rnorm(10000) # rate field_data <- data.frame(time = dcl_time_hyp$t, q = prod_data) dcl_fit_param_hyp <- decline_fit_param(input_unit = "Field", output_unit = "Field", fluid = "gas", model = "hyperbolic", fit_data = "rate", prod_data = prod_data, initial_param = c(1000, 0.01, 1.0), lower = c(0, 1e-6, 1e-6), upper = NULL, control = list(maxiter = 100)) tibble::glimpse(dcl_fit_param_hyp) dcl_fit_hyp <- decline_fit(dcl_fit_param_hyp, dcl_time_hyp) tibble::glimpse(dcl_fit_hyp) names(attr(dcl_fit_hyp, which = "nls.out")) attr(dcl_fit_hyp, which = "nls.out")$par attr(dcl_fit_hyp, which = "nls.out")$info attr(dcl_fit_hyp, which = "nls.out")$niter attr(dcl_fit_hyp, which = "nls.out")$deviance dcl_predict_hyp <- decline_predict(dcl_fit_hyp, dcl_time_hyp) field_data %>% ggplot(aes(x = time, y = q)) + geom_point(color = "blue", shape = 21, size = 3) + geom_line(aes(x = `Time_(day)`, y = `q_(MSCF/day)`), data = dcl_predict_hyp, color = "red", size = 1) + labs(x = "Time (days)", y = "Rate (MSCF/day)") + theme_bw()
Arps Modified_Hyperbolic Examples
library(Rdca) library(ggplot2) library(ggpubr) dcl_param_mod_hyp <- decline_param(input_unit = "SI", output_unit = "Field", fluid = "oil", model = "modified_hyperbolic", qi = 1000, Di = 0.0055, b = 0.85, Dt = 0.0005, q_abnd = 5) dcl_param_mod_hyp decline_time_mod_hyp <- decline_time(seq(as.Date("2000/1/1"), as.Date("2030/12/31"), "days"), unit = "date") str(decline_time_mod_hyp) decline_predict_mod_hyp <- decline_predict(dcl_param_mod_hyp, decline_time_mod_hyp) head(decline_predict_mod_hyp, 10) time_abnd <- decline_predict_mod_hyp$`time_abnd_(days)`[1] EUR <- decline_predict_mod_hyp$`EUR_(bbl)`[1] p1 <- decline_predict_mod_hyp %>% ggplot(aes(x = `Time_(day)`, y = `q_(bbl/day)`)) + geom_point(color = "red") + geom_vline(aes(xintercept = `time_abnd_(days)`), linetype = 2) + annotate(geom = "text", x = time_abnd + 200, y = 1000, label = "time_abnd", angle = 90, color = "blue") + geom_hline(aes(yintercept = 5 * 6.289814), linetype = 2) + annotate(geom = "text", x = 8000, y = 200, label = "rate_abnd", color = "blue") + theme_bw() p2 <- decline_predict_mod_hyp %>% ggplot(aes(x = `Time_(day)`, y = `Q_(bbl)`)) + geom_point(color = "red") + geom_vline(aes(xintercept = `time_abnd_(days)`), linetype = 2) + annotate(geom = "text", x = time_abnd + 200, y = 3e6, label = "time_abnd", angle = 90, color = "blue") + geom_hline(aes(yintercept = `EUR_(bbl)`), linetype = 2) + annotate(geom = "text", x = 8000, y = 1.03 * EUR, label = "EUR", color = "blue") + theme_bw() hyp_plots <- ggarrange(p1, p2, ncol = 1, nrow = 2, align = "v") hyp_plots
library(Rdca) library(ggplot2) library(magrittr) dcl_time_mod_hyp <- decline_time(1:300, unit = "month") dcl_param_mod_hyp <- decline_param(input_unit = "Field", output_unit = "Field", fluid = "oil", model = "modified_hyperbolic", qi = 8000, Di = 0.04, b = 0.75, Dt = 0.01, q_abnd = 10) set.seed(4321) prod_data <- decline_predict(dcl_param_mod_hyp, dcl_time_mod_hyp)$`q_(bbl/month)` + rnorm(300, mean = 100, sd = 50) # rate field_data <- data.frame(time = dcl_time_mod_hyp$t, q = prod_data, Q = cumsum(prod_data)) dcl_fit_param_mod_hyp <- decline_fit_param(input_unit = "Field", output_unit = "Field", fluid = "oil", model = "modified_hyperbolic", fit_data = "cum", prod_data = field_data$Q, initial_param = c(10000, 0.1, 1.0, 0.01), lower = NULL, upper = NULL, control = list(maxiter = 100)) tibble::glimpse(dcl_fit_param_mod_hyp) dcl_fit_mod_hyp <- decline_fit(dcl_fit_param_mod_hyp, dcl_time_mod_hyp) tibble::glimpse(dcl_fit_mod_hyp) names(attr(dcl_fit_mod_hyp, which = "nls.out")) attr(dcl_fit_mod_hyp, which = "nls.out")$par attr(dcl_fit_mod_hyp, which = "nls.out")$info attr(dcl_fit_mod_hyp, which = "nls.out")$niter attr(dcl_fit_mod_hyp, which = "nls.out")$deviance dcl_predict_mod_hyp <- decline_predict(dcl_fit_mod_hyp, dcl_time_mod_hyp) p_cum <- field_data %>% ggplot(aes(x = time, y = Q)) + geom_point(color = "blue", shape = 21, size = 3) + geom_line(aes(x = `Time_(month)`, y = `Q_(bbl)`), data = dcl_predict_mod_hyp, color = "red", size = 1) + labs(x = "Time (months)", y = "Cumulative Production (bbl)") + theme_bw() p_cum p_rate <- field_data %>% ggplot(aes(x = time, y = q)) + geom_point(color = "blue", shape = 21, size = 3) + geom_line(aes(x = `Time_(month)`, y = `q_(bbl/month)`), data = dcl_predict_mod_hyp, color = "red", size = 1) + labs(x = "Time (months)", y = "Production Rate (bbl/month)") + theme_bw() p_rate
References
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.