Calculate VLP using Hagedorn-Brown (no heat transfer)

library(rNodal)
library(tibble)

# Example from C.13 in Brown
# P2 (pressure at end point is given). 
# The question is: what is the length of the tubing.
# P2 = 1000 psia

input.example.C13 <- setWellInput(field.name = "HAGBR.MOD",
                                    well.name = "Brown_C13", 
                                    depth.wh = 0, depth.bh = 2670, diam.in = 1.995, 
                                    GLR = 500, liq.rt = 1000, wcut = 0.6, 
                                    thp = 500, tht = 120, bht = 150, 
                                    API = 22, gas.sg = 0.65, wat.sg = 1.07, if.tens = 30)


well.model <- setVLPmodel(vlp.model = "hagbr.mod", segments = 11, tol = 0.000001)

as.tibble(runVLP(well.input = input.example.C13, well.model))
# A tibble: 12 x 45
       i     depth       dL     temp      pres     p_avg    t_avg segment
   <int>     <dbl>    <dbl>    <dbl>     <dbl>     <dbl>    <dbl>   <dbl>
 1     1    0.0000   0.0000 120.0000  500.0000  500.0000 120.0000       0
 2     2  242.7273 242.7273 122.7273  547.8516  523.9258 121.3636       1
 3     3  485.4545 242.7273 125.4545  595.9096  571.8806 124.0909       2
 4     4  728.1818 242.7273 128.1818  644.2142  620.0619 126.8182       3
 5     5  970.9091 242.7273 130.9091  692.8010  668.5076 129.5455       4
 6     6 1213.6364 242.7273 133.6364  741.7021  717.2516 132.2727       5
 7     7 1456.3636 242.7273 136.3636  790.9463  766.3242 135.0000       6
 8     8 1699.0909 242.7273 139.0909  840.5592  815.7527 137.7273       7
 9     9 1941.8182 242.7273 141.8182  890.5634  865.5613 140.4545       8
10    10 2184.5455 242.7273 144.5455  940.9788  915.7711 143.1818       9
11    11 2427.2727 242.7273 147.2727  991.8226  966.4007 145.9091      10
12    12 2670.0000 242.7273 150.0000 1043.1094 1017.4660 148.6364      11
# ... with 37 more variables: GOR <dbl>, Rs <dbl>, gas.fvf <dbl>,
#   gas.free <dbl>, liq.dens <dbl>, z <dbl>, gas.dens <dbl>,
#   oil.visc <dbl>, wat.visc <dbl>, mixL.visc <dbl>, oil.fvf <dbl>,
#   wat.fvf <dbl>, liq.svel <dbl>, gas.svel <dbl>, NL <dbl>, CNL <dbl>,
#   NLV <dbl>, NGV <dbl>, A <dbl>, B <dbl>, BA <dbl>, ND <dbl>, X2 <dbl>,
#   HL.psi <dbl>, X2.mod <dbl>, psi <dbl>, HL <dbl>, Re.TP <dbl>,
#   ff <dbl>, mix.dens <dbl>, mixL.volume <dbl>, mixL.dens <dbl>,
#   mixTP.dens <dbl>, mixTP.svel <dbl>, elev.grad <dbl>, fric.grad <dbl>,
#   dp.dz <dbl>

+ Heat transfer calculations. Angle constant

It will grab only few variables from the VLP final table above.

 c("depth", "dL", "pres", "temp")
# calculate the fluid temperature in the well
# input: deviation survey and well calculated parameters: uses new functions: 
#        get_well_parameters
#        rNodal:::temp.gradient

library(rNodal)

# get only the variable we need for heat transfer. But what we really want 
# is the deviation survey: MD, TVD
well_table <- runVLP(well.input = input.example.C13, 
                     well.model)[, c("depth", "dL", "pres", "temp")]    

input.example.C13 <- setWellInput(field.name = "HAGBR.MOD",
                                    well.name = "Brown_C13", 
                                    depth.wh = 0, depth.bh = 2670, diam.in = 1.995, 
                                    GLR = 500, liq.rt = 1000, wcut = 0.6, 
                                    thp = 500, tht = 120, bht = 150, 
                                    API = 22, gas.sg = 0.65, wat.sg = 1.07,
                                  U = 17)

well_parameters <- get_well_parameters(input.example.C13)

# temp.gradient calculates the fluid temperature coming from the wellbore
rNodal:::temp.gradient(well_table, well_parameters)         
        depth       dL      pres     temp         L       Ti
 1:    0.0000   0.0000  500.0000 120.0000 2670.0000 135.8614
 2:  242.7273 242.7273  547.8516 122.7273 2427.2727 138.8760
 3:  485.4545 242.7273  595.9096 125.4545 2184.5455 141.5070
 4:  728.1818 242.7273  644.2142 128.1818 1941.8182 143.7471
 5:  970.9091 242.7273  692.8010 130.9091 1699.0909 145.5987
 6: 1213.6364 242.7273  741.7021 133.6364 1456.3636 147.0745
 7: 1456.3636 242.7273  790.9463 136.3636 1213.6364 148.1974
 8: 1699.0909 242.7273  840.5592 139.0909  970.9091 149.0007
 9: 1941.8182 242.7273  890.5634 141.8182  728.1818 149.5276
10: 2184.5455 242.7273  940.9788 144.5455  485.4545 149.8296
11: 2427.2727 242.7273  991.8226 147.2727  242.7273 149.9657
12: 2670.0000 242.7273 1043.1094 150.0000    0.0000 150.0000

Same as above but calculating fluid temperature. Angle constant

Added new input parameters:

.  U = double 1= 8
.  oil.cp = double 1= 0.53
.  gas.cp = double 1= 0.5
.  wat.cp = double 1= 1

Added new calculated objects:

.  mass.rt = double 1= 378585
.  mass.rate = double 1= 378585
.  cp.avg = double 1= 0.67667
# this tests if new function get_well_parameters() returns all what's needed for heat transfer
library(rNodal)

well_table <- runVLP(well.input = input.example.C13, 
                     well.model)[, c("depth", "dL", "pres", "temp")]   

input.example.C13 <- setWellInput(field.name = "HAGBR.MOD",
                                    well.name = "Brown_C13", 
                                    depth.wh = 0, depth.bh = 2670, diam.in = 1.995, 
                                    GLR = 500, liq.rt = 1000, wcut = 0.6, 
                                    thp = 500, tht = 120, bht = 150, 
                                    API = 22, gas.sg = 0.65, wat.sg = 1.07,
                                  U = 17)
# input.example.C13
# getBasicCalcs(input.example.C13)
well_params <- get_well_parameters(input.example.C13)
Hmisc::list.tree(well_params, maxcomp = 40)
 well_params = list 39 (4760 bytes)
.  field.name = character 1= HAGBR.MOD 
.  well.name = character 1= Brown_C13 
.  depth.wh = double 1= 0
.  tht = double 1= 120
.  depth.bh = double 1= 2670
.  bht = double 1= 150
.  diam.in = double 1= 1.995
.  ed = double 1= 6e-04
.  thp = double 1= 500
.  liq.rt = double 1= 1000
.  wcut = double 1= 0.6
.  API = double 1= 22
.  oil.visc = double 1= 5
.  gas.sg = double 1= 0.65
.  GLR = double 1= 500
.  wat.sg = double 1= 1.07
.  salinity = double 1= 0
.  if.tens = double 1= 30
.  U = double 1= 17
.  oil.cp = double 1= 0.53
.  gas.cp = double 1= 0.5
.  wat.cp = double 1= 1
.  angle = double 1= 1.5708
.  temp.grad = double 1= 0.011236
.  diam = double 1= 0.16625
.  area = double 1= 0.021708
.  diam.ft = double 1= 0.16625
.  oil.sg = double 1= 0.92182
.  oil.fraction = double 1= 0.4
.  wat.fraction = double 1= 0.6
.  WOR = double 1= 1.5
.  oil.rt = double 1= 400
.  gas.rt = double 1= 5e+05
.  wat.rt = double 1= 600
.  mass.total = double 1= 378.59
.  GOR = double 1= 1250
.  mass.rt = double 1= 378585
.  mass.rate = double 1= 378585
.  cp.avg = double 1= 0.67667
# temp.gradient calculates the fluid temperature coming from the wellbore
rNodal:::temp.gradient(well_table, well_parameters)    
        depth       dL      pres     temp         L       Ti
 1:    0.0000   0.0000  500.0000 120.0000 2670.0000 135.8614
 2:  242.7273 242.7273  547.8516 122.7273 2427.2727 138.8760
 3:  485.4545 242.7273  595.9096 125.4545 2184.5455 141.5070
 4:  728.1818 242.7273  644.2142 128.1818 1941.8182 143.7471
 5:  970.9091 242.7273  692.8010 130.9091 1699.0909 145.5987
 6: 1213.6364 242.7273  741.7021 133.6364 1456.3636 147.0745
 7: 1456.3636 242.7273  790.9463 136.3636 1213.6364 148.1974
 8: 1699.0909 242.7273  840.5592 139.0909  970.9091 149.0007
 9: 1941.8182 242.7273  890.5634 141.8182  728.1818 149.5276
10: 2184.5455 242.7273  940.9788 144.5455  485.4545 149.8296
11: 2427.2727 242.7273  991.8226 147.2727  242.7273 149.9657
12: 2670.0000 242.7273 1043.1094 150.0000    0.0000 150.0000

old version using spelled-out parameters

# this in an old version where all well parameters had to be spelled out
# parameters necessary to calculate the fluid temperature
well_table <- runVLP(well.input = input.example.C13, 
                     well.model)[, c("depth", "dL", "pres", "temp")] 

theta   <-  pi /2
diam.in <- 1.995
diam.ft <- diam.in / 12
tht     <- 120
bht     <- 150
depth   <- 2670
ge      <- (bht - tht) / depth
mass.rate <- 228145
U <-  17
# U <- 4
cp.avg <- (0.53 + 0.5 + 1 ) / 3

# calculate dT/dx for the well
rNodal:::temp.fluid(well_table, theta, depth, bht, tht, U, cp.avg, diam.ft, mass.rate)
        depth       dL      pres     temp         L       Ti
 1:    0.0000   0.0000  500.0000 120.0000 2670.0000 129.3220
 2:  242.7273 242.7273  547.8516 122.7273 2427.2727 133.4227
 3:  485.4545 242.7273  595.9096 125.4545 2184.5455 137.1156
 4:  728.1818 242.7273  644.2142 128.1818 1941.8182 140.3541
 5:  970.9091 242.7273  692.8010 130.9091 1699.0909 143.1053
 6: 1213.6364 242.7273  741.7021 133.6364 1456.3636 145.3532
 7: 1456.3636 242.7273  790.9463 136.3636 1213.6364 147.1017
 8: 1699.0909 242.7273  840.5592 139.0909  970.9091 148.3767
 9: 1941.8182 242.7273  890.5634 141.8182  728.1818 149.2261
10: 2184.5455 242.7273  940.9788 144.5455  485.4545 149.7192
11: 2427.2727 242.7273  991.8226 147.2727  242.7273 149.9432
12: 2670.0000 242.7273 1043.1094 150.0000    0.0000 150.0000
# we don't want all parameters spelled out      ^   ^      ^     ^      ^      ^     

APPENDIX

previous data (unit testing)

p30 = 1043.8745
p30 = 1043.8793
p30 = 1045.1834
p30 = 1043.1091 (after using p.avg and t.avg)
p30 = 1043.1094 (after using p.avg, t.avg, p0 = p.calc)

where the HDF5 file is

link to hdf5 file

hdf5 in inst/extdata

h5

results for unit testing

    MD      TVD     Pres    Temp
    0       0       500.0   135.8
    242.7   242.7   563.1   137.9
    485.5   485.5   627.5   139.8
    728.2   728.2   693.1   141.6
    970.9   970.9   759.8   143.4
    1213.6  1213.6  827.6   144.9
    1456.4  1456.4  896.5   146.3
    1699.1  1699.1  966.4   147.6
    1941.8  1941.8  1037.3  148.6
    2184.5  2184.5  1109.3  149.3
    2427.3  2427.3  1182.2  149.8
    2670.0  2670.0  1255.9  150.0
    
    
    
    
library(rNodal)

well_as_text <- "
MD      TVD    
0       0   
242.7   242.7
485.5   485.5
728.2   728.2
970.9   970.9
1213.6  1213.6
1456.4  1456.4
1699.1  1699.1
1941.8  1941.8
2184.5  2184.5
2427.3  2427.3
2670.0  2670.0
"

deviation_survey <- set_deviation_survey(well_as_text)
rNodal:::calc_angle_deviation_survey(deviation_survey)
Error in get(name, envir = asNamespace(pkg), inherits = FALSE): object 'calc_angle_deviation_survey' not found