def test_load_df(self): well = load( load( r'https://github.com/pro-well-plan/well_profile/raw/master/well_profile/tests/' r'trajectory1.xlsx').df()) run_assertions(self, well, 3790)
def test_load_from_df(self): df = pd.read_excel('trajectory1.xlsx') my_wp = wp.load(df) self.assertIsInstance(my_wp.zstep, int, msg='zstep is not an integer') self.assertEqual(my_wp.md[0], 0, msg='MD is not starting from 0') self.assertEqual(my_wp.zstep, len(my_wp.tvd), msg='wrong number of values in tvd') self.assertEqual(my_wp.zstep, len(my_wp.north), msg='wrong number of values in north') self.assertEqual(my_wp.zstep, len(my_wp.east), msg='wrong number of values in east') self.assertEqual(my_wp.zstep, len(my_wp.inclination), msg='wrong number of values in inclination') self.assertEqual(my_wp.zstep, len(my_wp.dogleg), msg='wrong number of values in dogleg') self.assertEqual(my_wp.zstep, len(my_wp.azimuth), msg='wrong number of values in azimuth') self.assertIsInstance(my_wp.deltaz, int, msg='grid length is not an integer')
def load_trajectory(): trajectory = None file_type = st.selectbox( "File format", ['excel', 'csv'], ) uploaded_file = st.file_uploader('Load file ', type=["xlsx", "csv"]) if uploaded_file: if file_type == 'excel': df = pd.read_excel(uploaded_file) else: df = pd.read_csv(uploaded_file) trajectory = wp.load(df) trajectory.md = [point['md'] for point in trajectory.trajectory] trajectory.tvd = [point['tvd'] for point in trajectory.trajectory] trajectory.inclination = [ point['inc'] for point in trajectory.trajectory ] trajectory.azimuth = [point['azi'] for point in trajectory.trajectory] return trajectory
def test_load_from_lists(self): data = [[0, 1, 2, 3, 4, 5], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 4, 5]] well = load(data, points=100) run_assertions(self, well, 5)
def test_load_from_df(self): df = pd.read_excel( r'https://github.com/pro-well-plan/well_profile/raw/master/well_profile/tests/' r'trajectory1.xlsx') well = load(df) run_assertions(self, well, 3790)
def test_load_initial(self): my_wp = wp.load('trajectory1.xlsx') my_wp_initial = my_wp.initial() self.assertIsInstance(my_wp, object, msg='main function is not returning an object') self.assertIsInstance(my_wp_initial, pd.DataFrame, msg='method is not returning a dataframe')
def test_load_initial(self): well = load( r'https://github.com/pro-well-plan/well_profile/raw/master/well_profile/tests/trajectory1.xlsx' ) well_initial = well._base_data self.assertIsInstance(well, object, msg='main function is not returning an object') self.assertIsInstance(well_initial, pd.DataFrame, msg='method is not returning a dataframe')
def add_trajectory(self, survey): trajectory = wp.load(survey, equidistant=False) idx = [ trajectory.trajectory.index(x) for x in trajectory.trajectory if self.top <= x['md'] <= self.shoe ] trajectory.md = [x['md'] - self.top for x in trajectory.trajectory][idx[0]:idx[-1] + 1] trajectory.tvd = [x['tvd'] - self.top for x in trajectory.trajectory][idx[0]:idx[-1] + 1] trajectory.inclination = [x['inc'] for x in trajectory.trajectory ][idx[0]:idx[-1] + 1] trajectory.azimuth = [x['azi'] for x in trajectory.trajectory ][idx[0]:idx[-1] + 1] trajectory.dls = [x['dls'] for x in trajectory.trajectory][idx[0]:idx[-1] + 1] self.trajectory = trajectory
def load_trajectory(): trajectory = None file_type = st.selectbox( "File format", ['excel', 'csv'], ) uploaded_file = st.file_uploader('Load file ', type=["xlsx", "csv"]) if uploaded_file: if file_type == 'excel': df = pd.read_excel(uploaded_file) else: df = pd.read_csv(uploaded_file) trajectory = wp.load(df) return trajectory
def test_load_from_dicts(self): data = [ { 'md': 0, 'tvd': 0, 'azimuth': 0, 'inclination': 0 }, { 'md': 1, 'tvd': 1, 'azimuth': 0, 'inclination': 0 }, { 'md': 2, 'tvd': 2, 'azimuth': 0, 'inclination': 0 }, { 'md': 3, 'tvd': 3, 'azimuth': 0, 'inclination': 0 }, { 'md': 4, 'tvd': 4, 'azimuth': 0, 'inclination': 0 }, { 'md': 5, 'tvd': 5, 'azimuth': 0, 'inclination': 0 }, ] well = load(data, points=100) run_assertions(self, well, 5)
def test_load_from_data(self): data = [ { 'md': 0, 'tvd': 0, 'azimuth': 0, 'inclination': 0 }, { 'md': 1, 'tvd': 1, 'azimuth': 0, 'inclination': 0 }, { 'md': 2, 'tvd': 2, 'azimuth': 0, 'inclination': 0 }, { 'md': 3, 'tvd': 3, 'azimuth': 0, 'inclination': 0 }, { 'md': 4, 'tvd': 4, 'azimuth': 0, 'inclination': 0 }, { 'md': 5, 'tvd': 5, 'azimuth': 0, 'inclination': 0 }, ] my_wp = load(data, cells_no=100) run_assertions(self, my_wp, 5)
def test_torque(self): well = load( r'https://github.com/pro-well-plan/well_profile/raw/master/well_profile/tests/trajectory1.xlsx' ) dimensions = {'pipe': {'od': 4.5, 'id': 4, 'shoe': 2200}, 'odAnn': 5} tnd = calc(well.trajectory, dimensions, case='all', torque_calc=True, wob=50, tbit=5) self.assertTrue('lowering' and 'static' and 'hoisting' in tnd.force) self.assertTrue(len(tnd.force['lowering']) > 0) self.assertTrue(len(tnd.force['static']) > 0) self.assertTrue(len(tnd.force['hoisting']) > 0) self.assertTrue('lowering' and 'static' and 'hoisting' in tnd.torque) self.assertTrue(len(tnd.torque['lowering']) > 0) self.assertTrue(len(tnd.torque['static']) > 0) self.assertTrue(len(tnd.torque['hoisting']) > 0)
def test_load_from_data(self): data = [{'md': 0, 'tvd': 0, 'azimuth': 0, 'inclination': 0}, {'md': 1, 'tvd': 1, 'azimuth': 0, 'inclination': 0}, {'md': 2, 'tvd': 2, 'azimuth': 0, 'inclination': 0}, {'md': 3, 'tvd': 3, 'azimuth': 0, 'inclination': 0}, {'md': 4, 'tvd': 4, 'azimuth': 0, 'inclination': 0}, {'md': 5, 'tvd': 5, 'azimuth': 0, 'inclination': 0}, ] my_wp = wp.load(data, grid_length=1) self.assertIsInstance(my_wp.zstep, int, msg='zstep is not an integer') self.assertEqual(my_wp.md[0], 0, msg='MD is not starting from 0') self.assertEqual(my_wp.md[-1], 5, msg='Target depth not reached') self.assertEqual(my_wp.zstep, len(my_wp.tvd), msg='wrong number of values in tvd') self.assertEqual(my_wp.zstep, len(my_wp.north), msg='wrong number of values in north') self.assertEqual(my_wp.zstep, len(my_wp.east), msg='wrong number of values in east') self.assertEqual(my_wp.zstep, len(my_wp.inclination), msg='wrong number of values in inclination') self.assertEqual(my_wp.zstep, len(my_wp.dogleg), msg='wrong number of values in dogleg') self.assertEqual(my_wp.zstep, len(my_wp.azimuth), msg='wrong number of values in azimuth') self.assertIsInstance(my_wp.deltaz, int, msg='grid length is not an integer')
def test_load_df(self): my_wp = wp.load('trajectory1.xlsx').df() self.assertIsInstance(my_wp, pd.DataFrame, msg='method is not returning a dataframe') self.assertEqual(len(my_wp.md), len(my_wp.tvd), msg='wrong number of values in tvd') self.assertEqual(len(my_wp.md), len(my_wp.north), msg='wrong number of values in north') self.assertEqual(len(my_wp.md), len(my_wp.east), msg='wrong number of values in east') self.assertEqual(len(my_wp.md), len(my_wp.inclination), msg='wrong number of values in inclination') self.assertEqual(len(my_wp.md), len(my_wp.azimuth), msg='wrong number of values in azimuth')
from unittest import TestCase import well_profile as wp trajectory = wp.load('trajectory1.xlsx') class TestMain(TestCase): def test_temp_time_drilling(self): from pwptemp.drilling import input, main tdata = input.data() well = input.set_well(tdata, trajectory) td = main.temp_time(2, well) self.assertEqual(len(td.tdsi), len(td.ta), len(td.tr)) self.assertEqual(len(td.tcsg), len(td.tsr), len(td.tfm)) self.assertEqual(td.time, 2) self.assertIsInstance(td.tdsi, list) self.assertIsInstance(td.ta, list) self.assertIsInstance(td.tr, list) self.assertIsInstance(td.tcsg, list) self.assertIsInstance(td.tsr, list) self.assertIsInstance(td.tfm, list) def test_temp_time_injection(self): from pwptemp.injection import input, main tdata = input.data() well = input.set_well(tdata, trajectory) td = main.temp_time(2, well) self.assertEqual(len(td.tft), len(td.ta), len(td.tr)) self.assertEqual(len(td.tc), len(td.tsr), len(td.tfm)) self.assertEqual(td.time, 2) self.assertIsInstance(td.tft, list)
def test_color(self): well = load( r'https://github.com/pro-well-plan/well_profile/raw/master/well_profile/tests/trajectory1.xlsx' ) well.plot(style={'color': 'dls'})
def test_size(self): well = load( r'https://github.com/pro-well-plan/well_profile/raw/master/well_profile/tests/trajectory1.xlsx' ) well.plot(style={'size': 5})
def test_load_from_excel(self): well = load( r'https://github.com/pro-well-plan/well_profile/raw/master/well_profile/tests/trajectory1.xlsx' ) run_assertions(self, well, 3790)
def test_dark_mode(self): well = load( r'https://github.com/pro-well-plan/well_profile/raw/master/well_profile/tests/trajectory1.xlsx' ) well.plot(style={'darkMode': True})
from unittest import TestCase import pwptemp.production as ptp import pwptemp.injection as pti import well_profile as wp trajectory = wp.load( r'https://github.com/pro-well-plan/well_profile/raw/master/well_profile/tests/trajectory1.xlsx', equidistant=True).trajectory class TestMain(TestCase): def test_temp_behavior(self): pass
from unittest import TestCase import well_profile as wp trajectory = wp.load( r'https://github.com/pro-well-plan/pwptemp/raw/master/pwptemp/tests/trajectory1.xlsx', equidistant=True) class TestMain(TestCase): def test_temp_time_injection(self): pass def test_temp_time_production(self): pass
def test_load_df(self): my_wp = load(load('trajectory1.xlsx').df()) run_assertions(self, my_wp, 3790)
def add_pwploads_app(): st.subheader('Load Cases APP') st.write( "This is a web based application to generate load cases along pipes." " This is part of the open source initiative by Pro Well Plan AS.") st.info( 'pwploads is a python package for load cases calculations in order to develop modern \ well designs easier and faster. New features are added as they are needed; ' 'suggestions and contributions of all kinds are very welcome.') c1, c2, c3, c4, c5 = st.columns(5) with c1: st.markdown( "[![Github](https://img.shields.io/badge/source-pwploads-green.svg?logo=github)]" "(https://github.com/pro-well-plan/pwploads)") with c2: st.markdown("[![PyPI version](https://badge.fury.io/py/pwploads.svg)]" "(https://badge.fury.io/py/pwploads)") with c3: st.markdown( "[![Documentation Status](https://readthedocs.org/projects/pwploads/badge/?version=latest)]" "(http://pwploads.readthedocs.io/?badge=latest)") with c4: st.markdown( "[![Build Status](https://www.travis-ci.org/pro-well-plan/pwploads.svg?branch=master)]" "(https://www.travis-ci.org/pro-well-plan/pwploads)") st.markdown('#### 1. Load the wellbore trajectory') file_type = st.selectbox("File format", ['excel', 'csv'], key='file_type') trajectory = None uploaded_file = st.file_uploader('Load well trajectory: ', type=["xlsx", "csv"]) if uploaded_file: if file_type == 'excel': df = pd.read_excel(uploaded_file) else: df = pd.read_csv(uploaded_file) trajectory = wp.load(df, equidistant=False, set_info={'units': 'metric'}) st.markdown('#### 2. Create a casing with the specifications you need') df = { 'pipe': { 'tension': 1.1, 'compression': 1.1, 'burst': 1.1, 'collapse': 1.1, 'triaxial': 1.25 }, 'connection': { 'tension': 1.0, 'compression': 1.0 } } pipe = { 'od': 8, 'id': 7.2, 'shoeDepth': 1500, 'tocMd': 1000, 'weight': 100, 'yield': 80000, 'top': 200, 'e': 29e6 } settings = { 'densities': { 'mud': 1.2, 'cement': 1.8, 'cementDisplacingFluid': 1.3, 'gasKick': 0.5, 'completionFluid': 1.8 }, 'tripping': { 'slidingFriction': 0.24, 'speed': 0.3, 'maxSpeedRatio': 1.5 }, 'production': { 'resPressure': 5800, 'resTvd': 2000, 'fluidDensity': 1.7, 'packerFluidDensity': 1.3, 'packerTvd': 1450, 'perforationsTvd': 1600, 'poisson': 0.3 }, 'forces': { 'overpull': 0, 'preloading': 0 }, 'testing': { 'cementingPressure': 4000 } } # Default Values grade = 'L-80' conn_compression = 0.6 conn_tension = 0.6 if st.checkbox('Set Casing Dimensions'): pipe['od'] = st.number_input('OD, [in]:', value=8.0, step=0.1) pipe['id'] = st.number_input('ID, [in]:', value=7.2, step=0.1) pipe['shoeDepth'] = st.number_input('Shoe depth, [m]:', value=1500, min_value=10, step=100) pipe['top'] = st.number_input('Top depth MD, [m]:', value=1500, min_value=10, step=100) if st.checkbox('Set Material Properties'): pipe['weight'] = st.number_input('Nominal weight, [kg/m]:', value=100, step=1) grade = st.selectbox("Steel grade:", [ 'H-40', 'J-55', 'K-55', 'M-65', 'N-80', 'L-80', 'C-90', 'R-95', 'T-95', 'C-110', 'P-110', 'Q-125' ], index=5) conn_compression = st.number_input( 'Connection compression strength, [%]:', value=60, step=1, min_value=0, max_value=100) / 100 conn_tension = st.number_input('Connection tension strength, [%]:', value=60, step=1, min_value=0, max_value=100) / 100 if st.checkbox('Set Design Factors'): df['pipe']['triaxial'] = st.number_input('Von Mises:', value=1.25, step=0.1) df['pipe']['burst'] = st.number_input('API - Burst:', value=1.1, step=0.1) df['pipe']['collapse'] = st.number_input('API - Collapse:', value=1.1, step=0.1) df['pipe']['tension'] = st.number_input('API - Tension:', value=1.3, step=0.1) df['pipe']['compression'] = st.number_input('API - Compression:', value=1.3, step=0.1) df['connection']['compression'] = st.number_input( 'Connection - Compression:', value=1.0, step=0.1) df['connection']['tension'] = st.number_input('Connection - Tension:', value=1.0, step=0.1) pipe['yield'] = int(grade[2:]) * 1000 casing = pld.Casing(pipe, conn_compression, conn_tension, df) st.markdown('#### 3. Set parameters') if st.checkbox('Set densities, sg'): settings['densities']['mud'] = st.number_input('Mud:', value=1.2, step=0.1) settings['densities']['cement'] = st.number_input('Cement:', value=1.8, step=0.1) settings['densities']['cementDisplacingFluid'] = st.number_input( 'Displacing fluid (cementing):', value=1.3, step=0.1) settings['densities']['gasKick'] = st.number_input('Gas kick:', value=0.5, step=0.1) settings['densities']['completionFluid'] = st.number_input( 'Completion fluid:', value=1.8, step=0.1) if st.checkbox('Set tripping parameters'): settings['tripping']['slidingFriction'] = st.number_input( 'Sliding friction factor:', value=0.24, step=0.01) settings['tripping']['speed'] = st.number_input( 'Sliding friction factor, m/s:', value=0.3, step=0.1) settings['tripping']['maxSpeedRatio'] = st.number_input( 'Max / Avg speed ratio:', value=1.5, step=0.1) if st.checkbox('Set production parameters'): settings['production']['resPressure'] = st.number_input( 'Reservoir pressure, psi:', value=5800, step=100) settings['production']['resTvd'] = st.number_input( 'Reservoir depth (tvd), m:', value=2000, step=100) settings['production']['fluidDensity'] = st.number_input( 'Production fluid density, sg:', value=1.7, step=0.1) settings['production']['packerFluidDensity'] = st.number_input( 'Packer fluid density, sg:', value=1.3, step=0.1) settings['production']['packerTvd'] = st.number_input( 'Packer depth (tvd), m:', value=1450, step=100) settings['production']['perforationsTvd'] = st.number_input( 'Depth (tvd) of perforations:', value=1600, step=100) if st.checkbox('Set additional forces'): settings['forces']['overpull'] = st.number_input('Overpull, kN:', value=0, step=10) settings['forces']['preloading'] = st.number_input('Preload, kN:', value=0, step=10) if st.checkbox('Set testing'): settings['testing']['cementingPressure'] = st.number_input( 'Cementing Pressure test, psi:', value=4000, step=100) plots = { 'Triaxial Envelope': 'vme', 'Load Profiles': 'pressureDiff', 'Safety Factors (Axial)': 'axial', 'Safety Factors (Burst)': 'burst', 'Safety Factors (Collapse)': 'collapse' } plot_type = st.selectbox("Generate Plot", ['None'] + list(plots.keys())) if plot_type != 'None': if trajectory is not None: casing.add_trajectory(trajectory.trajectory) casing.run_loads(settings) fig = casing.plot(plot_type=plots[plot_type]) st.plotly_chart(fig) else: st.warning('No trajectory loaded') st.write('More features will be added soon...')
def add_torque_drag_app(): st.subheader('Torque and Drag APP') st.write( "This is a web based application to calculate drag forces and torque along the well." " This is part of the open source initiative by Pro Well Plan AS.") st.info( 'torque_drag is a python package for Torque & Drag calculations. New features are \ added as they are needed; suggestions and contributions of all kinds are very welcome.' ) c1, c2, c3, c4, c5 = st.columns(5) with c1: st.markdown( "[![Github](https://img.shields.io/badge/source-torque_drag-green.svg?logo=github)]" "(https://github.com/pro-well-plan/torque_drag)") with c2: st.markdown( "[![PyPI version](https://badge.fury.io/py/torque-drag.svg)]" "(https://badge.fury.io/py/torque-drag)") file_type = st.selectbox("File format", ['excel', 'csv'], key='file_type') trajectory = None uploaded_file = st.file_uploader('Load well trajectory: ', type=["xlsx", "csv"]) if uploaded_file: if file_type == 'excel': df = pd.read_excel(uploaded_file) else: df = pd.read_csv(uploaded_file) trajectory = wp.load(df, units='metric') trajectory.md = [point['md'] for point in trajectory.trajectory] trajectory.tvd = [point['tvd'] for point in trajectory.trajectory] trajectory.inclination = [ point['inc'] for point in trajectory.trajectory ] trajectory.azimuth = [point['azi'] for point in trajectory.trajectory] # Set default parameters friction_factor = 0.24 od_pipe = 4.5 id_pipe = 4.0 od_annular = 5.0 length_pipe = 2000 rhof = 1.3 rhod = 7.8 wob = 0 tbit = 0 if st.checkbox('Set parameters:'): friction_factor = st.number_input('Friction Factor:', value=0.24, step=0.1) if st.checkbox('Pipe parameters:'): od_pipe = st.number_input('Pipe OD, [in]:', value=4.5, step=0.1) id_pipe = st.number_input('Pipe ID, [in]:', value=4.0, step=0.1) od_annular = st.number_input('Annular OD, [in]:', value=5.0, step=0.1) length_pipe = st.number_input('Pipe length, [m]:', value=2000, min_value=10, step=100) if st.checkbox('Densities:'): rhof = st.number_input('Fluid density, [sg]:', value=1.3, step=0.1) rhod = st.number_input('Pipe density, [sg]:', value=7.8, step=0.1) if st.checkbox('Operational parameters:'): wob = st.number_input('Weight on bit, [kN]:', value=0, step=1) tbit = st.number_input('Torque on bit, [kN*m]:', value=0, step=1) st.write('Plot:') plot_dg = st.checkbox('Drag force', value=True) plot_tq = st.checkbox('Torque') if trajectory is not None: dimensions = { 'pipe': { 'od': od_pipe, 'id': id_pipe, 'length': length_pipe, 'shoe': length_pipe }, 'odAnn': od_annular } densities = {'rhof': rhof, 'rhod': rhod} result = td.calc(trajectory.trajectory, dimensions, densities, case='all', torque_calc=True, wob=wob, tbit=tbit, fric=friction_factor) if plot_dg: fig = result.plot() st.plotly_chart(fig) if plot_tq: fig = result.plot(plot_case='Torque') st.plotly_chart(fig) else: st.warning('No data loaded')
def add_torque_drag_app(): st.subheader('Torque and Drag APP') st.write( "This is a web based application to calculate drag forces and torque along the well." " This is part of the open source initiative by Pro Well Plan AS.") st.info( 'torque_drag is a python package for Torque & Drag calculations. New features are \ added as they are needed; suggestions and contributions of all kinds are very welcome.' ) st.markdown('[source code]' '(https://github.com/pro-well-plan/torque_drag)') st.markdown('[python package]' '(https://pypi.org/project/torque_drag/)') st.markdown( '[About our Open Source initiative]' '(https://prowellplan.com/modern-drilling-organization/open-source-boosting-the-digital-transformation)' ) file_type = st.selectbox("File format", ['excel', 'csv'], key='file_type') trajectory = None uploaded_file = st.file_uploader('Load well trajectory: ', type=["xlsx", "csv"]) if uploaded_file: if file_type == 'excel': df = pd.read_excel(uploaded_file) else: df = pd.read_csv(uploaded_file) trajectory = wp.load(df, units='metric') # Set default parameters od_pipe = 4.5 id_pipe = 4.0 od_annular = 5.0 length_pipe = 2000 rhof = 1.3 rhod = 7.8 wob = 0 tbit = 0 if st.checkbox('Set parameters:'): if st.checkbox('Pipe parameters:'): od_pipe = st.number_input('Pipe OD, [in]:', value=4.5, step=0.1) id_pipe = st.number_input('Pipe ID, [in]:', value=4.0, step=0.1) od_annular = st.number_input('Annular OD, [in]:', value=5.0, step=0.1) length_pipe = st.number_input('Pipe length, [m]:', value=2000, min_value=10, step=100) if st.checkbox('Densities:'): rhof = st.number_input('Fluid density, [sg]:', value=1.3, step=0.1) rhod = st.number_input('Pipe density, [sg]:', value=7.8, step=0.1) if st.checkbox('Operational parameters:'): wob = st.number_input('Weight on bit, [kN]:', value=0, step=1) tbit = st.number_input('Torque on bit, [kN*m]:', value=0, step=1) st.write('Plot:') plot_dg = st.checkbox('Drag force', value=True) plot_tq = st.checkbox('Torque') if st.button('Generate plot'): if trajectory is not None: dimensions = { 'od_pipe': od_pipe, 'id_pipe': id_pipe, 'length_pipe': length_pipe, 'od_annular': od_annular } densities = {'rhof': rhof, 'rhod': rhod} result = td.calc(trajectory, dimensions, densities, case='all', torque_calc=True, wob=wob, tbit=tbit) if plot_dg: fig = result.plot() st.plotly_chart(fig) if plot_tq: fig = result.plot(plot_case='Torque') st.plotly_chart(fig) else: st.warning('No data loaded')
def add_well_profile_app(): st.subheader('WELLBORE 3D APP') st.write( "This is a web based application to create, manipulate and visualize 3D wellbore trajectory data," " based on well_profile. This is part of the open source initiative by Pro Well Plan AS." ) st.info( 'well_profile is a python package to generate or load wellbore profiles in 3D. Features are added \ as they are needed; suggestions and contributions of all kinds are very welcome.' ) st.markdown('[source code]' '(https://github.com/pro-well-plan/well_profile)') st.markdown('[python package]' '(https://pypi.org/project/well-profile/)') st.markdown( '[About our Open Source initiative]' '(https://prowellplan.com/modern-drilling-organization/open-source-boosting-the-digital-transformation)' ) building_preference = st.selectbox( 'Select the way to start:', ('Load existing trajectory', 'Create a new trajectory')) units = st.selectbox('Select the system of units', ('metric', 'english')) if units == 'metric': length_units = 'm' else: length_units = 'ft' if building_preference == 'Create a new trajectory': profile = st.selectbox( 'Select a well profile type', ('Vertical', 'J-type', 'S-type', 'Horizontal single curve', 'Horizontal double curve')) # Create a vertical well if profile == 'Vertical': profile = 'V' param_dict = set_parameters(profile, length_units) traj = wp.get(param_dict['mdt'], cells_no=param_dict['cells_no'], units=units, set_start=param_dict['start']) data_and_plot(traj) # Create a J-type well if profile == 'J-type': profile = 'J' param_dict = set_parameters(profile, length_units) traj = wp.get(param_dict['mdt'], cells_no=param_dict['cells_no'], profile=profile, build_angle=param_dict['build_angle'], kop=param_dict['kop'], eob=param_dict['eob'], units=units, set_start=param_dict['start']) data_and_plot(traj) # Create a S-type well if profile == 'S-type': profile = 'S' param_dict = set_parameters(profile, length_units) traj = wp.get(param_dict['mdt'], cells_no=param_dict['cells_no'], profile=profile, build_angle=param_dict['build_angle'], kop=param_dict['kop'], eob=param_dict['eob'], sod=param_dict['sod'], eod=param_dict['eod'], units=units, set_start=param_dict['start']) data_and_plot(traj) # Create a horizontal single curve well if profile == 'Horizontal single curve': profile = 'H1' param_dict = set_parameters(profile, length_units) traj = wp.get(param_dict['mdt'], cells_no=param_dict['cells_no'], profile=profile, kop=param_dict['kop'], eob=param_dict['eob'], units=units, set_start=param_dict['start']) data_and_plot(traj) # Create a horizontal double curve well if profile == 'Horizontal double curve': profile = 'H2' param_dict = set_parameters(profile, length_units) traj = wp.get(param_dict['mdt'], cells_no=param_dict['cells_no'], profile=profile, build_angle=param_dict['build_angle'], kop=param_dict['kop'], eob=param_dict['eob'], kop2=param_dict['kop2'], eob2=param_dict['eob2'], units=units, set_start=param_dict['start']) data_and_plot(traj) if building_preference == 'Load existing trajectory': st.set_option('deprecation.showfileUploaderEncoding', False) wells_no = st.number_input('Number of files:', step=1, value=1) wellbores_data = [] wellbores_names = [] for x in range(wells_no): st.write('_________________') well_name = st.text_input('Set name:', value='well ' + str(x + 1)) start = {'north': 0, 'east': 0} if st.checkbox('Set coordinates of initial point:', key='set_start' + str(x)): start_north = st.number_input("Initial point, North, " + length_units, value=0, step=1, key='initial_north' + str(x)) start_east = st.number_input("Initial point, East, " + length_units, value=0, step=1, key='initial_east' + str(x)) start = {'north': start_north, 'east': start_east} file_type = st.selectbox("File format", ['excel', 'csv'], key='file_type' + str(x)) uploaded_file = st.file_uploader('Load file ' + str(x + 1), type=["xlsx", "csv"]) if uploaded_file: if file_type == 'excel': df = pd.read_excel(uploaded_file) else: df = pd.read_csv(uploaded_file) trajectory = wp.load(df, units=units, set_start=start) wellbores_data.append(trajectory) wellbores_names.append(well_name) if st.checkbox("Show loaded data", value=False, key='raw_load' + str(x)): st.dataframe(df, width=1000) if st.checkbox("Show converted data", value=False, key='conv_load' + str(x)): st.dataframe(trajectory.df()) csv = trajectory.df().to_csv(index=False) b64 = base64.b64encode( csv.encode()).decode() # some strings link = f'<a href="data:file/csv;base64,{b64}" download="wellpath.csv">Download dataset</a>' st.markdown(link, unsafe_allow_html=True) if st.button('Generate 3D plot'): if len(wellbores_data) == 0: st.warning('No data loaded') else: fig = wellbores_data[0].plot(add_well=wellbores_data[1:], names=wellbores_names) st.plotly_chart(fig)
def add_pwploads_app(): st.subheader('Load Cases APP') st.write( "This is a web based application to generate load cases along pipes." " This is part of the open source initiative by Pro Well Plan AS.") st.info( 'pwploads is a python package for load cases calculations in order to develop modern \ well designs easier and faster. New features are added as they are needed; ' 'suggestions and contributions of all kinds are very welcome.') st.markdown('[source code]' '(https://github.com/pro-well-plan/pwploads)') st.markdown('[python package]' '(https://pypi.org/project/pwploads/)') st.markdown('[documentation]' '(https://pwploads.readthedocs.io/en/latest/)') st.markdown('[About our Open Source initiative]' '(https://prowellplan.com/modern-drilling-organization/' 'open-source-boosting-the-digital-transformation)') st.markdown('#### 1. Load the wellbore trajectory') file_type = st.selectbox("File format", ['excel', 'csv'], key='file_type') trajectory = None uploaded_file = st.file_uploader('Load well trajectory: ', type=["xlsx", "csv"]) if uploaded_file: if file_type == 'excel': df = pd.read_excel(uploaded_file) else: df = pd.read_csv(uploaded_file) trajectory = wp.load(df, units='metric') st.markdown('#### 2. Create a casing with the specifications you need') # Default Values od_pipe = 8.0 id_pipe = 7.2 length_pipe = 1500 nominal_weight = 100 grade = 'L-80' df_vme = 1.25 df_burst = 1.1 df_collapse = 1.1 df_tension = 1.3 df_compression = 1.3 p_test = 4000 f_ov = 0 specs = False f_ov_status = False p_test_status = False v_avg = 0.3 e = 464 fric = 0.24 a = 1.5 cement = False rho_cem = 1.8 if st.checkbox('Set Casing Dimensions'): od_pipe = st.number_input('OD, [in]:', value=8.0, step=0.1) id_pipe = st.number_input('ID, [in]:', value=7.2, step=0.1) length_pipe = st.number_input('Pipe length, [m]:', value=1500, min_value=10, step=100) if st.checkbox('Set Material Properties'): nominal_weight = st.number_input('Nominal weight, [kg/m]:', value=100, step=1) grade = st.selectbox("Steel grade:", [ 'H-40', 'J-55', 'K-55', 'M-65', 'N-80', 'L-80', 'C-90', 'R-95', 'T-95', 'C-110', 'P-110', 'Q-125' ], index=5) if st.checkbox('Set Design Factors'): df_vme = st.number_input('Von Mises:', value=1.25, step=0.1) df_burst = st.number_input('API - Burst:', value=1.1, step=0.1) df_collapse = st.number_input('API - Collapse:', value=1.1, step=0.1) df_tension = st.number_input('API - Tension:', value=1.3, step=0.1) df_compression = st.number_input('API - Compression:', value=1.3, step=0.1) casing = pld.Casing(od_pipe, id_pipe, length_pipe, nominal_weight, int(grade[2:]) * 1000, df_tension, df_compression, df_burst, df_collapse, df_vme) st.markdown('#### 3. Set fluid') fluids_no = st.number_input('Number of fluids:', step=1, value=1) delta_tvd = float(length_pipe / fluids_no) rho_list = [] tvd_list = [] for x in range(fluids_no): st.write(' - fluid ' + str(x + 1)) rho_f = st.number_input('Fluid density, sg:', value=1.2, step=0.1, key='fluid' + str(x)) rho_list.append(rho_f) tvd_f = st.number_input('Final Depth, m:', value=float(delta_tvd * (x + 1)), step=100.0, key='tvd' + str(x)) tvd_list.append(tvd_f) tvd_list = tvd_list[:-1] st.markdown('#### 4. Modify parameters for load cases') if st.checkbox('Running in hole'): specs = True if st.checkbox('Overpull'): f_ov_status = True specs = True if st.checkbox('Green Cement Pressure Test'): p_test_status = True cement = True if p_test_status: p_test = st.number_input('Testing pressure, psi:', value=4000, step=100) if f_ov_status: f_ov = st.number_input('Overpull force, kN:', value=0, step=10) if specs: v_avg = st.number_input('Average running speed, m/s:', value=0.3, step=0.1) e = st.number_input("Young's modulus, psi x10^6:", value=464, step=1) fric = st.number_input('Sliding friction factor:', value=0.24, step=0.01) a = st.number_input('Ratio max speed / avg speed:', value=1.5, step=0.1) if cement: rho_cem = st.number_input('Cement density, sg:', value=1.8, step=0.1) if st.button('Generate plot'): if trajectory is not None: casing.add_trajectory(trajectory) e *= 1e6 / 14.504 casing.overpull(tvd_fluid=tvd_list, rho_fluid=rho_list, v_avg=v_avg, e=e, fric=fric, a=a, f_ov=f_ov) casing.running(tvd_fluid=tvd_list, rho_fluid=rho_list, v_avg=v_avg, e=e, fric=fric, a=a) casing.green_cement(tvd_fluid_int=tvd_list, rho_fluid_int=rho_list, rho_cement=rho_cem, p_test=p_test) fig = casing.plot() st.plotly_chart(fig) else: st.warning('No trajectory loaded') st.write('More features will be added soon...')
def add_well_profile_app(): st.subheader('WELLBORE 3D APP') st.write( "This is a web based application to create, manipulate and visualize 3D wellbore trajectory data," " based on well_profile. This is part of the open source initiative by Pro Well Plan AS." ) st.info( 'well_profile is a python package to generate or load wellbore profiles in 3D. Features are added \ as they are needed; suggestions and contributions of all kinds are very welcome.' ) c1, c2, c3, c4, c5 = st.columns(5) with c1: st.markdown( "[![Github](https://img.shields.io/badge/source-well_profile-green.svg?logo=github)]" "(https://github.com/pro-well-plan/well_profile)") with c2: st.markdown( "[![PyPI version](https://badge.fury.io/py/well-profile.svg)]" "(https://badge.fury.io/py/well-profile)") with c3: st.markdown( "[![Documentation Status](https://readthedocs.org/projects/well_profile/badge/?version=latest)]" "(http://well_profile.readthedocs.io/?badge=latest)") with c4: st.markdown( "[![Build Status](https://www.travis-ci.org/pro-well-plan/well_profile.svg?branch=master)]" "(https://www.travis-ci.org/pro-well-plan/well_profile)") st.markdown( '<iframe src="https://ghbtns.com/github-btn.html?user=pro-well-plan&repo=well_profile&type=star&' 'count=true" frameborder="0" scrolling="0" width="160" height="25" title="GitHub"></iframe>', unsafe_allow_html=True) building_preference = st.selectbox( 'Select the way to start:', ('Load existing trajectory', 'Create shape-based trajectory', 'Create trajectory from 2 points')) if building_preference == 'Create trajectory from 2 points': st.markdown('### Set kick-off point:') kop_depth = st.number_input("tvd", value=100, step=10) st.markdown('### Set target point:') c1, c2, c3 = st.columns(3) with c1: target_north = st.number_input("north", value=500, step=10) with c2: target_east = st.number_input("east", value=800, step=10) with c3: target_depth = st.number_input("tvd", value=800, step=10) show_data, dark, color = settings() traj = wp.two_points({ 'kickoff': { 'north': 0, 'east': 0, 'tvd': kop_depth }, 'target': { 'north': target_north, 'east': target_east, 'tvd': target_depth } }) data_and_plot(traj, show_data, dark, color) if building_preference == 'Create shape-based trajectory': units = 'metric' length_units = 'm' profile = st.selectbox( 'Select a well profile type', ('Vertical', 'J-type', 'S-type', 'Horizontal single curve', 'Horizontal double curve')) show_data, dark, color = settings() # Create a vertical well if profile == 'Vertical': profile = 'V' param_dict = set_parameters(profile, length_units) traj = wp.get(param_dict['mdt'], points=100, set_info={'units': units}, set_start=param_dict['start']) data_and_plot(traj, show_data, dark, color) # Create a J-type well if profile == 'J-type': profile = 'J' param_dict = set_parameters(profile, length_units) traj = wp.get(param_dict['mdt'], points=100, profile=profile, build_angle=param_dict['build_angle'], kop=param_dict['kop'], eob=param_dict['eob'], set_info={'units': units}, set_start=param_dict['start']) data_and_plot(traj, show_data, dark, color) # Create a S-type well if profile == 'S-type': profile = 'S' param_dict = set_parameters(profile, length_units) traj = wp.get(param_dict['mdt'], points=100, profile=profile, build_angle=param_dict['build_angle'], kop=param_dict['kop'], eob=param_dict['eob'], sod=param_dict['sod'], eod=param_dict['eod'], set_info={'units': units}, set_start=param_dict['start']) data_and_plot(traj, show_data, dark, color) # Create a horizontal single curve well if profile == 'Horizontal single curve': profile = 'H1' param_dict = set_parameters(profile, length_units) traj = wp.get(param_dict['mdt'], profile=profile, kop=param_dict['kop'], eob=param_dict['eob'], set_info={'units': units}, set_start=param_dict['start']) data_and_plot(traj, show_data, dark, color) # Create a horizontal double curve well if profile == 'Horizontal double curve': profile = 'H2' param_dict = set_parameters(profile, length_units) traj = wp.get(param_dict['mdt'], points=100, profile=profile, build_angle=param_dict['build_angle'], kop=param_dict['kop'], eob=param_dict['eob'], kop2=param_dict['kop2'], eob2=param_dict['eob2'], set_info={'units': units}, set_start=param_dict['start']) data_and_plot(traj, show_data, dark, color) if building_preference == 'Load existing trajectory': st.set_option('deprecation.showfileUploaderEncoding', False) c1, c2 = st.columns(2) with c1: wells_no = st.number_input('Number of files:', step=1, value=1) wellbores_data = [] wellbores_names = [] with c2: units = st.selectbox('System of units', ('metric', 'english')) if units == 'metric': length_units = 'm' else: length_units = 'ft' for x in range(wells_no): st.write('_________________') c1, c2 = st.columns(2) with c1: well_name = st.text_input('Set name:', value='well ' + str(x + 1)) with c2: file_type = st.selectbox("File format", ['excel', 'csv'], key='file_type' + str(x)) start = {'north': 0, 'east': 0} uploaded_file = st.file_uploader('Load file ' + str(x + 1), type=["xlsx", "csv"]) if uploaded_file: if file_type == 'excel': df = pd.read_excel(uploaded_file) else: df = pd.read_csv(uploaded_file) if st.checkbox('Set initial point:', key='set_start' + str(x)): c1, c2 = st.columns(2) with c1: start_north = st.number_input("north, " + length_units, value=0, step=10, key='initial_north' + str(x)) with c2: start_east = st.number_input("east, " + length_units, value=0, step=10, key='initial_east' + str(x)) start = {'north': start_north, 'east': start_east} trajectory = wp.load(df, equidistant=False, set_info={'units': units}, set_start=start) wellbores_data.append(trajectory) wellbores_names.append(well_name) c1, c2 = st.columns(2) with c1: if st.checkbox("Show loaded data", value=False, key='rawLoad' + str(x)): st.dataframe(df, width=1000) with c2: if st.checkbox("Show converted data", value=False, key='convLoad' + str(x)): st.dataframe(trajectory.df()) csv = trajectory.df().to_csv(index=False) b64 = base64.b64encode( csv.encode()).decode() # some strings link = f'<a href="data:file/csv;base64,{b64}" download="wellpath.csv">Download dataset</a>' st.markdown(link, unsafe_allow_html=True) interp_pt = st.number_input( "Data at MD depth (" + length_units + ")", value=0.0, step=10.0, key='interp' + str(x), min_value=0.0, max_value=float(trajectory.trajectory[-1]['md'])) if interp_pt != 0: st.write(trajectory.get_point(interp_pt)) if len(wellbores_data) >= 1: st.write('-----------------') style = {'units': units} c1, c2, c3 = st.columns(3) with c1: st.write('') st.write('') st.write('') style['darkMode'] = st.checkbox("Dark Mode", value=False) with c2: plot_type = st.selectbox('Plot type:', ('3d', 'top', 'vs')) with c3: color = st.selectbox( 'Color by:', ('None', 'Dogleg Severity (dls)', 'Dogleg (dl)', 'Inclination (inc)', 'Azimuth (azi)', 'Measured Depth (md)', 'True Vertical Depth (tvd)')) color_data = { 'None': None, 'Dogleg Severity (dls)': 'dls', 'Dogleg (dl)': 'dl', 'Inclination (inc)': 'inc', 'Azimuth (azi)': 'azi', 'Measured Depth (md)': 'md', 'True Vertical Depth (tvd)': 'tvd' } style['color'] = color_data[color] style['size'] = 2 if color_data[color] is not None: style['size'] = st.slider('Marker size:', min_value=1, max_value=8, value=2, step=1) if len(wellbores_data) == 0: st.warning('No data loaded') else: if plot_type == 'vs': c1, c2 = st.columns(2) with c1: xaxis = st.selectbox('X axis:', ('md', 'tvd', 'north', 'east', 'dl', 'dls', 'inc', 'azi')) with c2: yaxis = st.selectbox('Y axis:', ('inc', 'azi', 'dl', 'dls', 'md', 'tvd', 'north', 'east')) else: xaxis = yaxis = None fig = wellbores_data[0].plot(plot_type=plot_type, x_axis=xaxis, y_axis=yaxis, add_well=wellbores_data[1:], names=wellbores_names, style=style) st.plotly_chart(fig)
def calc_temp(trajectory, casings=None, set_inputs=None, operation='drilling', time_steps=210, smooth=True, cells_no=None): """ Function to calculate the well temperature distribution during a specific operation at a certain time. Arguments: trajectory: wellbore trajectory excel|csv|dataframe|list casings: list of dictionaries with casings characteristics (od, id and depth) set_inputs: dictionary with parameters to set. operation: define operation type. ('drilling', 'circulating') time_steps: number of time steps to run calculations. smooth: smooth the temperature profiles. cells_no: (int) number of cells. If None -> keep same number of cells than trajectory Returns: Well temperature distribution object """ tdata = inputs_dict(casings) if set_inputs is not None: for x in set_inputs: # changing default values if x in tdata: tdata[x] = set_inputs[x] else: raise TypeError('%s is not a parameter' % x) if cells_no is not None: survey = wp.load(trajectory, points=cells_no).trajectory else: survey = wp.load(trajectory, equidistant=False).trajectory md_initial = tdata['water_depth'] md_final = survey[-1]['md'] well = set_well(tdata, survey, operation) time = [] rop_steps = [] depths = sorted([x[2] for x in well.casings]) if operation == 'drilling': prev_point = md_initial cummulative_time = [] for x in range(len(depths)): distance = depths[x] - prev_point time_section = distance / well.rop_list[x] time.append(time_section) cummulative_time.append(sum(time)) prev_point = depths[x] time.append((md_final - prev_point) / well.rop_list[-1]) cummulative_time.append(sum(time)) depths = list(depths) + [md_final] if depths[0] == 0: depths = depths[1:] time = time[1:] cummulative_time = cummulative_time[1:] tcirc = sum(time) * 3600 # drilling time, s for x in cummulative_time: rop_steps.append(round(x * 3600 / tcirc / time_steps)) else: tcirc = tdata['time'] * 3600 # circulating time, s time_step = tcirc / time_steps # seconds per time step log_temp_values(well, initial=True) # log initial temperature distribution well.delta_time = time_step time_n = time_step well.op = operation td = len(well.trajectory) - 1 for x in range(time_steps): if well.op == 'drilling': d = depths[0] rop = well.rop_list[0] t = time[0] * 3600 for y in range(len(time)): if time_n < sum(time[:y + 1]) * 3600: d = depths[y] if len(well.rop_list) > 1: rop = well.rop_list[y] t = sum(time[:y + 1]) * 3600 break bit_depth = d - rop / 3600 * (t - time_n) bit_position = [ cell for cell, point in enumerate(well.trajectory) if point['md'] <= bit_depth ][-1] td = bit_position if time_steps > 1: if td > 0: well = calc_temperature_distribution(well, time_step, td) well = define_temperatures(well, td) log_temp_values(well, time_n) if well.op == 'drilling': if x in range(len(rop_steps)): well.temperatures['in_pipe'] = well.temp_fm well.temperatures['pipe'] = well.temp_fm well.temperatures['annulus'] = well.temp_fm well.temperatures['casing'] = well.temp_fm well.temperatures['riser'] = well.temp_fm well.temperatures['sr'] = well.temp_fm for i in well.sections: for j in range(len(well.trajectory)): i[j]['temp'] = well.temp_fm[j] i[j]['temp_fm'] = well.temp_fm[j] well.time = time_n / 3600 time_n += time_step if smooth: smooth_results(well) additional_points(well) return well
def test_load_from_df(self): df = pd.read_excel('trajectory1.xlsx') my_wp = load(df) run_assertions(self, my_wp, 3790)