Skip to content

Commit

Permalink
Fix for straight hole conditions.
Browse files Browse the repository at this point in the history
In wells with straight hole sections where the angle between
subsequent survey stations is 0 degrees, a ZeroDivisionError occurred.

This issue was flagged in #54.
  • Loading branch information
Zabamund committed May 18, 2022
1 parent 95e00b7 commit f36ca15
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 40 deletions.
5 changes: 4 additions & 1 deletion wellpathpy/position_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,10 @@ def deviation(self):
d = np.linalg.norm(v1)
incs.append(i2)
azis.append(a2)
mds.append(d * alpha / np.sin(alpha))
if alpha == 0:
mds.append(d)
else:
mds.append(d * alpha / np.sin(alpha))
# The current lower station is the upper station in the next
# segment.
i1 = i2
Expand Down
7 changes: 7 additions & 0 deletions wellpathpy/test/fixtures/straight_dev_section.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
md,inc,azi
0,0,0
50,0,0
100,2,0
150,2,0
200,2,0
250,2,0
7 changes: 7 additions & 0 deletions wellpathpy/test/fixtures/straight_vert_section.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
md,inc,azi
0,0,0
190,0,0
222,0,0
360,0.3,256.5
390,0.2,124.8
419,0.4,114.3
60 changes: 60 additions & 0 deletions wellpathpy/test/test_calculations.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
# import test well data
well9 = np.loadtxt('./wellpathpy/test/fixtures/well9.csv', delimiter=",", skiprows=1)
well10 = np.loadtxt('./wellpathpy/test/fixtures/well10.csv', delimiter=",", skiprows=1)
straight_vert = np.loadtxt('./wellpathpy/test/fixtures/straight_vert_section.csv', delimiter=",", skiprows=1)
straight_deviated = np.loadtxt('./wellpathpy/test/fixtures/straight_dev_section.csv', delimiter=",", skiprows=1)

# get data series
well9_true_md_m = well9[:,0] * 0.3048 # converting feet to meters
well9_true_inc = well9[:,1]
Expand Down Expand Up @@ -196,3 +199,60 @@ def test_roundtrip(atol = 0.01):
np.testing.assert_allclose(pos.depth, well9_true_tvd_m, atol=1)
np.testing.assert_allclose(pos.northing, well9_true_northing, atol=1)
np.testing.assert_allclose(pos.easting, well9_true_easting, atol=1)

def test_roundtrip_vertical_straight_hole(atol = 0.01):
"""
This pretty much only tests the mincurve, but packed in the
deviation+position_log interface
For a vertical straight hole, the inclination stays 0, but
azimuth can rotate freely.
"""
md_m = straight_vert[:, 0] * 0.3048 # converting feet to meters
inc = straight_vert[:, 1]
azi = straight_vert[:, 2]
tvd_m = straight_vert[:, 0] * 0.3048 # converting feet to meters
easting = [0, 0, 0, 0, 0, 0]
northing = [0, 0, 0, 0, 0, 0]

# the hole is vertical
assert np.all(inc) == 0

dev = deviation(md_m, inc, azi)
pos = dev.minimum_curvature()
dev2 = pos.deviation()
np.testing.assert_allclose(dev.md, dev2.md, atol = atol)
np.testing.assert_allclose(dev.inc, dev2.inc, atol = atol)
np.testing.assert_allclose(dev.azi, dev2.azi, atol = atol)

pos.to_wellhead(surface_northing = 0.0, surface_easting = 0.0, inplace = True)
np.testing.assert_allclose(pos.depth, tvd_m, atol=1)
np.testing.assert_allclose(pos.northing, northing, atol=1)
np.testing.assert_allclose(pos.easting, easting, atol=1)

def test_roundtrip_deviated_straight_hole(atol = 0.01):
"""
This pretty much only tests the mincurve, but packed in the
deviation+position_log interface
For a deviated straight hole, MD should increase, but inc
and azi must remain constant.
"""
md_m = straight_deviated[:, 0]
inc = straight_deviated[:, 1]
azi = straight_deviated[:, 2]
tvd_m = np.array([0., 50., 99.989847, 149.959388, 199.928929, 249.898471])
easting = [0, 0, 0, 0, 0, 0]
northing = np.array([0., 0., 0.872576, 2.617551, 4.362526, 6.107501])

dev = deviation(md_m, inc, azi)
pos = dev.minimum_curvature()
dev2 = pos.deviation()
np.testing.assert_allclose(dev.md, dev2.md, atol = atol)
np.testing.assert_allclose(dev.inc, dev2.inc, atol = atol)
np.testing.assert_allclose(dev.azi, dev2.azi, atol = atol)

pos.to_wellhead(surface_northing = 0.0, surface_easting = 0.0, inplace = True)
np.testing.assert_allclose(pos.depth, tvd_m, atol=1)
np.testing.assert_allclose(pos.northing, northing, atol=1)
np.testing.assert_allclose(pos.easting, easting, atol=1)
39 changes: 0 additions & 39 deletions wellpathpy/test/test_position_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,42 +38,3 @@ def test_copy():
copy = original.copy()
original.depth += 10
np.testing.assert_equal([1,2,3,4], copy.depth)

def test_straight_down_segment_preserves_depth():
"""
When the well is straight down, the vertical depth and measured depth
should increase at the same rate.
"""
md = [0, 3, 7]
inc = [0, 0, 0]
azi = [0, 0, 0]

pos = deviation(md, inc, azi).minimum_curvature()
np.testing.assert_array_equal(md, pos.depth)
np.testing.assert_array_equal([0, 0, 0], pos.northing)
np.testing.assert_array_equal([0, 0, 0], pos.easting)

def test_straight_nonvertical_segment():
"""
The well has a constant inclination which means delta(md) > delta(vd), the
path is not straight down. This doesn't test for the path going back up.
"""
md = np.array([1, 3, 7])
inc = np.array([30, 30, 30])
azi = np.array([0, 0, 0])

pos = deviation(md, inc, azi).minimum_curvature()
delta_md = md[1:] - md[:-1]
delta_vd = pos.depth[1:] - pos.depth[:-1]
assert (delta_md > delta_vd).all()

@pytest.mark.xfail(strict = True)
def test_straight_hole():
md = np.array([0, 10, 20]).reshape(3, 1)
inc = azi = np.zeros((3, 1))
dev = deviation(md=md, inc=inc, azi=azi)
step = 10
depths = list(range(0, int(dev.md[-1]) + 10, step))
with np.errstate(invalid='raise'):
pos = dev.minimum_curvature().resample(depths=depths)
dev2 = pos.deviation()

0 comments on commit f36ca15

Please sign in to comment.