You are on page 1of 9

700

750
800
850
900
950
1000
1050
1100
1150
10/18/2012 12/7/2012 1/26/2013 3/17/2013 5/6/2013 6/25/2013 8/14/2013 10/3/2013 11/22/2013 1/11/2014
T
e
m
p
e
r
a
t
u
r
e

(
F
)
390
400
410
420
430
440
450
460
470
480
490
500
510
520
530
540
550
P
r
e
s
s
u
r
e

(
p
s
i
g
)
Coil Inlet Pressure
Process Outlet Temperature
Tube Metal Temperature
Accelerated
Creep Range
Convection Section
Tubes 1 18
Roof Section
Tubes 19 30
Radiant Section
Tubes 31 50
P = 476 psig
Inlet Pressure
P = 105 psig
Outlet Pressure
TI
TI
TI
TI
TI
TI
Smart Pig performed November 2012
0% Creep (Diametrical Growth)
Baseline thickness readings
Tube Pressure
(Simulated)
Deterministic Remaining Life Analysis for Single Tube #31
Tube Metal Temperature
(Simulated)
Calculate future expected creep damage by simulating coking
runs based on historical pressure, temperature, and corrosion
rates.
Use methods of API 530 & API 579 to find cumulative Partial
Damage Fraction based on Larson-Miller parameter.
API 579 recommends tube retirement at PDF > 0.80
PDF is a function of temperature, pressure, and tube thickness
) , ( ) (
10
24 24
20
460
1000
1
thickness pressure f stress f LMP
Failure to Time
PDF PDF
n
n
T
LMP
n n
= =
= + =

Assumed Operating Conditions


psig 361
F 1121
psig 343
F 986
150
/ 58 . 9
o o
=
=
=
=
=
=
EOR
EOR
SOR
SOR
P
T
P
T
days Length Run
year in Rate Corrosion
What input values to use for model?
Answer: Monte Carlo Simulation
900
950
1000
1050
1100
1150
10/18/2012 12/7/2012 1/26/2013 3/17/2013 5/6/2013 6/25/2013
T
e
m
p
e
r
a
t
u
r
e

(
F
)
Tube Metal Temperatures & Run Length
C
o
n
v
e
c
t
i
o
n

S
e
c
t
i
o
n
T
u
b
e
s

1

1
8
TI
TI
TI
TI
TI
TI TI
TI
TI
TI
TI
TI
Coil 5 Coil 6
R
o
o
f

S
e
c
t
i
o
n
T
u
b
e
s

1
9

3
0
R
a
d
i
a
n
t

S
e
c
t
i
o
n
T
u
b
e
s

3
1

5
0
Radiant Tubes
Temperature profile based on TI readings
Roof Tubes
Temperature profile based on adjusted IR readings
Maximum recorded IR temperatures are scaled from the
measurement date to SOR and EOR using the Rankine
energy scale and TI measured values.
SOR Temperature
EOR Temperature
Pressure Profile & Corrosion Rates
C
o
n
v
e
c
t
i
o
n

S
e
c
t
i
o
n
T
u
b
e
s

1

1
8
TI
TI
TI
TI
TI
TI TI
TI
TI
TI
TI
TI
Coil 5 Coil 6
R
o
o
f

S
e
c
t
i
o
n
T
u
b
e
s

1
9

3
0
R
a
d
i
a
n
t

S
e
c
t
i
o
n
T
u
b
e
s

3
1

5
0
100
150
200
250
300
350
400
450
500
0 5 10 15 20 25 30 35 40 45 50
T
u
b
e

P
r
e
s
s
u
r
e

(
p
s
i
g
)
Pressure Profile P_SOR P_EOR
R
2
= 0.8666
0
1
2
3
4
5
6
7
8
9
10
0 5 10 15 20 25 30 35 40 45 50
C
o
r
r
o
s
i
o
n

R
a
t
e

(
i
n
/
y
e
a
r
)
Pressure Profile
Inlet Pressures Scaled to Fit Hydraulic Pressure Drop Model
Corrosion Rates
Calculated for Each Tube from Install Date
P = 476 psig
Inlet Pressure
P = 105 psig
Outlet Pressure
Roof Tubes
Installed 1991
Material Properties Larson Miller Parameter
API 530 provides Average and Minimum value curves for the Larson
Miller Parameter as a function of stress for 9Cr-1Mo metallurgy
Minimum LMP is considered unrealistically conservative by industry for
remaining life analysis
Average LMP is more realistic but it is possible to have material properties
below this value
For Monte Carlo analysis we can construct a random normal distribution
of LMP values in between the Average and Minimum curves
Curve fits for LMP
min
and LMP
ave
are given in API 579
Stress
LMP
API 530
Average
LMP Curve
API 530
Minimum
LMP Curve Introduce LMP Multiplier
( )
3
5 . 0
, 5 . 0 = = N
( ) ( )
4 4 4 3 4 4 4 2 1
3
5 . 0
min min
, 5 . 0 = = + = N LMP LMP LMP LMP
ave

=
9
min
9
10 1
ln 14465 . 3
10 2
ln 07692 . 3
stress
LMP
stress
LMP
ave
LMP Percent = Normal random variable
approximately between 0 and 1
Monte Carlo Simulation Setup
Utilized the R statistical computing language to write two functions
tube_life() generates one deterministic run of simulated creep damage for a
single tube based on the parameters passed to it until PDF > 0.80 and returns the
expected remaining life.
tube_life(run_length,tube_OD,tube_thickness,corrosion_rate,P_SOR,P_EOR,T_
SOR,T_EOR,LMP_percent,partial_damage_fraction) { return(remaining_life)}
tube_mc() runs the Monte Carlo simulation by generating random normal
distributions of size n for SOR/EOR temperature, run length, and LMP percent.
The SOR/EOR pressure, tube thickness, and corrosion rate data is retrieved from
a csv file for the given tube_number and tube_life() is called to make n runs of the
simulation. The resulting distribution of remaining_life is written to output.csv.
tube_mc(tube_number,n)
Start of run Pressure: P_SOR
End of run Pressure: P_EOR
Tube Outer Diameter: tube_OD
Measured Thickness: tube_thickness
Corrosion Rate: corrosion_rate
Roof Tube Temperature Zone
T_SOR: N(=911.66,=39.13)
T_EOR: N(=1113.49,=44.88)
Radiant Tube Temperature Zone
T_SOR: N(=960.1,=14.159)
T_EOR: N(=1151.46,=19.97)
Run length : N(=163.7,=32.95)
LMP Percent: N(=0.5,=0.5/3)
Deterministic Variables Random Variables
coil_data.csv
EOR Temperature Sensitivity - Tube #24
Coil 5 average values for all parameters
0
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
1000 1020 1040 1060 1080 1100 1120 1140 1160 1180 1200 1220 1240 1260 1280 1300 1320 1340
End of Run Temperature (F)
R
e
m
a
i
n
i
n
g

L
i
f
e

(
y
e
a
r
s
)
Monte Carlo Simulation Results
Monte Carlo simulation results show that Tube #24 in
Coil 5 is the first tube expected to reach a partial damage
fraction of 0.80 in 3.73 years at the 99% confidence level.
We can safely continue to operate the heater until August
2016 (3.73 years from 11/15/12) with less than a 1%
probability of mechanical failure. There should be no
issues to make it to the planned January 2016 turnaround.
Increasing end of run temperatures significantly reduces
tube life at an exponential rate.
Coker Heater Remaining Life Monte Carlo Simulation
99% confidence interval (n=10,000)
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
Tube Number
R
e
m
a
i
n
i
n
g

L
i
f
e

(
y
e
a
r
s
)
Coil 5
Coil 6
Coil 5 - Tube #24
3.73 years (Aug 2016)
Tube #50 Distribution of Remaining Life
1% Probability Failure
Monte Carlo Simulation Coil 5 Run Comparisons
0
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
11000
12000
13000
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
Tube Number
R
e
m
a
i
n
i
n
g

L
i
f
e

(
d
a
y
s
)
n=10,000 n=1000 Minimum LMP (LMP Percent = 0) Average LMP (LMP Percent = 1)
#clear all
rm(list = ls(all = TRUE))
for(i in 1:200){cat("\n")}
getwd()

tube_life <-
function(run_length,tube_OD,tube_thickness,corrosion_rate,P_SOR,P_EOR,T_SOR,T_EOR,LMP_percen
t,partial_damage_fraction){

T_daily_increase = (T_EOR-T_SOR)/run_length
P_daily_increase = (P_EOR-P_SOR)/run_length
remaining_life = 0
T = T_SOR
P = P_SOR

while (partial_damage_fraction < 0.80) {

stress = P/2*(tube_OD/tube_thickness-1)
LMP_ave = -1*log(stress/2e+09)*1/0.325
LMP_min = -1*log(stress/1e+09)*1/0.318
LMP = LMP_min + (LMP_ave-LMP_min)*LMP_percent

time_to_rupture = 10^(LMP/(T+460)*10^3-20)
partial_damage_fraction = 24/time_to_rupture + partial_damage_fraction

T = T + T_daily_increase
P = P + P_daily_increase
tube_thickness = tube_thickness - corrosion_rate
remaining_life = remaining_life + 1

if (T > T_EOR) {
T = T_SOR
P = P_SOR
}
}

return(remaining_life)
}

tube_mc <- function(tube_number,n){

tube_data = read.csv("coil 6 data.csv")

pressure = tube_data[tube_number,]$pressure
P_SOR = tube_data[tube_number,]$P_SOR
P_EOR = tube_data[tube_number,]$P_EOR
tube_OD = tube_data[tube_number,]$tube_OD
tube_thickness = tube_data[tube_number,]$tube_thickness
corrosion_rate = tube_data[tube_number,]$corrosion_rate/(1000*365)

RND_T_SOR = rnorm(n, mean=T_SOR_mean, sd=T_SOR_sd)
RND_T_EOR = rnorm(n, mean=T_EOR_mean, sd=T_EOR_sd)
RND_run_length = rnorm(n, mean=run_length_mean, sd=run_length_sd)
RND_LMP_percent = rnorm(n, mean=0.5, sd=0.5/3)

life_dist =
mapply(tube_life,run_length=RND_run_length,tube_OD=tube_OD,tube_thickness=tube_thickness,cor
rosion_rate=corrosion_rate,P_SOR=P_SOR,P_EOR=P_EOR,T_SOR=RND_T_SOR,T_EOR=RND_T_EOR,LMP_perce
nt=RND_LMP_percent,partial_damage_fraction=0)

hist(life_dist,nclass=20)
percentiles = quantile(life_dist,probs=seq(0,1,.01))
percentiles = c(tube_number,n,percentiles)
names(percentiles)[1] = "tube_number"
names(percentiles)[2] = "n"

print(percentiles)

output = data.frame(t(percentiles))
names(output) = names(percentiles)


if (file.exists("output.csv")) {
output_file = read.csv("output.csv")
names(output_file) = names(percentiles)

output_file = rbind(output_file,output)
write.table(output_file, sep = ",", file = "output.csv")
} else write.table(output, sep = ",", file = "output.csv")

}

run_length_mean = 163.7
run_length_sd = 32.95

#roof tubes
T_SOR_mean = 911.66
T_SOR_sd = 39.13
T_EOR_mean = 1113.49
T_EOR_sd = 44.88

tube_mc(19,10000)
tube_mc(20,10000)
tube_mc(21,10000)
tube_mc(22,10000)
tube_mc(23,10000)
tube_mc(24,10000)
tube_mc(25,10000)
tube_mc(26,10000)
tube_mc(27,10000)
tube_mc(28,10000)
tube_mc(29,10000)
tube_mc(30,10000)

#radiant tubes
T_SOR_mean = 960.1
T_SOR_sd = 14.159
T_EOR_mean = 1151.46
T_EOR_sd = 19.97

tube_mc(31,10000)
tube_mc(32,10000)
tube_mc(33,10000)
tube_mc(34,10000)
tube_mc(35,10000)
tube_mc(36,10000)
tube_mc(37,10000)
tube_mc(38,10000)
tube_mc(39,10000)
tube_mc(40,10000)
tube_mc(41,10000)
tube_mc(42,10000)
tube_mc(43,10000)
tube_mc(44,10000)
tube_mc(45,10000)
tube_mc(46,10000)
tube_mc(47,10000)
tube_mc(48,10000)
tube_mc(49,10000)
tube_mc(50,10000)

You might also like