{"id":48496384,"url":"https://github.com/cog-imperial/drill-scheduling","last_synced_at":"2026-04-07T12:30:38.283Z","repository":{"id":94599092,"uuid":"321943250","full_name":"cog-imperial/drill-scheduling","owner":"cog-imperial","description":"Pyomo implementation of a drill scheduling case study","archived":false,"fork":false,"pushed_at":"2021-03-09T10:33:16.000Z","size":38,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-10T13:09:17.786Z","etag":null,"topics":["optimization","pyomo","scheduling"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cog-imperial.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-12-16T10:13:14.000Z","updated_at":"2022-07-10T22:06:56.000Z","dependencies_parsed_at":"2023-07-28T17:15:52.864Z","dependency_job_id":null,"html_url":"https://github.com/cog-imperial/drill-scheduling","commit_stats":{"total_commits":10,"total_committers":2,"mean_commits":5.0,"dds":"0.19999999999999996","last_synced_commit":"c070adde1b9e8eacbe333a570cf1fc5e480f2f32"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cog-imperial/drill-scheduling","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cog-imperial%2Fdrill-scheduling","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cog-imperial%2Fdrill-scheduling/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cog-imperial%2Fdrill-scheduling/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cog-imperial%2Fdrill-scheduling/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cog-imperial","download_url":"https://codeload.github.com/cog-imperial/drill-scheduling/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cog-imperial%2Fdrill-scheduling/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31513375,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["optimization","pyomo","scheduling"],"created_at":"2026-04-07T12:30:37.654Z","updated_at":"2026-04-07T12:30:38.275Z","avatar_url":"https://github.com/cog-imperial.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Background\n:copyright: 2021, Johannes Wiebe. Refer to [License](LICENSE).\n\nThis repository contains an implementation of the drill scheduling problem\noutlined in Section 3.2 of [A robust approach to warped Gaussian process-constrained optimization](https://arxiv.org/abs/2006.08222).\n\nIf you use this work, please cite our paper:\n\n    @misc{Wiebe2020robust,\n          title={A robust approach to warped Gaussian process-constrained optimization}, \n          author={Johannes Wiebe and Inês Cecílio and Jonathan Dunlop and Ruth Misener},\n          year={2020},\n          eprint={2006.08222},\n          archivePrefix={arXiv},\n          primaryClass={math.OC}\n    }\n\nThe drill scheduling problem is an optimization problem which attempts to\nminimize the total completion time of drilling a well. It considers:\n\n1. The time spent drilling\n2. The time spent doing maintenance on the Positive Displacement Motor (PDM)\n\nThe solution of the problem is a schedule of drill parameters weight on bit W\nand rotational speed N, as illustrated below:\n\n![](drilling.png)\n\nThe relationship between the PDM's rate of degradation and differential\npressure across the PDM, which depends on the drill parameters, is only known\nin form of expensive simulations and experiments. Our approach to this problem\ntrains a [Gaussian Process](https://en.wikipedia.org/wiki/Gaussian_process)\nbased on a small data set for this relationship.\n\nFor a detailed description of the problem and the optimization model, please\nlook at Section 3.2 of [our paper](https://arxiv.org/abs/2006.08222).\n\n# Requirements\n\nThe optimization model is implemented in [Pyomo](http://www.pyomo.org/). In\norder to use Gaussian Processes with Pyomo we use [ROGP](https://github.com/johwiebe/rogp).\nTo install ROGP, run:\n\n    python -m pip install git+https://github.com/johwiebe/rogp.git\n\nThis will also install Pyomo. Using Pyomo to solve optimization problems also\nrequires a suitable solver to be installed. We use\n[Ipopt](https://github.com/coin-or/Ipopt).\n\n# Usage\n\nRun `example.py` for a full example in action.\n\n## Setting up the drill-string\n\nIn this simplified model, the drill string consists of the bit and PDM.\nSetting up the bit just requires two parameters, the bit radius and the ratio\nof inner to outer bit radius:\n\n    # Bit\n    bit = tools.Bit(100, 0)\n\nThe model of the PDM consists of three components: a function modeling motor\nRPM vs differential pressure, a function modeling torque vs differential\npressure, and a function modeling rate of degradation vs differential\npressures. Details of the model can be found in Section 3.2 and Appendix D of\n[our paper](https://arxiv.org/abs/2006.08222).\n\nWe model the RPM and torque curves as quadratics:\n\n    # Motor curves\n    rpmcurve = curves.Quadratic(np.array([[0., 100.],\n                                          [1400., 60.],\n                                          [2500., 0.]]))\n    torquecurve = curves.Quadratic(np.array([[0., 0.],\n                                             [1400., 3.5],\n                                             [2500., 5.0]])),\n\nand the degradation curve using a (warped) Gaussian Process:\n\n    # Motor degradation curve\n    data = np.load('gp_data.npy')\n    x, y = data[:,0,None], data[:,1,None]\n    failurecurve = curves.WarpedGP(x, y, warping_terms=2)\n\nThe final steps then are to define the PDM, drill string and a cost function\nfor maintenance:\n\n    # PDM\n    pdm = tools.PDM(rpmcurve, torquecurve, failurecurve, initial_degradation, 1/1500/25)\n\n    # Drill string\n    drillstring = tools.DrillString(pdm, bit)\n\n    # Cost function maintenance\n    cost_maint = curves.Linear(np.array([[0., 4.],\n                                         [4000., 20.]]))\n\n## Setting up the geology\n    \nWe use a simple geology consisting of two types of rocks which alternate. Rock\ntypes are defined using a set of six parameters:\n\n    rock1 = geology.Rock(278, 330, 125, 0.48, 157, 0.98)\n    rock2 = geology.Rock(315, 68.6, 50, 0.93, 33, 0.65)\n\nThe geology is defined by the depths at which a new rock type begins:\n\n    geo = geology.Geology({0: rock2,\n                           100: rock1,\n                           200: rock2,\n                           400: rock1,\n                           550: rock2,\n                           800: rock1,\n                           1800: rock2,\n                           2000: rock1,\n                           2500: rock2,\n                           2600: rock1})\n\n## Building and solving the model:\n    \nA deterministic model is defined using the `Deterministic` class:\n\n    scheduler = sc.Deterministic(geo, drillstring, cost_maint, xfin=3500)\n\nA model using the Wolfe Duality based reformulation described in our paper can\nbe defined using the `Wolfe` class:\n\n    scheduler = sc.Wolfe(geo, drillstring, cost_maint, xfin=3500, alpha=0.95)\n\nTo solve the model need to either choose the enumeration algorithm, or one of\nthe heuristics described in Section 3.2.2 of our paper:\n\n    # Enumeration\n    algo = algorithms.enum\n\n    # Boundary heuristic\n    algo = algorithms.boundary_heuristic\n\n    # No-degradation heuristic\n    algo = algorithms.no_degradation_start_heuristic\n\nFinally, build and solve the model using:\n\n    scheduler.build()\n    scheduler, obj = algo(scheduler)\n\n# Acknowledgements\nThis work was funded by the Engineering \u0026 Physical Sciences Research Council\n(EPSRC) Center for Doctoral Training in High Performance Embedded and\nDistributed Systems (EP/L016796/1) and an EPSRC/Schlumberger CASE studentship\n(EP/R511961/1, voucher 17000145).\n\nAuthor: Johannes Wiebe\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcog-imperial%2Fdrill-scheduling","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcog-imperial%2Fdrill-scheduling","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcog-imperial%2Fdrill-scheduling/lists"}