Support Services Corporate Home EarthVision Events
 
FAQs


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:
  1. Determining the names of the top and bottom horizons
  2. Creating a script to calculate the distance
  3. 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:
  1. Creating and running a script that identifies the name of the grid that represents the surface in the desired fault block
  2. 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:
  1. 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