Well Order Optimization

In this section we introduce the reader to preparing, launching and analyzing results of an optimization of well order in a drilling sequence for several planned wells. First, we formulate an example optimization problem and we explain the configuration files. Next, we show how to launch an optimization experiment and then we analyze the results:

Define optimization problem

We are interested in finding drilling sequence of several wells that maximizes a certain objective function over a certain set of geological scenarios and over a certain time period.

Optimization variables

Drilling priority values

We plan to drill 6 wells; 4 producers: A1, A2, A3, A4 and 2 injectors A5, A6. We choose the starting date for drilling to be 2022-09-03. We assume that the drilling rig continuously available without any interruptions. We also assume that it takes 120 days for each well to be drilled, completed and ready to operate. This means that the dates at which wells will be opened in the model are fixed and we only search for optimal opening order. See the Table: Initial drilling order for resulting drilling dates based on chosen starting date and drilling times.

Table: Initial drilling order

Dates

2023-01-01

2023-05-02

2023-08-31

2023-12-30

2024-04-29

2024-08-28

Wells

A1

A2

A3

A4

A5

A6

Priorities

0.6

0.55

0.5

0.45

0.4

0.35

Let’s assume, we want to start optimization with wells drilled in alphabetical order. We need to assign drilling priority value for each well. The higher the probability value the earlier the well will be drilled. This means, we need to choose the highest priority value for the first well (A1) and lowest priority for the last well (A6). See the Table: Initial drilling order for chosen well priority values. We recommend spacing priority values evenly. We also need to specify what standard deviation to use when randomizing priorities for perturbations. We recommend setting standard deviation to be equal to difference between the priority values (0.05 for the example in Table: Initial drilling order). For information on how to define a more complex time scheduling constraints with rig and slot availability, see relevant documentation section (Everest documentation)

Objective functions

Net present value (NPV)

A single objective function is utilized in this well trajectory optimization tutorial. The economic objective function is defined as Net Present Value (NPV) as follows:

\[J = \sum\limits_{k=1}^{K}\Bigg(\dfrac{\{[(q_{o,k}) \cdot r_{o} + (q_{g,k}) \cdot r_{g} - (q_{wp,k}) \cdot r_{wp}] - [(q_{wi,k}) \cdot r_{wi}]\} \cdot \Delta t_{k} - c_{k}}{(1+b)^{\frac{t_{k}}{\tau_{t}}}}\Bigg)\]

Where \(q_{o,k}\) is the oil production rate in \(\frac{Sm^3}{day}\), \(q_{g,k}\) is the gas production rate in \(\frac{Sm^3}{day}\), \(q_{wp,k}\) is the water production rate in \(\frac{Sm^3}{day}\), \(q_{wi,k}\) is the water injection rate in \(\frac{Sm^3}{day}\), \(r_o\) is the price of oil in \(\frac{$}{Sm^3}\), \(r_{wp}\) is the cost of water produced in \(\frac{$}{Sm^3}\), \(r_{wi}\) is the cost of water injected in \(\frac{$}{Sm^3}\), \({\Delta}t_k\) is the difference between consecutive time steps in days, \(c_k\) are the CAPEX costs, \(b\) is the discount factor expressed as a fraction per year, \(t_k\) is the cumulative time in days corresponding to time step \(k\), and \({\tau}_t\) is the reference time period for discounting, typically one year (365.24 days). The unit prices for oil production (\(r_o\)), gas production (\(r_g\)), water production (\(r_{wp}\)), and water injection (\(r_{wi}\)) as well as drilling costs can be defined in well_order/everest/input/prices.yml.

Simulation models

Drogon Reservoir Model

The Equinor Drogon model is a synthetic reservoir model designed for testing and demonstrating ensemble-based workflows, including uncertainty quantification and optimization in subsurface projects. It is publicly available on GitHub to facilitate reproducible research and training.

model zones

Drogon model: Average initial oil saturation across the ensemble.

The model contains four production wells (A1 to A4) and two water injection wells (A5 to A6). In this tutorial, the production and injection starts in September 2022 and is simulated until January 2030. The average oil saturation across the 100 geological realizations for September 2022 is shown in Drogon model: Average initial oil saturation across the ensemble.. The production wells A1 to A4 are located within the oil-bearing zone, while the injection wells A5 and A6 are placed below oil-water contact.

Prepare configuration

The downloaded material is already complete and ready to be launched, however it is still useful to understand how the defined problem was configured. Information related to initial guess, objective functions and the model needs to be specified in main EVEREST configuration file. After downloading tutorial files from Download Material this file will be located at well_order/everest/model/wellorder_experiment.yml.

Main configuration

The initial guess for EVEREST is located in the section controls in main configuration file. This is where we insert the initial priority values for each well:

controls:
  - name: well_order
    type: well_control
    min: 0
    max: 1
    perturbation_magnitude: 0.05
    variables:
      - {name: A1, initial_guess: 0.6}
      - {name: A2, initial_guess: 0.55}
      - {name: A3, initial_guess: 0.5}
      - {name: A4, initial_guess: 0.45}
      - {name: A5, initial_guess: 0.4}
      - {name: A6, initial_guess: 0.35}

At every iteration EVEREST will randomly perturb current best priority values and use this information to calculate the direction and step size to propose improved priority values (and therefore improved drilling order) for the next iteration. This means that we need to choose the size of the perturbation, see standard deviation input as perturbation_magnitude in the controls section. We also need to choose number of perturbations for each geological realization, see keyword perturbation_num in optimization section:

optimization:
  perturbation_num: 1

We also need to specify the name of the objective function in the objective_functions section. EVEREST will require file of the same name generated by one of the forward model jobs.

objective_functions:
  - name: npv

Configuration of forward jobs

For every set of priorities EVEREST needs to translate these priorities into drilling schedule, and then insert selected keyword template responsible for opening the well into simulation schedule file at the correct date. This is accomplished by a sequence of forward jobs, i.e.:

forward_model:
  - drill_planner -i wells.json -c input/drill_planner_config.yml -opt well_order.json -o wells.json
  - add_templates -i wells.json -c input/template_config.yml -o wells.json 
  - schmerge -i wells.json -s simulator/model/WELLORDER.SCH -o simulator/model/SCHEDULE_OPT.SCH
  - job: flow r{{eclbase}} --enable-tuning=true
    results:
      file_name: r{{eclbase}}
      type: summary
  - npv -s simulator/model/DROGON.UNSMRY -o npv -c input/prices.yml -i wells.json -sd 2023-01-01 -ed 2030-01-01

The drill_planner job will translate a set of priorities given by EVEREST into a drilling schedule, i.e. each well will be assigned a date according to drilling order at which to insert a keyword template. The start date and rig availability needs to be specified in the input file to the drill planner, i.e. well_order/everest/input/drill_planner_config.yaml:

start_date: 2022-09-03
end_date: 2030-01-01
rigs:
  - name: 'A'
    wells: ['A1', 'A2', 'A3', 'A4', 'A5', 'A6']

The add_templates job will assign a keyword template for each well. In case of drilling order optimization this template contains simulator specific keyword to open the well:

WELOPEN
  '{{ name }}' 'OPEN' /
/

where EVEREST will replace {{name}} with the name of the well. Finally the schmerge (schedule merge) forward job will take the input schedule template WELLORDER.SCH and insert the WELOPEN keyword for each well and the correct date. Then it will produce updated schedule file SCHEDULE_OPT.SCH which will be used by the reservoir simulator. The remaining two forward jobs:

  - job: flow r{{eclbase}} --enable-tuning=true
    results:
      file_name: r{{eclbase}}
      type: summary
  - npv -s simulator/model/DROGON.UNSMRY -o npv -c input/prices.yml -i wells.json -sd 2023-01-01 -ed 2030-01-01

are responsible for launching reservoir simulator and calculating NPV. The NPV input file well_order/everest/input/prices.yml contains economic input parameters such as unit prices for oil production, water production and injection, drilling costs, discount factor, etc. For more detailed information and examples regarding the forward models please refer to the EVEREST Documentation.

Simulation schedule template

Before the optimization, the schedule file for simulation needs to be adapted. For example, in case of optimization of drilling order, EVEREST will insert WELOPEN keyword for optimized wells. Therefore, if a different well order was defined in the schedule it needs to be removed. At the same time, wells need to have specified well controls in the beginning of the schedule with keywords such as WCONPROD or WCONINJE but the optimized wells need to have there SHUT status. See an example schedule template in downloaded material: well_order/simulator/wELLORDER.SCH. The updated schedule file by EVEREST can be seen in the simulation output directory defined in main EVEREST configuration file:

environment:
  simulation_folder: r{{configpath}}/../output/r{{case_name}}/simulation_output

Updated schedule files for two different perturbations can be open to see the differences.

Run EVEREST and analyze results

After downloading the tutorial files from Download Material and the reservoir model realizations from Drogon Reservoir Model we need to point EVEREST to the downloaded model realizations by changing the line:

definitions: 
  realization_folder: r{{configpath}}/../../../fmu-drogon-flow-files/realization-r{{realization}}/iter-0/eclipse

to the correct directory path.

Note

In addition we might want to change the name of the cluster scheduler. If no cluster support is present, then we can change the line to run all simulations locally, i.e., change lsf to local in line:

simulator:
  queue_system:
    name: lsf 

See also Everest documentation.

To launch EVEREST, we can execute the following command in the directory with configuration file:

everest run wellorder_experiment.yml

Note

The string r{{configpath}} will be interpreted asa directory path to the configuration file and the string r{{realization}} will be interpreted as integer number of the geological realization.

Note

For more information on command line interface of EVEREST type everest --help

Attention

Note that the optimization results may differ when launched on a different machine, python version or random seed due to random perturbations.

After optimization is finished we can take a look at the output directories defined in environment section of EVEREST configuration file:

environment:
  simulation_folder: r{{configpath}}/../output/r{{case_name}}/simulation_output
  output_folder: r{{configpath}}/../output/r{{case_name}}

In our case we can find optimization results in r{{configpath}}/../output/r{{case_name}}/optimization_output and reservoir simulation results in r{{configpath}}/../output/r{{case_name}}/simulation_output. The reservoir simulation results will be organized per batch and simulation index. This means that since we have 100 realizations, then directories which end with simulation_0 to simulation_99 represent current best drilling order and the remaining directories, i.e., simulation_100, simulation_101, simulation_102, etc. correspond to the randomly perturbed drilling order. The total number of simulations will therefore depend on the choice of number of perturbations in the main configuration file of EVEREST. In our case, we selected 1 perturbation for each geological realization therefore in total we should have 200 simulation directories at each iteration.

Note

Drilling order in batch 0 is the chosen initial drilling order.

Note

Depending on the choice of speculative option in optimization section, the calculations for current best solution and for the gradient might be split in multiple batches, see Everest documentation.

The Figure: Objective function over the iterations shows average objective function at the iterations of the optimization experiment (average NPV over all geological realizations). The increase in objective function value of $6.24e+07 was achieved by changing a drilling order from the initial guess.

../_images/wo_objectives.svg

Figure: Objective function over the iterations

../_images/wo_controls.svg

Figure: Initial and optimal priorities

The drilling order is defined by set of priority values. We can compare these values for the initial guess an optimal solution, see Figure: Initial and optimal priorities. Most notably, the priority value of the producer A4 and injector A5 increased placing them in front of producers A2 and A3. In addition, the priority values of injector A6 decreased, reinforcing its place at the end of the drilling sequnce, see Table: Initial and optimal drilling order.

Table: Initial and optimal drilling order

Dates

2023-01-01

2023-05-02

2023-08-31

2023-12-30

2024-04-29

2024-08-28

Initial order

A1

A2

A3

A4

A5

A6

Optimal order

A1

A4

A5

A2

A3

A6

In order to understand why the gain in NPV is achieved we can compare production data from the reservoir simulations for initial and optimal strategies. We notice that, by drilling producer and injector earlier, we achieved increased oil production in the two time periods in the beginning and also increasing total cumulative oil production at the end of the production life-cycle, see Figure: Field Oil Production Rate and Figure: Field Oil Production Total.

../_images/wo_FOPR.svg

Figure: Field Oil Production Rate

../_images/wo_FOPT.svg

Figure: Field Oil Production Total

While we increased total oil production, the total gas production has been slightly decreased, see Figure: Field Gas Production Total. It was a beneficial trade-off for the NPV.

../_images/wo_FGPT.svg

Figure: Field Gas Production Total

By drilling injectory earlier, the cumulative values for water production and water injection increased compared to intitial strategy, see Figure: Field Water Production Total and Figure: Field Water Injection Total. It was again a beneficial trade-off for the NPV.

../_images/wo_FWPT.svg

Figure: Field Water Production Total

../_images/wo_FWIT.svg

Figure: Field Water Injection Total

This concludes the drilling order tutorial. We encourage the reader to check other types of tutorials in the Experiments section.