home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hall of Fame
/
HallofFameCDROM.cdr
/
oilfield
/
dynagraf.lzh
/
SPEDYN.BAS
< prev
next >
Wrap
BASIC Source File
|
1989-03-24
|
37KB
|
1,071 lines
'University of Oklahoma Sucker Rod Pumping Unit Diagnostic System
'
'By Robert P. Moore
'
'The Diagnostic system is designed to evaluate surface dynagrphs
'and generate the pump dynagraph from the input data.
'
'The diagnostic system was developed in 1988 - 89 as partial
'fulfilment of the requirements for a Master's of Science in
'Petroleum Engineering. The system is designed for operation on an
'IBM Compatable PC which is attached to a line printer, Calcomp
'Model 23120 12 button Digitizer, and a pen plotter.
'Both the digitizer and the pen plotter are configured through
'COM1. An A-B switch is needed to select which component is needed
'at a particular time. The printer is attached to the parallel
'interface. An Intel 8087-2 Math Co-Processor was also installed to
'speed operations.
'The programming language is Borland's Turbo BASIC for the program
'and Hewlett Packard Graphics Language for the plotter. Due to problems
'initializing the digitizer with the compiled version, I have included
'the Turbo-BASIC Software and Program. To start Turbo Basic, simply type
'and enter tb. After that select 'file', 'retrieve', and the program,
''SPEDYN.BAS. To execute the program simply type 'r' for run. Also
'included on the disc is a LOTUS - 123 spreadsheet which is used to
'plot the data if a pen plotter is not available. The program
'creates a sequential data file which can be loaded into the spread-
'sheet. A macro creates and saves the graphs for plotting with the
'PRINTGRAPH utility. A list of input and output is given below.
'The purpose of the dynagraph diagnostic package is to enable a
'production engineer to analyse a dynagraph quickly and easily
'through a PC environment. Total run time is less than five minutes
'in all cases evaluated to date, including operator input.
'The future in this area could be portable PC's and dynagraph
'interfaces which allow dynagraph analysis on-site and almost in
'real time.
'A field dynagraph is included with this disk to enable operation of
'the program. Also, output generated is given.
'The author would like to recognize the previous work of Cox and
'Chacin. A modified version of Cox's dynagraph input routine is
'while the downhole dynagraph generation solution and routine were
'developed by Chacin as part of his Doctoral research. I would also
'like to thank Dr. Ron Evans for permission to submit this program.
'
'
'..... Input Data....
' 1. Well Name
' 2. Surface Dynagraph Profile
' 3. Peak Polished Rod Load
' 4. Minimum Polished Rod Load
' 5. Travelling Valve Load
' 6. Standing Valve Load
' 7. Counter Balance Effect
' 8. Rod Strin Data
' 9. Fluid Gravity (Optional)
'10. Damping Factor
'11. # Strokes / Minute
'12. Stroke Length
'13. Pump Plunger Diameter
'14. Tubing Head Pressure
'.... Ouput Data ....
' 1. Calculated Fluid Gravity
' 2. Formation Flowing Pressure
' 3. Workin Fluid Depth
' 4. Maximum Polished Rod Load
' 5. Maximum Rod Stress in Top Rod Section
' 6. Average Maximum Polished Rod Load
' 7. Average Minimum Polished Rod Load
' 8. Ideal Counter Balance Effect
' 9. Polished Rod Horsepower
'10. Maximum Pumpstroke
'11. Effective Pumpstroke
'12. Theoretical Pumping Rate
'13. Peak Torque
'14. Peak Torque Crank Angle
'15. Plot of Pump Load vs. Pump Position
'16. Plot of Torque vs. Crank Angle
'If you have any questions I can be reached at 364-8137.
'... Digitize the Dynagraph ...
$com1 4096 'Dimension Com Port Buffer
screen 2
'
begin:
clear
cls
line (0,0)-(0,0),3 'Set up plot capability
dim cr(20) '
get(0,0)-(0,0),cr
dim x(5000),y(5000),c$(5000) 'Dimension Arrays
dim xg(5000),yg(5000)
input "Enter Well Name: ",wellid$
cls
close #1
open "com1:9600,n,8,1" as #1:out &H3FB,11 'Initialize tablet
print #1, "2A"
close #1
open "com1:9600,e,7,1"as #1 'Set tablet for point mode
print #1,"SQj2l"
'
print "Digitize topmost point of dynagraph, by pressing 0"
print #1,"?"
input #1,xymax,ymax,c$
print "Point digitized"
print "
print "Digitize bottom-most point of dynagraph, by pressing 0"
print #1,"?"
input #1,xymin,ymin,c$
print "Point digitized"
delay 1
cls
print "Move cursor to beginning point of dynagraph and press "
print "button #0 when ready. Digitize the upstroke by slowly"
print "tracing the upper half of the profile of the card."
print "
print "After digitizing the upstroke of the card,
print "press button #1 and move the cursor minutely to the right.
print "Release the button and trace the downstroke profile.
'
430 print #1,"?"
input #1,xleft,yleft,c$
if c$<>"1" then goto 430
'
print #1,"SRj2l" 'Put tablet into Run-Prompt mode
i=0
print " x y "
'
inputroutine:
410 i=i+1
j=i-1
420 print #1,"?"
input #1,x(i),y(i),c$(i)
if(x(i)<=x(j)) then goto 420
print "i=" i, x(i),y(i),c$(i)
if c$(i)="2" then goto 450
goto 410
'
450 xright=x(i):yright=y(i):num=i
455 i=i+1
j=i-1
460 print #1,"?"
input #1,x(i),y(i),c$(i)
if(x(i)>=x(j)) then goto 460
if (x(i)<=xleft) then goto 470
print "i=" i, x(i),y(i),c$(i)
goto 455
'
470 locate 20,55
print "Digitizing is complete.
cnt = i
delay 2
'
PlotCard:
cls
locate 1,30
print wellid$
xl=cint((xleft-2000)*.053)
yl=cint((yleft-6000)*-(.05/2))
'print xl,yl
put(xl,yl),cr
for k=1 to i
xg(k)=cint((x(k)-2000)*.053)
yg(k)=cint((y(k)-6000)*-(.05/2))
line -(xg(k),yg(k))
next k
'
locate 20,1
input "Was the digitized shape correct?(y/n)";yes$
if (yes$="Y") then goto start
if (yes$="y") then goto start
print
input "Redo the digitizing. Press enter to start again.";yes$
goto begin
start:
cls
'
input "Enter value for Peak Polished Rod Load";lodmx
print "
input "Enter value for Minimum Polished Rod Load";loadmin
print "
input "Enter Travelling Valve Test Value";tv%
print "
input "Enter Standing Valve Test Value";sv%
print "
input "Enter Counter Balance Effect Value";cbe%
print "
'Dimension Arrays
dim posi(5000),load(5000)
dim posit(5000),newld(5000)
'
i = cnt
x(i)=x(1) 'Convert data to dynagraph scale
y(i)=y(1)
'
for j=1 to i
posi(j)=ceil((x(j)-xleft)*(1000/(xright-xleft)))
load(j)=ceil(((y(j)-ymax)*((lodmx-loadmin)/(ymax-ymin)))+lodmx)
if(posi(j-1)=1000) and (posi(j)=1000) then goto 508
' print posi(j),load(j)
508 next j
'
print ""
print "Data Values Converted to Desired Load and Position Values......Wait"
print "
'
EliminateDuplicates:
posi(1)=0
n=0 'Eliminate duplicate x-axis points
590 n=n+1
m=n+1
if (posi(n)>=1000) then posi(n)=1000: goto 591 'Eliminate duplicates
if (posi(m)<=posi(n)) then posi(m)=(posi(n))+1 'on upstroke
goto 590
' 'Eliminate duplicates
591 if (posi(m)>=posi(n)) then posi(m)=posi(n)-1 'on downstroke
if (posi(n)=0) then print "Duplicate Points Eliminated..Wait":goto interpolate
n=n+1
m=n+1
goto 591
'
interpolate: 'Interpolate between data
numb=n 'to obtain 1000 data points
posmax=posi(numb) 'on the upstroke and the
n=0:m=0:j=0 'downstroke.
502 j=1
n=1
505 m=n+1
if posi(n)=1000 then goto 592
pt1=posi(n):ld1=load(n)
pt2=posi(m):ld2=load(m)
510 if((pt2-pt1)=1) then goto 520
515 newpt2=pt1+ceil((pt2-pt1)/2)
newload=ld1+ceil((ld2-ld1)/2):goto 535
'
520 posit(j)=pt1
newld(j)=ld1
a=1
goto 530
'
535 posit(j)=pt1:newld(j)=ld1
posit(j+1)=newpt2:newld(j+1)=newload
a=2
530 j=j+a
n=n+1
goto 505
'
525 m=n+1
592 pt1=posi(n):ld1=load(n)
pt2=posi(m):ld2=load(m)
593 if((pt1-pt2)=1) then goto 595
594 newpt2=pt1-ceil((pt1-pt2)/2)
newload=ld1-ceil((ld1-ld2)/2)
goto 597
'
595 posit(j)=pt1
newld(j)=ld1
a=1
goto 596
'
597 posit(j)=pt1:newld(j)=ld1
posit(j+1)=newpt2:newld(j+1)=newload
a=2
596 if (posit(j)=0) then goto 540
j=j+a
n=n+1
goto 525
'
540 print "num=" j
if (j>2001) then print "Error in Interpolation":end
repeat:
for b=1 to j
posi(b)=posit(b)
load(b)=newld(b)
next b
if(j<2001) then goto 502
'
print "Interpolation Completed"
print "
'
Filter:
b = 0
for a% = 1 to 500
y = cint((2001/501)*a%)
posi(a%) = posi(y)
load(a%) = load(y)
' print a%,posi(a%),load(a%)
next a%
'lprint "Filter",a%,posi(a%),load(a%)
cls
lprint " *********************************"
lprint
lprint " "Wellid$:lprint
lprint " *********************************"
lprint
input "Enter number of different rod sections:",ntap%
lprint " Rod String Data":lprint:lprint
'...Dimension and initialize variables ...
'ntap% = # of tapers
Dim irod%(ntap%) 'rod material ; 1 = steel; 2 = fiberglass
dim dia(ntap%) 'diameter in inches of the rods
dim aleng(ntap%) 'length of rod section,input in ft converted to in
dim aaleng(ntap%) 'part of aaleng that will need to be interpolated
dim slfact(ntap%) 'strain multiplier to give load
dim wr(ntap%+1) 'weight of rods
dim ey(ntap%) 'young's modulus
dim a(ntap%) 'speed of wave propogation in the rod section
dim amc(ntap%) 'weight per foot of the rod section -- API RP-11l
totdepth = 0
'... Input data from screen ...
print:print"Enter rod data top to bottom.":print
for i% = 1 to ntap%
print:print"Rod section number",i%
print:input"Enter diameter of this rod section #.### in :",dia(i%)
print:input"enter length of this rod section - ft :",aleng(i%)
totdepth = totdepth + aleng (i%)
' print totdepth
aleng(i%) = aleng(i%) * 12 'convert to inches
1 print:input"Enter rod type (1 = steel, 2 = fiberglass) :",irod%(i%)
if irod%(i%) < 1 or irod%(i%) > 2 then print "bad input" : goto 1
lprint " Rod Section Number "i%:
if irod%(i%) = 1 then rodtype$ = "steel"
if irod%(i%) = 2 then rodtype$ = "fiberglass"
lprint " "aleng(i%)/12 " feet of "dia(i%) " inch " rodtype$ " rods."
lprint
next i%
'... Input fluid gravity or calculate it from the SV check ...
lprint " *********************************"
lprint
res = 5! 'convergence criterion on the position variable
cut = 1! 'maximum length ignored for interpolation
cut = cut * 12
pi = 3.1415926#
'... dimension variables ...
m% = 500 '500 data points will be read
dim time(m%+1)
dim ww(m%+1), uprime(ntap%+1,m%+1),vprime(ntap%+1,m%+1),wprime(ntap%+1,m%+1)
dim us(2*m%+1),vs(2*m%+1),ws(2*m%+1)
'in the previously dimensioned variables, u refers to
'position in inches, v refers to strain, and w refers
'to velocity in in / sec, time is in seconds
' ... Initialize arrays ...
' for i% = 1 to m%
' time(i%+1) = time(i%) + adt
' next i%
for i% = 1 to ntap% + 1
wr(i%) = 0
next i%
' ...Loop to calculate rod section properties ...
for i% = 1 to ntap%
if irod%(i%) = 2 then goto 10
' ... for steel rods ...
a(i%) = 195600!
ey(i%) = 3.05E+07
if dia(i%) = 1.5 then amc(i%) = 533!*pi*(dia(i%)^2)/6912! 'lb/in
if dia(i%) = 1.25 then amc(i%) = 4.538/12!
if dia(i%) = 1.125 then amc(i%) = 3.676/12!
if dia(i%) = 1! then amc(i%) = 2.904/12!
if dia(i%) = .875 then amc(i%) = 2.224/12!
if dia(i%) = .75 then amc(i%) = 1.634/12!
if dia(i%) = .625 then amc(i%) = 1.135/12!
if dia(i%) = .5 then amc(i%) = 0.726/12!
goto 20
10 ' ... for fiberglass rods ...
a(i%) = 177270!
ey(i%) = 7200000!
amc(i%) = 153! * pi * (dia(i%)^2)/(4! * 144! * 12!)
20 slfact(i%) = pi * (dia(i%)^2) * ey(i%) / 4!
wr(i%) = amc(i%) * aleng(i%)
'print "20","i%="i%,"dia(i%)="dia(i%),"aleng(i%)=",aleng(i%)
'print "a(i%)="a(i%),"ey(i%)="ey(i%),"slfact(i%)="slfact(i%)
'print "wr(i%)="wr(i%)
next i%
' ... calculate total rod weight and volume ...
twr = 0!
rodvol = 0!
for i% = 1 to ntap%
rodvol = rodvol + ( pi * (dia(i%)^2)/4!) * aleng(i%)
twr = twr + wr(i%)
next i%
' ... input dynagraph data ...
lprint " Recorded Travelling Valve Load = "tv%" pounds":lprint
lprint " Recorded Standing Valve Load = "sv%" pounds":lprint
lprint " Recorded Counter Balance Effect = "cbe%" pounds":lprint
lprint " *********************************":lprint:lprint
if sv% = 0 then goto 5 'sv load is not input, fluid gravity must be
print
input "Do you want to input a fluid gravity instead of allowing a value be calculated? ",grvans$
if grvans$ = "y" then goto 5
if grvans$ = "Y" then goto 5 else goto 7
5 print:input "Specific gravity of fluid :",grav
lprint using " Input Fluid Gravity =#.###";grav:lprint
goto 8
7 grav = 7.874 * ( 1 - sv% / twr ) ' calculate fluid gravity
lprint using" Calculated Fluid Gravity =#.#### "; grav:lprint
8 print:input "Enter damping factor (0.1 1/sec is recommended) :",c
lprint using" Damping factor (1/sec) =#.###";c:lprint
lprint
lprint " *********************************"
lprint:lprint
' ... calculate buoyed weight of rods - wrf ...
buo = rodvol * grav * 62.4 / 1728!
wrf = twr - buo
' ... Calculate rod stretch ...
rodst = 0
for i% = 1 to ntap%
rodst = rodst + 32.2 * ((aleng(i%)/a(i%))^2)*(12!)
rodst = rodst + (4!*aleng(i%)/(pi*(dia(i%)^2)*ey(i%)))*(-buo+wr(i%+1))
next i%
if ntap% = 3 then goto 30 else goto 40
30 rodst = rodst + (4! * aleng(1) / (pi* (dia(1)^2)* ey(1))) * wr(3)
40 if ntap% = 4 then goto 50 else goto 60
50 rodst = rodst + (4! * aleng(1) / (pi* (dia(1)^2)* ey(1))) * (wr(3)+wr(4))
rodst = rodst + (4! * aleng(2) / (pi* (dia(2)^2)* ey(2))) * (wr(4))
60 '
'lprint "60","rodvol="rodvol,"twr="twr,"buo="buo,"wrf="wrf,"rodst="rodst
' ... Input unit data ...
lprint" Pump Data":lprint
print: input "Input number of strokes / minute:",nst#
lprint " Number of Strokes / Minute "nst#:lprint
print: input "Input stroke Length - in:",stl
lprint " Stroke Length= "stl" inches":lprint
print: input "Input Pump Plunger Diameter - inches:",plsize
lprint " Pump Plunger Diameter ="plsize"inches":lprint
print: input "Tubing Head Pressure - psi:",thp
lprint " Tubing Head Pressure ="thp"psi":lprint
plunarea = pi / 4 *(plsize)^2
if (sv% > 0 and tv% > 0) then goto 23 else goto 24
23 pwf = int((twr - sv%) / (pi * (dia(ntap%)/2)^2) - (tv% - sv%) / plunarea + (thp * ( 1 - (pi * (dia(ntap%)/2)^2) / plunarea)))
lprint " Flowing Pressure ="pwf"psi":lprint
wflddp = int(totdepth - (2.31 / grav) * ( pwf - thp))
lprint " Working Fluid Depth ="wflddp"feet":lprint
24 lprint " *********************************"
lprint:lprint
's = stroke indicator s = 0 =>upstroke; s= 1 =>downstroke
'tst = timestep , changes by adt at every ct point
'ct = counter for ouput of equally spaced (adt) position and strain
' values
s = 0 : tst = 0 : ct% = 1
upstarea = 0: downarea = 0
adt = (60 / nst# / 500) '500 dt points
'lprint "adt="adt
halfstr = stl /2 '1/2 strokelength
dimlen% = 500 '# of inputs from dynagraph file
'tm(j) = time that the data was recorded,start of upstroke = 0
'posi(j) = position data from dynagraph file, converted to inches
' varying from - stl/2 to + stl/2
'load(j) = load value from dynagraph file, converted to strain
' ... dimension, load, and convert dynagraph data to time basis ...
' This program is set up to use a dynagraph file with
' 250 points on the upstroke and downstroke. If a
' different size file is used the program will need to be changed.
dim tm(dimlen%),sload(dimlen%)
maxload = 0 'Maximum load in first rod section
'... Read load and position data from file ...
for j% = 1 to 500
posi(j%)=(posi(j%)/ 1000 * stl)-halfstr 'sine wave w/ amp = stl/2
' lprint j%,posi(j%)
if j% > 250 then s = 1 'downstroke
'... Calculate area under the dynagraph using Trapezoidal Rule ...
if j% > 1 and j% < 500 then goto 61 else goto 62
61 avload = load(j%) - ((load(j%) - load(j%-1))/2)
if load(j%) > maxload then maxload = load(j%)
area = avload * (posi(j%) - posi(j%-1))
if s = 0 then upstarea = upstarea + area
if s = 1 then downarea = downarea - area
62 sload(j%) = (load(j%) - wrf)/slfact(1) 'load to strain
'print "pos=",posi(j%),"load=",sload(j%),"s=",s:delay .2
sine = posi(j%)/halfstr
cosine = ((1-(sine)^2)^.5)
' lprint sine,cosine
if (cosine = 0 and posi(j%) < 0) then angle = -90 'avoid
if (cosine = 0 and posi(j%) > 0) then angle = 90 'error
if cosine <> 0 then angle = (atn((sine)/(cosine)))*180 /pi
'print sine,cosine,angle,posi(j%):delay 3
tm(j%) =s*60/nst#+(-1)^s*((1/nst#)*60/4 + angle/(nst#*360)*60)
'if tm(j%) < 0.5 then lprint j%,"time=",tm(j%),"posi=",posi(j%)
next j%
lprint " Dynagraph Data"
maxprl = (upstarea) / stl
maxstres = maxload / (pi * ((dia(1))^2)/4)
lprint
lprint using" Maximum Polished Rod Load (lb) =##### ";maxload:lprint
lprint using" Max Rod Stress in Top String(psi) = ##### ";maxstres:lprint
lprint using" Average Max Polished Rod Load (lb) =##### "; maxprl:lprint
minprl = downarea / stl
lprint using" Average Min Polished Rod Load (lb) =##### ";minprl
lprint
idcbeff = .5 * ( maxprl + minprl )
lprint using" Ideal Counter Balance Effect (lb)=##### "; idcbeff
lprint
prhp = stl * nst# * (upstarea - downarea) / ( 396000 * stl )
lprint using" Polished Rod Horse Power =###.# "; prhp :lprint
lprint " *********************************"
lprint:lprint
' ... Obtain 500 equally spaced(adt) data points ...
' The strain and position values are interpolated to correspond
' to the time step points
tm(1) = 0 : posi(1) = - stl/2
tm(500) = 60 / nst# : posi(500) = - stl/2
'chdir"c:\123\files"
'file$ = "erase2.prn"
'open file$ for output as #2
for k% = 1 to 500
55 q = abs(tm(k%) - tst):'lprint ct%,"tst="tst,"tm="tm(k%),"decimal q = ",q
if ( q < .000001)then goto 56 else goto 58
56 time(ct%) = tst:'print time(ct%)
uprime(0,ct%) = - posi(k%):'lprint uprime(0,ct%)
vprime(0,ct%) = sload(k%):'lprint vprime(0,ct%)
goto 71
58 q = int(int(q*100) + 1) '# of adt points between the values
'lprint ct%,"q=",q
if (tm(k%-1) < tst and tm(k%) >tst) then goto 59 else goto 65
59 for i% = 1 to q
'lprint"i%",i%
time(ct%) = tst 'interpolate strain and
intrp = - (tm(k%) - tst)/(tm(k%)-tm(k%-1)) 'position to time intv
uprime(0,ct%) = -(intrp*(posi(k%) - posi(k%-1)) + posi(k%))
vprime(0,ct%) = intrp*(sload(k%) - sload(k%-1)) + sload(k%)
70 'write #2,ct%,time(ct%),uprime(0,ct%),vprime(0,ct%)
'lprint "70",ct%,"time(ct%)="time(ct%),"uprime(0,ct%)="uprime(0,ct%)
'lprint "vprime(0,ct%)=",vprime(0,ct%):delay .3
ct% = ct% + 1 'next time based data point
if ct% > 500 then goto 66
tst = tst + adt 'next time step
next i%
goto 65
71 'write #2,ct%,time(ct%),uprime(0,ct%),vprime(0,ct%)
ct% = ct% + 1
if ct% > 500 then goto 66
tst = tst + adt
65 next k%
66
' uprime(x,ct%) => position at x (0=>surface) for ct% = 1 to 500
' vprime(x,ct%) => strain at x (0 =>surface) for ct% = 1 to 500
' ... Obtain polished rod velocity by differentiating position data ...
print " ... Data loaded and converted to time and strain ...
ct% = ct% - 1
for i% = 1 to ct%
if i% = ct% then uprime(0,i%+1) = uprime(0,1)
ww(i%) = (uprime(0,i%+1) - uprime(0,i%))/adt ' delta x / delta t
next i%
wprime(0,1) = (ww(1) + ww(ct%))/2!
for ii% = 2 to ct%
wprime(0,ii%) = (ww(ii%) + ww(ii%-1))/2!
'print ii%,time(ii%),wprime(0,ii%):delay .3
next ii%
'print "ct = 499"
'print uprime(0,499),vprime(0,499),wprime(0,499)
'print "ct = 500"
'print uprime(0,500),vprime(0,500),wprime(0,500)
'print "ct = 1"
'print uprime(0,1)vprime(0,1)wprime(0,1)
' ... Start method of characteristics ...
cls
print "Executing method of characteristics"
75 for ijk% = 1 to ntap%
' Calculate the propagation interval dx(inches), number of propagation
' intervals nn%, and fractional length for interpolation aaleng%(in),
' for current rod section ijk%
'print "adt=",adt,"a(ijk%)=",a(ijk%),"ijk%",ijk%
dx = adt * a(ijk%) / 24! ':print dx
dx = dx * 12!
'print aleng(ijk%)
anum = aleng(ijk%) / dx 'fractional # of dx's in this section
nn% = int(anum) 'number of dx's in this section
ill% = 1
aaleng(ijk%) = aleng(ijk%) - (dx * nn%) 'remaining section past
'nn%
'print : print anum,nn%,aaleng(ijk%)
aa = ( 1! / a(ijk%)) + (( c * adt/2!)/(2! * a(ijk%)))
bb = ( 1! / a(ijk%)) - (( c * adt/2!)/(2! * a(ijk%)))
' ... Set convergence counter to zero ...
lll% = 0
' ... Check if number of propagation intervals is zero ...
' If so, go to interpolation
if nn% = 0 then goto 76 else goto 80
76 for i% = 1 to ct%
uprime(ijk%,i%) = uprime(ijk%-1,i%) 'initial position
vprime(ijk%,i%) = vprime(ijk%-1,i%) 'initial strain
wprime(ijk%,i%) = wprime(ijk%-1,i%) 'initial velocity
'print "76",uprime(ijk%,i%),vprime(ijk%,i%),wprime(ijk%,i%)
next i%
' delay 20
goto 200
80 for j% = 1 to ct%
if j% < ct% goto 90
uprime(ijk%-1,ct%+1) = uprime(ijk%-1,1) 'position
vprime(ijk%-1,ct%+1) = vprime(ijk%-1,1) 'strain
wprime(ijk%-1,ct%+1) = wprime(ijk%-1,1) 'velocity
90 cc = - bb * wprime(ijk%-1,j%) + vprime(ijk%-1,j%)
dd = aa * wprime(ijk%-1,j%+1) + vprime(ijk%-1,j%+1)
' ... calculate velocity and strain at next point ...
wprime(ijk%,j%) = (dd - cc) / (bb + aa)
vprime(ijk%,j%) = (aa*dd + bb*cc) / (bb + aa)
' ...calculate positions at next two points along the char. ...
92 u=(dx/2!)*(vprime(ijk%,j%)+vprime(ijk%-1,j%+1))+uprime(ijk%-1,j%+1)
u=u-.5*(adt/2!)*(wprime(ijk%,j%)+wprime(ijk%-1,j%+1))
uu=(dx/2!)*(vprime(ijk%,j%)+vprime(ijk%-1,j%))+uprime(ijk%-1,j%)
uu=uu+.5*(adt/2!)*(wprime(ijk%,j%)+wprime(ijk%-1,j%))
diff = u - uu
diff = abs(diff)
'Check convergence of position along both characteristics. If convergence
'is satisfied, go on. If not increase counter by 1 and iterate
94 if diff < res goto 100
lll% = lll% + 1 'increase counter
f = ((c*adt)/(4!*a(ijk%)))*(wprime(ijk%,j%)+wprime(ijk%-1,j%))
f = f - wprime(ijk%-1,j%)/a(ijk%)+vprime(ijk%-1,j%)
g = ((c*adt)/(4!*a(ijk%)))*(wprime(ijk%,j%)+wprime(ijk%-1,j%+1))
g = g + wprime(ijk%-1,j%+1)/a(ijk%)+vprime(ijk%-1,j%+1)
vprime(ijk%,j%) = (f+g)/2!
wprime(ijk%,j%) = a(ijk%) * (g-f)/2!
'if more than ten iterations are needed to converge, prompt
'for larger value of res(inches).
if lll% > 10 then goto 95 else goto 92
95 print "Convergence criteria, RES, too small."
print "Currently RES in inches is",res
input "Enter new value for RES:",res
goto 75
100 lll% = 0
uprime(ijk%,j%) = (u+uu)/2
'if j% >498 then print uprime(ijk%,j%),vprime(ijk%,j%),wprime(ijk%,j%)
next j%
'end of loop to calculate all points (ct%) at current dx station
if ill% < nn% then goto 110 else goto 200
110 ill% = ill%+1
for i% = 1 to ct%
uprime(ijk%-1,i%) = uprime(ijk%,i%) 'position
vprime(ijk%-1,i%) = vprime(ijk%,i%) 'strain
wprime(ijk%-1,i%) = wprime(ijk%,i%) 'velocity
next i%
goto 80
'End of loop to calculate all data at nn% propagation intervals for
'current rod section.
200 'check if interpolation is desired on current rod section ijk%
if aaleng(ijk%) < cut goto 300
ddt = aaleng(ijk%) / a(ijk%)
dt = adt
us(1) =(1!/dt)*(uprime(ijk%,ct%)*ddt+uprime(ijk%,1)*(dt-ddt))
vs(1) =(1!/dt)*(vprime(ijk%,ct%)*ddt+vprime(ijk%,1)*(dt-ddt))
ws(1) =(1!/dt)*(wprime(ijk%,ct%)*ddt+wprime(ijk%,1)*(dt-ddt))
lm% = 2 * ct%
us(lm%) = (1!/dt)*(uprime(ijk%,ct%)*(dt-ddt)+uprime(ijk%,1)*ddt)
vs(lm%) = (1!/dt)*(vprime(ijk%,ct%)*(dt-ddt)+vprime(ijk%,1)*ddt)
ws(lm%) = (1!/dt)*(wprime(ijk%,ct%)*(dt-ddt)+wprime(ijk%,1)*ddt)
lc% = lm% - 2
ic% = 0
for k% = 2 to lc% step 2
iaa% = k%-1-ic%
ia% = k%-ic%
us(k%) = (1!/dt)*(uprime(ijk%,iaa%)*(dt-ddt)+uprime(ijk%,ia%)*ddt)
vs(k%) = (1!/dt)*(vprime(ijk%,iaa%)*(dt-ddt)+vprime(ijk%,ia%)*ddt)
ws(k%) = (1!/dt)*(wprime(ijk%,iaa%)*(dt-ddt)+wprime(ijk%,ia%)*ddt)
us(k%+1)=(1!/dt)*(uprime(ijk%,iaa%)*ddt+uprime(ijk%,ia%)*(dt-ddt))
vs(k%+1)=(1!/dt)*(vprime(ijk%,iaa%)*ddt+vprime(ijk%,ia%)*(dt-ddt))
ws(k%+1)=(1!/dt)*(wprime(ijk%,iaa%)*ddt+wprime(ijk%,ia%)*(dt-ddt))
ic% = ic% + 1
next k%
'for i% = 1 to lm%
' print us(i%),vs(i%),ws(i%)
'next i%
aaa = (1!/a(ijk%)) + ((c*ddt)/( 2! * a(ijk%)))
bbb = (1!/a(ijk%)) - ((c*ddt)/( 2! * a(ijk%)))
for k% = 1 to ct%
kk% = 2 * k%
kkk% = kk% - 1
ccc = -bbb * ws(kkk%) + vs(kkk%)
ddd = +aaa * ws(kk%) + vs(kk%)
'If this is the last section, the following calculated positions
'velocities, and strains will be the conditions at the pump.
wprime(ijk%,k%) = (ddd - ccc)/(bbb + aaa)
vprime(ijk%,k%) = (aaa * ddd + bbb * ccc)/(bbb + aaa)
uans = (aaleng(ijk%)/2!)*(vprime(ijk%,k%)+vs(kk%))
uans = uans + us(kk%) - (ddt*(wprime(ijk%,k%) + ws(kk%))/2!)
uuans = (aaleng(ijk%)/2!) * (vprime(ijk%,k%) + vs(kkk%))
uuans = uuans + us(kkk%) + (ddt*(wprime(ijk%,k%) + ws(kkk%))/2!)
uprime(ijk%,k%) = (uans + uuans)/2!
next k%
' Check to see if this is the last rod section. If not use continuity
' to determine boundary conditions. # of sections loop
' ends at 310
300 if ijk% < ntap% then goto 305 else goto 310
305 for i% = 1 to ct%
vprime(ijk%,i%) = vprime(ijk%,i%) * slfact(ijk%) 'load in this sect
vprime(ijk%,i%) = vprime(ijk%,i%) / slfact(ijk%+1) 'continuity load
'print i%
'print uprime(ijk%,i%),vprime(ijk%,i%),wprime(ijk%,i%) 'converted to
'strain in next
'section
next i%
310 next ijk% 'finish method of characteristics
for i% = 1 to ct%
330 uprime(ntap%,i%) = -uprime(ntap%,i%) + rodst
vprime(ntap%,i%) = vprime(ntap%,i%) * slfact(ntap%)
next i%
pstmin = 1000
pstmax = -1000
loadmax = 0
effcount = 0
loadmin = 10000000
for i% = 1 to ct%
if uprime(ntap%,i%) < pstmin then pstmin = uprime(ntap%,i%)
if uprime(ntap%,i%) > pstmax then pstmax = uprime(ntap%,i%)
if vprime(ntap%,i%) > loadmax then loadmax = vprime(ntap%,i%)
if vprime(ntap%,i%) < loadmin then loadmin = vprime(ntap%,i%)
if i% > (ct%/2) then goto 341 else goto 343
341 if effcount <> 0 then goto 343
if vprime(ntap%,i%) < .05 * loadmax then goto 342 else goto 343
342 effstr = uprime(ntap%,i%)
effcount = 1
343 next i%
lprint" Downhole Dynagraph Data"
lprint using" Maximum Pumpstroke (inches)=###";pstmax - pstmin
lprint
effstr = effstr - pstmin
lprint using" Effective Pumpstroke (inches) =###";effstr:lprint
thpumprt = effstr * nst# * plunarea * 60 * 24/(1728*5.615)
lprint using" Theoretical Pumping Rate (BBL/day)=####";thpumprt
lprint
s = 0
peaktk = 0:mintk =1000000
dim torque(500)
dim angle(500)
pktkang = -1
for i% = 1 to 500
if i% > 250 then s = 1
sine = posi(i%)/halfstr
cosine = ((1-(sine)^2)^.5)
if (cosine = 0 and posi(j%) < 0) then angle(i%) = -90 'avoid
if (cosine = 0 and posi(j%) > 0) then angle(i%) = 90 'error
if cosine <> 0 then angle(i%) = (atn((sine)/(cosine)))*180 /pi
if s = 0 then angle(i%) = angle(i%) + 90
if s = 1 then angle(i%) = 270 - angle(i%)
If i% = 1 then angle(i%) = 0
If i% = 500 then angle(i%) = 360
torque(i%) = ( load(i%) - cbe% ) * halfstr * sin(angle(i%)*2*pi/360)
if torque(i%) > peaktk then pktkang = angle(i%)
if torque(i%) > peaktk then peaktk = torque(i%)
if torque(i%) < mintk then mintk = torque(i%)
'print torque(i%),angle(i%):delay .1
next i%
lprint " *********************************":lprint
lprint " Torque Data"
lprint using" Peak Torque (inch lb) = ########"; peaktk :lprint
lprint using" Peak Torque Angle (degrees) =###"; pktkang :lprint
lprint " *********************************":lprint
input "Do you have a pen plotter available";ans$
if ans$ = "y" then goto plot:
if ans$ = "Y" then goto plot:
cls
print "Your downhole dynagraph data will be sent to a LOTUS 1-2-3 file"
print "where a graph can be made."
340 chdir"c:\123\files"
files "*.prn"
input"LOTUS file for Downhole Pump Card?",file$
open file$ for output as #2
for i% = 1 to ct%
write #2,i%,time(i%),uprime(ntap%,i%),vprime(ntap%,i%),angle(i%),torque(i%)
next i%
close #2
lprint " Data saved under:",file$
input "Press enter to return to system.",ent
cls
end
plot:
print"You may need to switch from the digitizer to the plotter."
print"The plotter will need pens in both the 1st and 2cd slots."
input"Press enter when ready."ans$
loadmax = ceil(loadmax/500) * 500 'set max load as nearest 500 above
loadmin = int(loadmin/500) * 500 'set min load as nearest 500 below
pstmax = ceil(pstmax/5) * 5 'set max position as nearest 5 above
pstmin = int(pstmin/5) * 5 'set min position as nearest 5 below
close #1
open "com1:9600 ,n,8,1,rs,cs65535,ds,cd" as #1
print #1, "in;sp1;ip2000,2000,8750,6250;"
print #1, "sc";pstmin,pstmax,loadmin,loadmax;
print #1, "pu"pstmin,loadmin;"pd"pstmax,loadmin,pstmax,loadmax,pstmin,loadmax,pstmin,loadmin;"pu;"
print #1, "si.2,.3;tl1.5,0;"
for x = pstmin to pstmax step 10
print #1,"pa";x,loadmin;";xt;"
if x > 100 then print #1,"cp -2.27,-1;":goto 800
if x < 10 then print #1,"cp -1.33,-1; "
if x > 9 then print #1,"cp -1.80,-1;"
800 print #1,"lb";x;chr$(3)
next x
pstavg = (pstmax - pstmin)/2 + pstmin
print #1,"pa"pstavg,loadmin;"cp-9,-2.5;"
print #1,"lbPump Position - in"+chr$(3)
for x = loadmin to loadmax step 500
print #1,"pa";pstmin,x;";yt;"
next x
for x = loadmin to loadmax step 1000
print #1,"pa"pstmin,x;
if x < -9999 then print #1,"cp-7,-.25;"
if x < -999 then print #1,"cp-6,-.25;":goto 801
if x < -100 then print #1,"cp-5,-.25;":goto 801
if x = 0 then print #1,"cp-2,-.25;":goto 801
if x = 500 then print #1,"cp-4,-.25;":goto 801
if x > 9999 then print #1,"cp-6,-.25;":goto 801
if x > 999 then print #1,"cp-5,-.25;":goto 801
if x > 99999 then print #1,"cp-7,-.25;":goto 801
801 print #1,"lb"x;chr$(3)
next x
print #1,"pa"pstmin,loadmax;"cp-5,2;"
print #1,"lbLoad - lb"+Chr$(3)"
title$ = wellid$
print #1,"sp1;pa"pstavg,loadmax;"si.3,.5;cp"; -len(title$)/2;"2;lb";title$+chr$(3)
print #1,"sp1;si.2,.3;"
print #1,"sp2;lt;pa";uprime(ntap%,1)","vprime(ntap%,1);"pd";
for x = 1 to 500
print #1,"pd";uprime(ntap%,x)","vprime(ntap%,x);
next x
6101 print #1,"sp0;"
cls
print"Reload plotter paper to plot Torque Curve."
input"Press enter when ready."ans$
loadmax = ceil(peaktk/5000) * 5 'set max torque as nearest 5000 above
loadmin = int(mintk/5000) * 5 'set min torque as nearest 5000 below
if loadmin > 0 then loadmin = 0
pstmax = 360
pstmin = 0
close #1
open "com1:9600 ,n,8,1,rs,cs65535,ds,cd" as #1
print #1, "in;sp1;ip2000,2000,8750,6250;"
print #1, "sc";pstmin,pstmax,loadmin,loadmax;
print #1, "pu"pstmin,loadmin;"pd"pstmax,loadmin,pstmax,loadmax,pstmin,loadmax,pstmin,loadmin;"pu;"
print #1, "si.2,.3;tl1.5,0;"
for x = pstmin to pstmax step 45
print #1,"pa";x,loadmin;";xt;"
if x > 100 then print #1,"cp -2.27,-1;":goto 805
if x < 10 then print #1,"cp -1.33,-1; "
if x > 9 then print #1,"cp -1.80,-1;"
805 print #1,"lb";x;chr$(3)
next x
pstavg = 180
print #1,"pa"pstavg,loadmin;"cp-7,-2.5;"
print #1,"lbAngle - degrees"+chr$(3)
for x = loadmin to loadmax step 2.5
print #1,"pa";pstmin,x;";yt;"
next x
for x = loadmin to loadmax step 5
print #1,"pa"pstmin,x;
if x < -9.999 then print #1,"cp-3,-.25;":goto 806
if x < -.999 then print #1,"cp-2,-.25;":goto 806
if x < -.100 then print #1,"cp-2,-.25;":goto 806
if x = 0 then print #1,"cp-2,-.25;":goto 806
if x = .500 then print #1,"cp-2,-.25;":goto 806
if x > 99.999 then print #1,"cp-4,-.25;":goto 806
if x > 9.999 then print #1,"cp-3,-.25;":goto 806
if x > .999 then print #1,"cp-2,-.25;":goto 806
806 print #1,"lb"x;chr$(3)
next x
print #1,"pa"pstmin,loadmax;"cp-7.5,2;"
print #1,"lbTorque - ( M in-lb)"+Chr$(3)"
title$ = wellid$
print #1,"sp1;pa"pstavg,loadmax;"si.3,.5;cp"; -len(title$)/2;"2;lb";title$+chr$(3)
print #1,"sp1;si.2,.3;"
print #1,"sp2;lt;pa";angle(1)","torque(1);"pd";
for x = 1 to 500
print #1,"pd";angle(x)","torque(x)/1000;
next x
print #1,"sp0;"
chdir "c:\turbo\files"
close #1
end