Well Positioning
April 1999, EarthVision 5
Many things go into good well positioning. The focus of this first Advanced
User Forum is how to determine a well path in relation to the structural
surface above and below the zone of interest. We will deal with four typical
problems:
A. Determining the distance from an existing
point to a top target horizon and a bottom target horizon.
B. Creating a series of points a specified distance
above a target horizon within a single fault block.
C. Correcting any point in a path that is closer
to a target horizon than desired using a single horizon grid.
D. Creating a series of points a specified distance
above a target horizon using a sequence file.
(Note: In all scripts and command lines that follow, a backslash
( \ ) at the end of a line indicates that the current line is continued
on the line that follows. When creating the script or typing the command
line, these lines should be entered as one continuous line without the backslash.)
A. Determining the distance
from an existing point to a top and bottom target horizon.
Required Elements:
sequence file with horizon grids
faces file of the model
data set
script below (bak2zones.sh)
Determining the distance from an existing point to a top and bottom target
horizon requires three steps:
- Determining the names of the top and bottom horizons
- Creating a script to calculate the distance
- Running the script from within the 3-D Viewer, while selecting the
desired points
The first thing is to determine the exact names of the top and bottom target
horizons. To do this, bring the sequence file into the Geologic Structure
Builder module and choose Model Definition -> Select Sequence. The
zone names are displayed in the left portion of the Select Sequence window
under the Zone label. An alternative method for determining the names
is to compose a "show" script, as shown below, that reports the zones in
stratigraphic order:
========= start of script: showzones.sh =================
#!/bin/sh
SEQFILE=$1
cat $1 | nawk '
$1 ~ /Zone/ {
split ($0, a, "\"");
print a[2];
}' | nawk '{x[NR]=$0}
END {
for (i=NR;i>0;i--)
print "\""x[i]"\""
}'
========= end of script: showzones.sh ===================
NOTE: This is a Bourne shell script using the "nawk" utility.
To use this script named showzones.sh (in this example), it must
have execute permissions:
chmod 777 showzones.sh
To run the script, a sequence file is given as the single command line argument:
showzones.sh gsbstrc.seq
The output lists the zone names between double quotation marks. These quotations
are not part of the zone names.
Once you have determined the top horizon name, the bottom horizon name,
and the sequence file name, that information can be entered into another
Bourne shell script file. In this example, the sequence file name is gsbstrc.seq,
the top layer is called Layer 4, and the bottom layer is called
Layer 3. In the script below, these values are entered in the
first few lines:
========= start of script: bak2zones.sh =================
#!/bin/sh -e
SEQFILE='gsbstrc.seq'
TOP='Layer 4'
BOTTOM='Layer 3'
while read point
do
XVAL=`echo $point | nawk 'BEGIN {FS=","} {print
$2}'`
XVAL=`echo $XVAL | sed 's/^.*=//'`
YVAL=`echo $point | nawk 'BEGIN {FS=","} {print $3}'`
YVAL=`echo $YVAL | sed 's/^.*=//'`
ZVAL=`echo $point | nawk 'BEGIN {FS=","} {print $4}'`
ZVAL=`echo $ZVAL | sed 's/^.*=//'`
echo "$XVAL $YVAL $ZVAL" >> temp$$.dat
ev_fbsort -d temp$$.dat $SEQFILE > temp2$$.dat
ev_fpfp << EOF
temp3$$.dat<faultblock>=temp2$$.dat<faultblock>;
EOF
BLOCK=`cat temp3$$.dat | nawk '/^#/ {next} {print}'`
rm -f temp$$.dat temp2$$.dat temp3$$.dat
GRID1=`cat $SEQFILE | nawk -v HOR="$TOP" -v BLK="$BLOCK"
'
/FaultBlock/ {
split ($0, a, "\"");
fb = a[2];
getline;
if ($0 !~ "Sequence") {
next;
}
else {
getline
while (!/}/) {
split ($0, b, "\"");
zn = b[2];
if (HOR ~ zn && BLK ~ fb) {
gsub(/ /,"_",zn)
print $NF
}
getline
}
}
}'`
GRID2=`cat $SEQFILE | nawk -v HOR="$BOTTOM" -v BLK="$BLOCK"
'
/FaultBlock/ {
split ($0, a, "\"");
fb = a[2];
getline;
if ($0 !~ "Sequence") {
next;
}
else {
getline
while (!/}/) {
split ($0, b, "\"");
zn = b[2];
if (HOR ~ zn && BLK ~ fb) {
gsub(/ /,"_",zn)
print $NF
}
getline
}
}
}'`
echo "POINT: $XVAL $YVAL $ZVAL"
echo "Distance from Top horizon: $TOP :"
ev_fpfp -u << EOF
$ZVAL-bakint($GRID1,$XVAL,$YVAL);
EOF
echo "Distance from Bottom horizon: $BOTTOM :"
ev_fpfp -u << EOF
$ZVAL-bakint($GRID2,$XVAL,$YVAL);
EOF
echo ""
done
========= end of script: bak2zones.sh ===================
Once this script is created and has execute permissions, it is ready
for use by simply typing its name at the command line.
The next step is to run the bak2zones.sh script within the 3-D
Viewer. Open the 3-D Viewer with the faces file of the model. Display
the scattered data file in question (use Ctrl-b hot key for a list of
data files). Then go to the Post Data window (hot key 6) and click on
the Select Data Query Program button. In the Status Window, type
in the name of the above script bak2zones.sh.
Each time you click on a data point with the right mouse button, a message
similar to the following will be displayed in the xterm window from which
you started EarthVision:
POINT: 74775.4 289700 -3523.32
Distance from Top horizon: Layer 4 :
-3523.32-bakint(EXTEN_Block5_Layer_4.2grd,74775.4,289700)
\
value: -84.2948535156252
Distance from Bottom horizon: Layer 3 :
-3523.32-bakint(EXTEN_Block5_Layer_3.2grd,74775.4,289700)
\
value: 43.1585156249998
The line beginning with the word "POINT" reports the X,Y,Z location of
the point selected. The first distance reports the distance below the
top horizon where a negative value indicates the point is below the top
horizon; the second distance reports the distance above the bottom horizon,
where a positive value indicates the point is above the bottom horizon).
B. Creating a series of points
that are a specified distance above a target horizon within a single fault
block.
Required Elements:
sequence file with horizon grids
data set
Creating a series of points that are a specified distance above a target
horizon within a single fault block requires the following steps:
- Creating and running a script that identifies the name of the grid
that represents the surface in the desired fault block
- Creating and running a Formula Processor script that adds the specified
distance to the back-interpolated value at each input data point location
When the data set lies entirely within the same fault block, the problem
is solved by simply performing a Formula Processor operation on the data
set and the grid for that horizon in that fault block. (If the data set
extends over several fault blocks, then a sequence file must be used; this
problem is solved in example D below.) The first step
is to identify the grid file that is in the desired fault block. The following
short script performs this task:
========= start of script: showblocks.sh =================
#!/bin/sh
SEQFILE=$1
HORIZON=$2
echo ""
echo "$HORIZON grid names for the following blocks"
cat $SEQFILE | nawk -v HOR="$HORIZON" '
/FaultBlock/ {
split ($0, a, "\"");
fb = a[2];
getline;
if ($0 !~ "Sequence") {
next;
}
else {
getline
while (!/}/) {
split ($0, b, "\"");
zn = b[2];
if (HOR ~ zn) {
print "BLOCK:",fb, "\t\tGRID:", $NF
}
getline
}
}
}'
echo ""
========= end of script: showblocks.sh ===================
This script is run by specifying a sequence file and zone name on the
command line. If the zone name has spaces in it, the full name must be
surrounded by double quotes:
showblocks.sh gsbstrc.seq "Layer 1"
The output lists all the grids associated with the specified layer as
well as the block with which each grid is associated:
Layer 1 grid names for the following blocks
BLOCK: Block1 GRID: Block1_Layer_1.2grd
BLOCK: Block2 GRID: Block2_Layer_1.2grd
BLOCK: Block3 GRID: Block3_Layer_1.2grd
BLOCK: Block4 GRID: Block4_Layer_1.2grd
BLOCK: Block5 GRID: Block5_Layer_1.2grd
BLOCK: Block 6 GRID: Block_6_Layer_1.2grd
BLOCK: Block 7 GRID: Block_7_Layer_1.2grd
The next step is to create the formula. If the data set (e.g., orig.dat)
you have is located in "Block5" and should have a Z-value 10 units above
"Layer 1", then the following formula would be used into the Formula Processor:
new.dat<x>=orig.dat<x>;
new.dat<y>=orig.dat<y>;
new.dat<z>=bakint(Block5_Layer_1.2grd,orig.dat<x>,
orig.dat<y>)
+ 10;
This formula creates a new file (new.dat) that has the same
X,Y locations as the original file but the new Z values are the result
of adding 10 to the back-interpolated value at each X,Y location on the
Layer 1 horizon.
C. Correcting any point
in a path that is closer than desired to a target horizon.
Required Elements:
sequence file with horizon grids
data set
Again, when the data set lies entirely within the same fault block, a simple
Formula Processor operation can be performed on the data set and the grid
for that horizon in that fault block.
If the data set (e.g., orig.dat) is located in Block5
and should be at least 10 Z units above Layer 1, then the following
formula can be used:
new.dat<x>=orig.dat<x>;
new.dat<y>=orig.dat<y>;
new.dat<z>=
lt(
(orig.dat<z>-bakint(Block5_Layer_1.2grd,orig.dat<x>,
orig.dat<y>)), 10,
(bakint(Block5_Layer_1.2grd,orig.dat<x>,orig.dat<y>)+10),
orig.dat<z>
);
This formula creates a new file (new.dat) that has the same
X,Y locations as the original file but the new Z values are either 10
plus the back-interpolated value at Layer 1 (if the original Z value is
less than 10 units above Layer 1) or the original Z-value (if it is more
than 10 units above Layer 1). (The less than (le) command says if "a"
is less than "b" return "c" otherwise return "d" (if "d" is present).)
D. Creating a series of points
a specified distance above a target horizon using a sequence file.
Required Elements:
sequence file with horizon grids
data set
script below (abovehorizon.sh)
Creating a series of points that are a specified distance above a faulted
target horizon (across the entire horizon) requires the following steps:
- Creating and running a script that performs the entire operation
using a sequence file
In example B, we showed the way to do this using points
that were all within a single fault block. In this example, we'll add a
group of points that lie within different fault blocks at a specified elevation
above a target horizon (i.e., any where above a faulted horizon). The following
script performs such a calculation if you have the following information:
sequence file name
input data name
horizon name
distance value
output data name
First copy the script into a file and make it executable:
========= start of script: abovehorizon.sh =================
#!/bin/sh
SEQFILE=$1
INPUTFILE=$2
HORIZON=$3
DISTANCE=$4
FINALOUT=$5
ev_fbsort -d $INPUTFILE $SEQFILE > TEMP3$$.dat
cat $1 | nawk -v HOR="$HORIZON" '
/FaultBlock/ {
split ($0, a, "\"");
fb = a[2];
gsub(/ /,"_",fb)
getline;
if ($0 !~ "Sequence") {
next;
}
else {
getline
while (!/}/) {
split ($0, b, "\"");
zn = b[2];
if (HOR ~ zn) {
gsub(/ /,"_",zn)
print $NF, zn, fb
}
getline
}
}
}' > TEMP$$
touch TEMP2$$
cat TEMP$$ | while read GRID HRZN BLK
do
ev_field -i TEMP3$$.dat -o ${BLK}_${HRZN}.dat
-r \
faultblock -s "$BLK"
# Get rid of files with no valid records.
FLAG=`cat ${BLK}_${HRZN}.dat | nawk '
/^#/ {next}
NF==0 {next}
NF>0 {count++}
count>0 {exit}
END {if (count > 0) {print "1"}}'`
if [ "x$FLAG" != "x1" ]
then
rm -f ${BLK}_${HRZN}.dat
continue
fi
ev_fpfp << EOF
${BLK}_${HRZN}.dat<BAKINT>=bakint("$GRID", \
${BLK}_${HRZN}.dat<x>, ${BLK}_${HRZN}.dat<y>);
${BLK}_${HRZN}.dat<z>=${BLK}_${HRZN}.dat<BAKINT>
\
+$DISTANCE;
EOF
echo "${BLK}_${HRZN}.dat" >> TEMP2$$
done
# put results back into one file
ev_datcombine -o $FINALOUT `cat TEMP2$$`
cat TEMP2$$ | while read FILE
do
rm -f $FILE
done
rm -f TEMP$$ TEMP2$$ TEMP3$$.dat
========= end of script: abovehorizon.sh ===================
The script can be run in the following manner:
abovehorizon.sh SEQUENCE_FILE INPUT_DAT HORIZON_NAME
\
DISTANCE OUTPUT_DAT
If the horizon name contains spaces, then the entire name must be surrounded
by double quotes. For example:
abovehorizon.sh gsbstrc.seq well1.dat "Layer 3" 20
junk.dat
The output file will have a Z value that is the specified distance above
the target horizon (in this case, 20 Z units), regardless of in which
fault block the input point lies. The X,Y locations in the output file
are identical to those in the input file.
Note: As with all calculations, some extreme data sets may
create anomalous results so all results should be checked for validity.
[Home]
[Corporate]
[Events & News]
[EarthVision] [Support]
[Services] [Contact
Us]
© 1999-2007 Dynamic Graphics, Inc. All
Rights Reserved. Legal Notices.
See Legal Notices for appropriate copyright trademark legend.
Feedback: webmaster@dgi.com
Last updated: March 22, 2007
|