Contents
Simulate a large example using parts of SPE10
This example is a larger example demonstrating the solver on a medium size grid (66,000 cells) with a relatively large amount of time steps (100). This example will take some time, especially if MLDIVIDE is used as the elliptic solver. Be wary that increasing the number of layers may let the simulations take a very long time.
Furthermore, note that the 'solvefiADI' solver and especially the CPR preconditioner, uses direct indexing into sparse matrices. In MATLABs prior to release R2011a, this is relatively inefficient. Starting from 2011a however, the bottleneck of direct indexing has been largely removed.
mrstModule add ad-fi deckformat spe10 % Read and process file. current_dir = fileparts(mfilename('fullpath')); fn = fullfile(current_dir, 'SPE10-S3.DATA.txt'); deck = readEclipseDeck(fn); % The deck is given in field units, MRST uses metric. deck = convertDeckUnits(deck); % Create a special ADI fluid which can produce differentiated fluid % properties. fluid = initDeckADIFluid(deck); % The case includes gravity gravity on % The initial state is provided as a binary file. The initial state % contains a uniform mixture of water (.12) and oil (.88). % load initialState;
Set up permeability, grid and wells
We will simulate on the top 5 layers.
layers = 1:5; [G, W, rock] = SPE10_setup(layers); % SPE10 contains zero and extremely low porosities. For the purpose of this % tutorial, we will mask away these values. An alternative would be to set % these cells to inactive by using extractSubgrid and removing the % corresponding cells. low = 1e-4; rock.poro(rock.poro < low) = low;
Plot the permeability
clf; plotCellData(G, log10(rock.perm(:,1)));

Set up solution structures.
% The initial reservoir is at 6000 psi and is fully oil saturated. The well % solution gets its initial pressure from the bottom hole pressure values % provided. initSat = [0 1 0]; state0 = initResSol(G, 6000*psia, initSat); state0.wellSol = initWellSolLocal(W, state0); for i = 1:numel(W) state0.wellSol(i).pressure = W(i).val; % Set well sign if strcmpi(W(i).name(1), 'p') W(i).sign = -1; else W(i).sign = 1; end end % Set up a Water / Oil system using CPR preconditioner. Alternatively we % could have used a specialized elliptic solver using the option 'cprEllipticSolver' % to exploit the nature of the variables involving pressure. system = initADISystem({'Water', 'Oil'}, G, rock, fluid, 'cpr', true, 'cprRelTol', 2e-2); % If an alternative solver for the pressure subproblem was installed, it % could be added using % % system.nonlinear.cprEllipticSolver = @(A,b) solver(A,b) % % This can greatly speed up the solution process, as the default option % uses MATLABs direct solver @mldivide which is very expensive for a % preconditioner.
Simulate 1000 days of production and save iteration count and time
We provide the solver with time steps for roughly 1000 days of production. A few smaller steps are done to get better accuracy during the initial injection period. After this we do 10 day intervals to step rapidly through the schedule. While this converges at every time step, implicit solvers will still get improved accuracy by doing smaller time steps. Numerical diffusion can, for instance, be problematic when doing large time steps.
dt = [ 0.001*day; repmat( 0.1 *day, [ 5, 1]); repmat( 1 *day, [ 10, 1]); repmat(10 *day, [100, 1])]; nstep = numel(dt); states = cell(nstep,1); its = zeros(nstep,1); time = zeros(nstep,1); state = state0; for t = 1 : nstep fprintf('Step %d/%d: %.2f -> %.2f [days]\n\n', t, nstep, ... convertTo(sum(dt(1:t-1)), day), ... convertTo(sum(dt(1:t )), day)); timer = tic(); [state, it] = solvefiADI(state, dt(t), W, G, system); states{t} = state; its(t) = it; time(t) = toc(timer); fprintf('\n\n'); end
Step 1/116: 0.00 -> 0.00 [days] Step 2/116: 0.00 -> 0.10 [days] Step 3/116: 0.10 -> 0.20 [days] Step 4/116: 0.20 -> 0.30 [days] Step 5/116: 0.30 -> 0.40 [days] Step 6/116: 0.40 -> 0.50 [days] Step 7/116: 0.50 -> 1.50 [days] Step 8/116: 1.50 -> 2.50 [days] Step 9/116: 2.50 -> 3.50 [days] Step 10/116: 3.50 -> 4.50 [days] Step 11/116: 4.50 -> 5.50 [days] Step 12/116: 5.50 -> 6.50 [days] Step 13/116: 6.50 -> 7.50 [days] Step 14/116: 7.50 -> 8.50 [days] Step 15/116: 8.50 -> 9.50 [days] Step 16/116: 9.50 -> 10.50 [days] Step 17/116: 10.50 -> 20.50 [days] Warning: Non-linear solver did not converge, stopped by max iterations... Step 18/116: 20.50 -> 30.50 [days] Step 19/116: 30.50 -> 40.50 [days] Step 20/116: 40.50 -> 50.50 [days] Step 21/116: 50.50 -> 60.50 [days] Step 22/116: 60.50 -> 70.50 [days] Step 23/116: 70.50 -> 80.50 [days] Step 24/116: 80.50 -> 90.50 [days] Step 25/116: 90.50 -> 100.50 [days] Step 26/116: 100.50 -> 110.50 [days] Step 27/116: 110.50 -> 120.50 [days] Step 28/116: 120.50 -> 130.50 [days] Step 29/116: 130.50 -> 140.50 [days] Step 30/116: 140.50 -> 150.50 [days] Step 31/116: 150.50 -> 160.50 [days] Step 32/116: 160.50 -> 170.50 [days] Step 33/116: 170.50 -> 180.50 [days] Step 34/116: 180.50 -> 190.50 [days] Step 35/116: 190.50 -> 200.50 [days] Step 36/116: 200.50 -> 210.50 [days] Step 37/116: 210.50 -> 220.50 [days] Step 38/116: 220.50 -> 230.50 [days] Step 39/116: 230.50 -> 240.50 [days] Step 40/116: 240.50 -> 250.50 [days] Step 41/116: 250.50 -> 260.50 [days] Step 42/116: 260.50 -> 270.50 [days] Step 43/116: 270.50 -> 280.50 [days] Step 44/116: 280.50 -> 290.50 [days] Step 45/116: 290.50 -> 300.50 [days] Step 46/116: 300.50 -> 310.50 [days] Step 47/116: 310.50 -> 320.50 [days] Step 48/116: 320.50 -> 330.50 [days] Step 49/116: 330.50 -> 340.50 [days] Step 50/116: 340.50 -> 350.50 [days] Step 51/116: 350.50 -> 360.50 [days] Step 52/116: 360.50 -> 370.50 [days] Step 53/116: 370.50 -> 380.50 [days] Step 54/116: 380.50 -> 390.50 [days] Step 55/116: 390.50 -> 400.50 [days] Step 56/116: 400.50 -> 410.50 [days] Step 57/116: 410.50 -> 420.50 [days] Step 58/116: 420.50 -> 430.50 [days] Step 59/116: 430.50 -> 440.50 [days] Step 60/116: 440.50 -> 450.50 [days] Step 61/116: 450.50 -> 460.50 [days] Step 62/116: 460.50 -> 470.50 [days] Step 63/116: 470.50 -> 480.50 [days] Step 64/116: 480.50 -> 490.50 [days] Step 65/116: 490.50 -> 500.50 [days] Step 66/116: 500.50 -> 510.50 [days] Step 67/116: 510.50 -> 520.50 [days] Step 68/116: 520.50 -> 530.50 [days] Step 69/116: 530.50 -> 540.50 [days] Step 70/116: 540.50 -> 550.50 [days] Step 71/116: 550.50 -> 560.50 [days] Step 72/116: 560.50 -> 570.50 [days] Step 73/116: 570.50 -> 580.50 [days] Step 74/116: 580.50 -> 590.50 [days] Step 75/116: 590.50 -> 600.50 [days] Step 76/116: 600.50 -> 610.50 [days] Step 77/116: 610.50 -> 620.50 [days] Step 78/116: 620.50 -> 630.50 [days] Step 79/116: 630.50 -> 640.50 [days] Step 80/116: 640.50 -> 650.50 [days] Step 81/116: 650.50 -> 660.50 [days] Step 82/116: 660.50 -> 670.50 [days] Step 83/116: 670.50 -> 680.50 [days] Step 84/116: 680.50 -> 690.50 [days] Step 85/116: 690.50 -> 700.50 [days] Step 86/116: 700.50 -> 710.50 [days] Step 87/116: 710.50 -> 720.50 [days] Step 88/116: 720.50 -> 730.50 [days] Step 89/116: 730.50 -> 740.50 [days] Step 90/116: 740.50 -> 750.50 [days] Step 91/116: 750.50 -> 760.50 [days] Step 92/116: 760.50 -> 770.50 [days] Step 93/116: 770.50 -> 780.50 [days] Step 94/116: 780.50 -> 790.50 [days] Step 95/116: 790.50 -> 800.50 [days] Step 96/116: 800.50 -> 810.50 [days] Step 97/116: 810.50 -> 820.50 [days] Step 98/116: 820.50 -> 830.50 [days] Step 99/116: 830.50 -> 840.50 [days] Step 100/116: 840.50 -> 850.50 [days] Step 101/116: 850.50 -> 860.50 [days] Step 102/116: 860.50 -> 870.50 [days] Step 103/116: 870.50 -> 880.50 [days] Step 104/116: 880.50 -> 890.50 [days] Step 105/116: 890.50 -> 900.50 [days] Step 106/116: 900.50 -> 910.50 [days] Step 107/116: 910.50 -> 920.50 [days] Step 108/116: 920.50 -> 930.50 [days] Step 109/116: 930.50 -> 940.50 [days] Step 110/116: 940.50 -> 950.50 [days] Step 111/116: 950.50 -> 960.50 [days] Step 112/116: 960.50 -> 970.50 [days] Step 113/116: 970.50 -> 980.50 [days] Step 114/116: 980.50 -> 990.50 [days] Step 115/116: 990.50 -> 1000.50 [days] Step 116/116: 1000.50 -> 1010.50 [days]
h = []; set(gcf, 'Renderer', 'OpenGL'); [htop, htext, hs] = plotWell(G, W); hg = plotGrid(G, 'FaceAlpha', 0, 'EdgeAlpha', .05); view(-60, 70); axis tight off

Plot the solution
for i = 1:numel(states) delete(h); data = states{i}.s(:,1); h = plotGrid(G, data > 0, 'FaceAlpha', .3, ... 'FaceColor', 'red', 'EdgeAlpha', 0); % Uncomment for slower, but prettier volume plotting % plotGridVolumes(G, data); title(['Water front after ' formatTimeRange(sum(dt(1:i)))]) pause(.1) end

Plot the time taken and number of iterations
delete([h, htext, htop, hs, hg]) plot([time, its], '.-'); legend({'Time (s)', 'Iterations'}) xlabel('Step #') title('Time and iteration count')
