Source code for well_profile.create_trajectory

from .equations import *
from numpy import arange
from math import degrees
from .well import Well, define_section


[docs]def get(mdt, profile='V', build_angle=1, kop=0, eob=0, sod=0, eod=0, kop2=0, eob2=0, **kwargs): """ Generate a wellpath. Parameters ---------- mdt: num target depth, m or ft profile: str 'V' for vertical, 'J' for J-type, 'S' for S-type, 'H1' for Horizontal single curve and 'H2' for Horizontal double curve build_angle: num building angle, ° kop: num kick-off point, m or ft eob: num end of build, m or ft sod: num start of drop, m or ft eod: num end of drop, m or ft kop2: num kick-off point 2, m or ft eob2: num end of build 2, m or ft Keyword Args ------------ points: int number of points set_start: dict, None set initial point in m {'north': 0, 'east': 0}. change_azimuth: float, int, None add specific degrees to azimuth values along the entire well. set_info: dict, None dict, {'dlsResolution', 'wellType': 'onshore'|'offshore', 'units': 'metric'|'english'}. Returns ------- well: well object A wellpath object with 3D position """ # Settings params = {'points': 100, 'set_start': None, 'change_azimuth': None, 'set_info': None, 'ndigits': 2} for key, value in kwargs.items(): params[key] = value set_start = params['set_start'] change_azimuth = params['change_azimuth'] set_info = params['set_info'] info = {'dlsResolution': 30, 'wellType': 'offshore', 'units': 'metric'} initial_point = {'north': 0, 'east': 0, 'depth': 0} if isinstance(set_info, dict): for param in set_info: # changing default values if param in info: info[param] = set_info[param] if isinstance(set_start, dict): for x in set_start: # changing default values if x in initial_point: initial_point[x] = set_start[x] md = list(arange(0, mdt + 1, 1)) # Measured Depth from RKB, m depth_step = md[1] if profile == 'V': # Vertical well tvd, north, east, inc, az = vertical_section(profile, md, kop, depth_step) elif profile == 'J': # J-type well tvd, north, east, inc, az = create_j_well(mdt, md, kop, eob, build_angle, depth_step) elif profile == 'S': # S-type well tvd, north, east, inc, az = create_s_well(mdt, md, kop, eob, sod, eod, build_angle, depth_step) elif profile == 'H1': # Horizontal single-curve well tvd, north, east, inc, az = create_h1_well(mdt, md, kop, eob, depth_step) else: # Horizontal double-curve well tvd, north, east, inc, az = create_h2_well(mdt, md, kop, eob, kop2, eob2, build_angle, depth_step) if change_azimuth is not None: az, north_new, east_new = mod_azimuth(change_azimuth, az, north, east) # CREATING TRAJECTORY POINTS trajectory = [{'md': 0, 'inc': 0, 'azi': 0, 'dl': 0, 'tvd': 0, 'sectionType': 'vertical'}] trajectory[-1].update(initial_point) for idx, md in enumerate(md): if idx > 0: dogleg = calc_dogleg(inc[idx - 1], inc[idx], az[idx - 1], az[idx]) point = {'md': md, 'inc': inc[idx], 'azi': az[idx], 'north': calc_north(trajectory[-1]['north'], trajectory[-1]['md'], md, trajectory[-1]['inc'], inc[idx], trajectory[-1]['azi'], az[idx], dogleg), 'east': calc_east(trajectory[-1]['east'], trajectory[-1]['md'], md, trajectory[-1]['inc'], inc[idx], trajectory[-1]['azi'], az[idx], dogleg), 'tvd': calc_tvd(trajectory[-1]['tvd'], trajectory[-1]['md'], md, trajectory[-1]['inc'], inc[idx], dogleg), 'dl': degrees(dogleg) } point['sectionType'] = define_section(point, trajectory[-1]) trajectory.append(point) return Well({'trajectory': trajectory, 'info': info})
def vertical_section(profile, md, kop, depth_step): if profile == 'V': tvd = md else: tvd = md[:round(kop / depth_step) + 1] # True Vertical Depth from RKB, m north = [0] * len(tvd) # x axis east = [0] * len(tvd) # x axis inclination = [0.0] * len(tvd) azimuth = [0] * len(tvd) return tvd, north, east, inclination, azimuth def create_s_well(mdt, md, kop, eob, sod, eod, build_angle, depth_step): # Vertical section tvd, north, east, inclination, azimuth = vertical_section('S', md, kop, depth_step) # Build section s = depth_step theta_delta = radians(build_angle) / round((eob - kop) / depth_step) theta = theta_delta r = s / theta z_displacement = (r * sin(theta)) tvd.append(round(tvd[-1] + z_displacement, 2)) z_count = z_displacement hz_displacement = r * (1 - cos(theta)) north.append(round(north[-1] + hz_displacement, 2)) east.append(0) inclination.append(degrees(theta)) azimuth.append(0) for x in range(round((eob - kop) / depth_step) - 1): theta += theta_delta inclination.append(degrees(theta)) z_displacement = (r * sin(theta)) - z_count tvd.append(round(tvd[-1] + z_displacement, 2)) z_count += z_displacement hz_displacement = r * (1 - cos(theta)) - north[-1] north.append(round(north[-1] + hz_displacement, 2)) east.append(0) azimuth.append(0) # Tangent section z_displacement = (depth_step * cos(radians(build_angle))) hz_displacement = (depth_step * sin(radians(build_angle))) for x in range(round((sod - eob) / depth_step)): tvd.append(round(tvd[-1] + z_displacement, 2)) north.append(round(north[-1] + hz_displacement, 2)) east.append(0) inclination.append(inclination[-1]) azimuth.append(0) # Drop section s = depth_step points_drop = round((eod - sod) / depth_step) theta_delta = radians(build_angle) / points_drop theta = radians(build_angle) r = s / theta_delta z_checkpoint = tvd[-1] hz_checkpoint = north[-1] for x in range(points_drop): z_displacement = r * (sin(theta) - sin(theta - (theta_delta * (x + 1)))) tvd.append(round(z_checkpoint + z_displacement, 2)) hz_displacement = r * (1 - cos(theta)) - r * (1 - cos(theta - (theta_delta * (x + 1)))) north.append(round(hz_checkpoint + hz_displacement, 2)) east.append(0) inclination.append(inclination[-1] - degrees(theta_delta)) azimuth.append(0) # Vertical section for x in range(round((mdt - eod) / depth_step)): tvd.append(round(tvd[-1] + depth_step, 2)) north.append(north[-1]) # x axis east.append(0) inclination.append(0) azimuth.append(0) return tvd, north, east, inclination, azimuth def create_j_well(mdt, md, kop, eob, build_angle, depth_step): # Vertical section tvd, north, east, inclination, azimuth = vertical_section('J', md, kop, depth_step) # Build section s = depth_step theta_delta = radians(build_angle / round((eob - kop) / depth_step)) theta = theta_delta r = s / theta z_vertical = tvd[-1] z_displacement = (r * sin(theta)) tvd.append(round(tvd[-1] + z_displacement, 2)) hz_displacement = r * (1 - cos(theta)) north.append(round(north[-1] + hz_displacement, 2)) east.append(0) inclination.append(degrees(theta)) azimuth.append(0) for x in range(round((eob - kop) / depth_step) - 1): theta += theta_delta inclination.append(degrees(theta)) z_displacement = (r * sin(theta)) tvd.append(round(z_vertical + z_displacement, 2)) hz_displacement = r * (1 - cos(theta)) - north[-1] north.append(round(north[-1] + hz_displacement, 2)) east.append(0) azimuth.append(0) # Tangent section z_displacement = (depth_step * cos(radians(build_angle))) hz_displacement = (depth_step * sin(radians(build_angle))) for x in range(round((mdt - eob) / depth_step)): tvd.append(round(tvd[-1] + z_displacement, 2)) north.append(round(north[-1] + hz_displacement, 2)) east.append(0) inclination.append(inclination[-1]) azimuth.append(0) return tvd, north, east, inclination, azimuth def create_h1_well(mdt, md, kop, eob, depth_step): # Vertical section tvd, north, east, inclination, azimuth = vertical_section('H1', md, kop, depth_step) # Build section s = depth_step theta_delta = radians(90) / round((eob - kop) / depth_step) theta = theta_delta r = s / theta z_displacement = (r * sin(theta)) tvd.append(round(tvd[-1] + z_displacement, 2)) z_count = z_displacement hz_displacement = r * (1 - cos(theta)) north.append(round(north[-1] + hz_displacement, 2)) east.append(0) inclination.append(degrees(theta)) azimuth.append(0) for x in range(round((eob - kop) / depth_step) - 1): theta += theta_delta z_displacement = (r * sin(theta)) - z_count tvd.append(round(tvd[-1] + z_displacement, 2)) z_count += z_displacement hz_displacement = r * (1 - cos(theta)) - north[-1] inclination.append(degrees(theta)) north.append(round(north[-1] + hz_displacement, 2)) east.append(0) azimuth.append(0) # Horizontal section for x in range(round((mdt - eob) / depth_step)): tvd.append(tvd[-1]) north.append(north[-1] + depth_step) east.append(0) inclination.append(90) azimuth.append(0) return tvd, north, east, inclination, azimuth def create_h2_well(mdt, md, kop, eob, kop2, eob2, build_angle, depth_step): # Vertical section tvd, north, east, inclination, azimuth = vertical_section('H2', md, kop, depth_step) # Build section s = depth_step theta_delta = radians(build_angle / round((eob - kop) / depth_step)) theta = theta_delta r = s / theta z_displacement = (r * sin(theta)) tvd.append(round(tvd[-1] + z_displacement, 2)) z_count = z_displacement hz_displacement = r * (1 - cos(theta)) north.append(round(north[-1] + hz_displacement, 2)) east.append(0) inclination.append(degrees(theta)) azimuth.append(0) for x in range(round((eob - kop) / depth_step) - 1): theta = theta + theta_delta z_displacement = (r * sin(theta)) - z_count tvd.append(round(tvd[-1] + z_displacement, 2)) z_count += z_displacement hz_displacement = r * (1 - cos(theta)) - north[-1] inclination.append(degrees(theta)) north.append(round(north[-1] + hz_displacement, 2)) east.append(0) azimuth.append(0) # Tangent section z_displacement = (depth_step * cos(radians(build_angle))) hz_displacement = (depth_step * sin(radians(build_angle))) for x in range(round((kop2 - eob) / depth_step)): tvd.append(round(tvd[-1] + z_displacement, 2)) inclination.append(inclination[-1]) north.append(round(north[-1] + hz_displacement, 2)) east.append(0) azimuth.append(0) # Build section 2 s = depth_step build_angle = 90 - build_angle points_drop = round((eob2 - kop2) / depth_step) theta_delta = radians(build_angle) / points_drop theta = radians(build_angle) r = s / theta_delta z_checkpoint = tvd[-1] hz_checkpoint = north[-1] for x in range(points_drop): hz_displacement = r * (sin(theta) - sin(theta - (theta_delta * (x + 1)))) north.append(round(hz_checkpoint + hz_displacement, 2)) inclination.append(inclination[-1] + degrees(theta_delta)) east.append(0) azimuth.append(0) z_displacement = r * (1 - cos(theta)) - r * (1 - cos(theta - (theta_delta * (x + 1)))) tvd.append(round(z_checkpoint + z_displacement, 2)) # Horizontal section for x in range(round((mdt - eob2) / depth_step)): tvd.append(tvd[-1]) north.append(north[-1] + depth_step) inclination.append(inclination[-1]) east.append(0) azimuth.append(0) return tvd, north, east, inclination, azimuth def mod_azimuth(change_azimuth, azimuth_new, north_new, east_new): for a in range(len(azimuth_new)): azimuth_new[a] += change_azimuth if change_azimuth <= 90: east_new[a] = north_new[a] * sin(radians(change_azimuth)) north_new[a] *= cos(radians(change_azimuth)) elif 90 < change_azimuth <= 180: angle = change_azimuth - 90 east_new[a] = north_new[a] * round(cos(radians(angle)), 3) north_new[a] *= - sin(radians(angle)) elif 180 < change_azimuth <= 270: angle = change_azimuth - 180 east_new[a] = - north_new[a] * round(sin(radians(angle)), 3) north_new[a] *= - cos(radians(angle)) else: angle = change_azimuth - 270 east_new[a] = - north_new[a] * round(cos(radians(angle)), 3) north_new[a] *= sin(radians(angle)) return azimuth_new, north_new, east_new