Intro MRST
Intro MRST
Toolbox (MRST)
Knut–Andreas Lie
1 Introduction
4 Incompressible flow
5 Multiphase flow
6 Compressible flow
1 / 117
The MATLAB Reservoir Simulation Toolbox
Used in publications:
24 PhD theses and 63 master theses
110+ journal/proceedings papers by authors outside our group
2 / 117
Toolbox for experimental programming
3 / 117
Why in MATLAB?
4 / 117
How the software is organized . . .
fully implicit
es
flow diagnostics discretizations
ul
od
m
on
d-
Ad
2
MRST core cells.faces = faces.nodes = faces.neighbors =
1 10 1 1 0 2
6
1 8 1 2 2 3
6 1 7 2 1 3 5
5 6 2 1 2 3 5 0
9 2 2 3 1 6 2
2 5 3 4 0 6
4 12 3 3 4 1 1 3
3 3 7 4 7 4 1
3 2 5 2 6 4
8
2 4 8 5 3 1 8
1 5 4 12 6 2 8 5
1 7 4 9 6 6 4 7
upscaling 2
7
10
14 5
5
5 11
3
4
7
7
8
3
4
3
7
0
8
7 co2lab
3 6 9 8 5
8 13 6 6 9 3
Original permeability Upscaled (x−direction) Upscaled (y−direction) 4 6 5 9 6
7 13 10 4
3 11 7 14 10 5 CO2 saturation
5 : : : : at 500 years 12%
16%
1 4 7
56%
12%
3%
Residual (traps)
Residual
Residual (plume)
Injected volume: Movable (traps)
2.185e+07 m3 Movable (plume)
50 Original Height of CO2−column x 10
7 Leaked
Upscaled (x)
14
40 2
12
30 10 1.5
8
20 1
6
4
10 0.5
2
0 0 0
−1.5 −1 −0.5 0 0.5 1 1.5 2 2.5 0 50 100 150 200 250 300 350 400 450 500
input decks
visualization
... ...
5 / 117
. . . core and add-on modules
The core module provides basic data structures and utility functions.
Add-on modules offer:
discretizations and solvers
simulators for incompressible and compressible flow
workflow tools such as coarsening, upscaling, flow diagnostics,
visualization, etc
special models like geomechanics and fractured reservoirs
analysis of large-scale CO2 storage in saline aquifers
6 / 117
Two different programming paradigms
7 / 117
Quick overview of functionality
8 / 117
Quick overview of functionality
Grid generation and coarsening:
MRST core upr coarsegrid agglom
MRST offers a wide variety of grid factory routines and input from Eclipse, upr
generates 2D and 3D Voronoi grids with cell and face constraints
coarsegrid: data structures and simple coarsening, adapted partitions in agglom
C-accelerated: processing in libgeometry and opm processing.
8 / 117
Quick overview of functionality
vem adjoint
8 / 117
Quick overview of functionality
deckreader ad-props
The AD-OO framework offers fully implicit simulators from industry-standard input
decks, including computations of adjoints
8 / 117
Quick overview of functionality
upscaling steady-state
msrsb is state-of-the art multiscale solver, hfm implements this for fracture models,
msmfem and msfvm are earlier developments
upscaling: flow-based single-phase upscaling, steady-state: multiphase upscaling
8 / 117
Quick overview of functionality
Fractured media:
dfm hfm dual-porosity
Geomechanics:
ad-mechanics vemmech fvbiot
Workflow tools:
co2lab diagnostics mrst-gui enkf
optimization remso
8 / 117
Outline
1 Introduction
4 Incompressible flow
5 Multiphase flow
6 Compressible flow
9 / 117
Downloading the software
MRST MATLAB Reservoir Simulation Toolbox SEARCH
You are here: MRST / Download
Download
SINTEF publishes several sets of resources as part of the Matlab Reservoir Simulation Toolbox. This is a list of packages and datasets
currently available for download.
The MATLAB Reservoir Simulation Toolbox
MRST is a set of core features intended to assist the student, researcher and practitioner who analyses reservoirtype flows or develops
numerical methods for solving flow or transport problems in reservoir applications. It is the intention of the MRST developers that the package
be a solid foundation for grid handling, visalisation, and advanced discretisations.
Sources to the current as well as a few, selected previous releases of the core MRST package set are available on a separate download page.
Please fill out the accompanying form to download the package.
Public Data Sets
The SAIGUP data set is a single realisation from the Sensitivity Analysis of the Impact of Geological Uncertainties on Production project.
The data is used in a number of examples accompanying the 2011a and later releases of MRST. You may download a copy of the data
from the following web page.
The Johansen formation is a candidate site for largescale CO2 storage offshore the southwest coast of Norway. The MatMoRA project
has developed a set of geological models based on available seismic and well data. You may download a copy of the data from the
following web page.
Published February 23, 2011
From http://www.sintef.no/MRST
10 / 117
Installing MRST
or on Windows,
cd C:\Users\username\mrst−2016b\
assuming that the files were extracted to the home directory. The startup.m file must
then be run to activate MRST,
startup;
11 / 117
Getting started: welcome message
If you start MATLAB in the directory containing MRST, or run the
startup.m file, you will see the following message
12 / 117
Getting started: sources for information
13 / 117
330 10 Solvers for Incompressible Immiscible Flow
Knut-Andreas Lie
An Introduction to Reservoir
Fig. 10.13. Illustration of the sloping sandbox used for the buoyancy example and
Simulation Using MATLAB how it is simulated by rotating the gravity vector. (Color: Gaussian porosity field).
R = makehgtform('yrotate',-pi*theta/180);
User Guide for the Matlab Reservoir Simulation gravity reset on
gravity( R(1:3,1:3)*gravity().' );
Toolbox (MRST) MRST defines the gravity vector as a persistent, global variable which by
default equals ~0. The second line ensures that ~g is set to the standard value
(pointing downward in the vertical direction) before we perform the rotation.
To initialize the problem, we assume that CO2 , which is lighter than the
June 12, 2017 resident brine, fills up the model from the bottom and to a prescribed height,
xr = initResSol(G, 1*barsa, 1);
d = gravity() ./ norm(gravity);
dc = G.cells.centroids * d.';
xr.s(dc>max(dc)-height) = 0;
For accuracy and stability, the time step is ramped up gradually as follows,
dT = [.5, .5, 1, 1, 1, 2, 2, 2, 5, 5, 10, 10, 15, 20, ...
repmat(25,[1,97])].*day;
to reach a final simulation time of 2500 days. The remaining code is similar
to what was discussed above; details can be found in buoyancyExample.m.
Let us consider the homogeneous case first. Initially, the buoyant CO2
plume will form a cone shape as it migrates upward and gradually drains the
resident brine. After approximately 175 days, the migrating plume starts to
accumulate as a thin layer of pure CO2 under the sloping east face of the box.
This layer will migrate quickly up towards the topmost northeast corner of
the box, which is reached after approximately 400 days, This corner forms a
structural trap that will gradually be filled as more CO2 migrates upward.
The trapped CO2 forms a diffused and curved interface (see the plots at
SINTEF ICT, Departement of Applied Mathematics 500 and 1000 days), but as time passes, the interface becomes sharper and
flatter. During the same period, brine will imbibe into the trailing edge of
Oslo, Norway the CO2 plume and gradually formed a layer of pure brine at the bottom.
Page: 1 job: mrst-book macro: svmono.cls date/time: 12-Jun-2017/20:34 Page: 330 job: mrst-book macro: svmono.cls date/time: 12-Jun-2017/22:33
Example scripts and tutorials . . .
>> mrstExamples
Module "core" has 18 examples:
flowSolverTutorial1.m
flowSolverTutorialAD.m
tutorialAD.m
tutorialBasicObjects.m
tutorialPlotting.m
datasets/showCaseB4.m
datasets/showJohansen.m
datasets/showNorne.m
datasets/showSAIGUP.m
datasets/showSPE10.m
grids/gridTutorialCornerPoint.m
grids/gridTutorialIntro.m
grids/gridTutorialStruct.m
grids/gridTutorialUnstruct.m
:
15 / 117
. . . presented in workbook format
16 / 117
Just-in-time online learning tools
Short learning modules consisting of 3-10 minute videos covering a specific topic.
Jolt1: explains what MRST is, how to download it, and how to make your first flow
solvers. Jolt2: introduction to grid and grid generation.
17 / 117
Finding more information . . .
18 / 117
Module examples on the web
MRST MATLAB Reservoir Simulation Toolbox SEARCH
You are here: MRST / Modules / Grid Coarsening
Grid Coarsening
The module implements functionality for generating coarse partitions and turning these into MRST grids.
Tutorials
Example 1 Example 2
This example shows you how to partition We show partitions of grids representing more
rectangular 2D Cartesian grids, the complex domains: a rectangular grid with a
relationship between cell and block numbers, semicircular cutout, a 3D cupformed domain,
and outlines the basics of the coarsegrid a 2D Voronoi grid of rectangular domain with a
structure, including numbering of cells, faces, quatercircle cutout, and a cornerpoint grid
and node. with a single fault.
Example 3 Example 4
The example continues the discussion of the In this example, we take a closer look at
coarsegrid structure and shows how we can partition vectors and discuss how different
partition the coarse faces so that there are types of partitions can be combined into one.
more than one face (connection) between
neighboring coarse blocks.
Example 6
Example 5
We partition the Norne field uniformly in logical
In this example, we use the function Cartesian space. Since the model contains
refineNearWell to make coarse grids with many inactive cells, the initial partition must be
various types of nearwell refinement. The postprocessed to ensure a contigous partition
examples uses both Cartesian and 2.5 D PEBI vector. We visualize some of the coarse blocks
fine grids. and show how they are connected with their
neighbors.
19 / 117
Example 7
The module explorer
K
∇ · ~v = q, ~v = − ∇p + ρg∇z
µ
Vertical well and Dirichlet boundary
% Grid and rock parameters
nx = 20; ny = 20; nz = 10;
G = computeGeometry(cartGrid([nx, ny, nz]));
rock.perm = repmat(100 * milli*darcy, [G.cells.num, 1]);
fluid = initSingleFluid('mu', 1*centi*poise, ...
' rho ' , 1014*kilogram/meterˆ3);
gravity reset on Source term and boundary
condition
% Fluid sources and boundary conditions
c = (nx/2*ny+nx/2 : nx*ny : nx*ny*nz) .';
src = addSource([], c, ones(size(c)) ./ day());
bc = pside([], G, ' LEFT', 10*barsa());
% Compute transmissibilities
T = computeTrans(G, rock);
21 / 117
Operating modules
22 / 117
Finding more information . . .
23 / 117
Manual pages: computing transmissibility
>> help computeTrans
Compute transmissibilities.
SYNOPSIS:
T = computeTrans(G, rock)
T = computeTrans(G, rock, ’pn’, pv, ...)
PARAMETERS:
G - Grid structure as described by grid_structure.
rock - Rock data structure with valid field ’perm’. The permeability
is assumed to be in measured in units of metres squared (m^2).
Use function ’darcy’ to convert from darcies to m^2, e.g.,
COMMENTS:
PLEASE NOTE: Face normals are assumed to have length equal to the corresponding
face areas. This property is guaranteed by function ’computeGeometry’.
SEE ALSO:
computeGeometry, computeMimeticIP, darcy, permTensor.
24 / 117
Finding more information . . .
25 / 117
Source code: computing transmissibility
% Vectors from cell centroids to face centroids
cellNo = rldecode(1:G.cells.num, diff(G.cells.facePos), 2)';
if ∼isempty(opt.cellCenters)
C = opt.cellCenters;
else
C = G.cells.centroids;
end
if ∼isempty(opt.cellFaceCenters)
C = opt.cellFaceCenters − C(cellNo,:);
else
C = G.faces.centroids(G.cells.faces(:,1), :) − C(cellNo,:);
end
% Normal vectors
sgn = 2*(cellNo == G.faces.neighbors(G.cells.faces(:,1), 1)) − 1;
N = bsxfun(@times, sgn, G.faces.normals(G.cells.faces(:,1),:));
clear sgn;
if strcmpi(opt.K_system, 'xyz'),
[K, i, j] = permTensor(rock, G.griddim);
From computeTrans.m
26 / 117
Finding more information . . .
27 / 117
The MRST-users mailing list
URL: https://groups.google.com/forum/#!forum/sintef-mrst
28 / 117
Finding more information . . .
29 / 117
Public data sets
Norne SAIGUP
Johansen CaseB4
30 / 117
Public data sets
31 / 117
Software requirements
32 / 117
External dependencies
33 / 117
Tutorials
Terms of use All modules in MRST have a set of tutorial scripts that introduce you to the basic functionality of the module. Several of
these are also available on the module webpages. In addition, we have number of tutorials that introduce you to basic
functionality of MRST.
You are free to use the software within the GNU GPL3 license, but . . .
Citing MRST
If you are using MRST in any publication, we would be grateful if you cite the MRST book or one of the following three papers (possibly in
addition to a link to our webpage):
K. Bao, K.A. Lie, O. Møyner, and M. Liu. Fully implicit simulation of polymer flooding with MRST. Comput. Geosci.,
2017. DOI: 10.1007/s1059601796272. Also available from: Springer Nature ShareIt.
An earlier version was published as: K. Bao, K.A. Lie, O. Møyner, and M. Liu Fullyimplicit simulation of polymer flooding with MRST.
ECMOR XV, Amsterdam, Netherlands, 29 Aug1 Sept, 2016. DOI: 10.3997/22144609.201601880
S. Krogstad, K.A. Lie, O. Møyner, H. M. Nilsen, X. Raynaud, and B. Skaflestad. MRSTAD an opensource framework
for rapid prototyping and evaluation of reservoir simulation problems. Paper 173317MS presented at the 2015
Reservoir simulation Symposium, Houston, Texas, USA, 2325 February 2015.
K.A. Lie, S. Krogstad, I. S. Ligaarden, J. R. Natvig, H. M. Nilsen, and B. Skaflestad. Open source MATLAB
implementation of consistent discretisations on complex grids. Comput. Geosci., , Vol. 16, No. 2, pp. 297322, 2012.
DOI: 10.1007/s1059601192444
Complete MATLAB scripts that reproduce (almost) all the figures and examples in the paper are available for
download, see e.g., Example 5 and Example 6.
An earlier version was published as: K.A. Lie, S. Krogstad, I. S. Ligaarden, J. R. Natvig, H. M. Nilsen, and B. Skaflestad. Discretisation on
complex grids Open source MATLAB implementation. Proceedings of ECMOR XII, Oxford, UK, 69 September 2010
Scientific publications utilizing MRST
MRST has been used in a large number of journal articles, conference proceedings, and master and doctoral theses. We try to collect as many
as possible of these publications and have compiled them in separate lists. If your paper is missing in the lists, if have you used MRST in your
thesis, or if have you supervised students using MRST, we are of course very happy to hear about it. If you provide us with publication details,
we will list your publication or details about the thesis. If you also provide us with an illustrateive picture and a short description, we will
highlight your work on our gallery pages. Contact: Knut[email protected]
Published June 14, 2011
34 / 117
Computer exercises
35 / 117
Outline
1 Introduction
4 Incompressible flow
5 Multiphase flow
6 Compressible flow
36 / 117
What you will learn in this section
To learn more:
– watch the videos in Jolt2
– study tutorials called gridTutorial*.m in mrst-core
– read Lie et al. (COMG, 2012), doi: 10.1007/s10596-011-9244-4
– read Chapters 2 and 3 in the MRST book
37 / 117
Grids and physical quantities
38 / 117
Standard grids: Cartesian grids
0.9
0 0.8
0.5
0.7
1
10 0.6
9
0.5
8
7 0.4
6
0.3
5
4 5 0.2
3 4
2 3 0.1
2
1
1 0
0 0 0 0.2 0.4 0.6 0.8 1 1.2 1.4
39 / 117
Standard grids: curvilinear grids
Create a rough grid by perturbing the inner nodes randomly
nx = 12; ny=6;
G = cartGrid([nx, ny]);
plotGrid(G,' LineStyle ' , ' : ' );
0
0 2 4 6 8 10 12
40 / 117
Standard grids: fictitious domains
−1
Alternative approach: embed the domain within a
0
larger “fictitious” domain of simple shape, −2
1
boolean indicator value tells whether each cell is 0
2
part of the domain or not. Here, an ellipsoid 2 2
2
within a cube: 0
0
2
−2 −2
x = linspace(−2,2,21);
G = tensorGrid(x,x,x);
subplot(1,2,1); plotGrid(G);view(3); axis equal
−2
subplot(1,2,2); plotGrid(G,'FaceColor
−1
' , ' none' );
G = computeGeometry(G); 0 2
c = G.cells.centroids; 1
−2
1
r = c(:,1).ˆ2 + 0.25*c(:,2).ˆ2+0.25*c(:,3).ˆ2; 0
2
G = removeCells(G, r>1); 2 2
0
2
plotGrid(G); view(−70,70); axis equal;
0
2
1 −1
0
0
−2 −2 −1
−2 −2
41 / 117
Standard grids: Delaunay and Voronoi grids
42 / 117
Using an external grid generator
Install DistMesh by Persson & Strang as a module
path = fullfile(ROOTDIR,'utils' , ' 3rdparty ' , ' distmesh ' );
mkdir(path)
unzip('http:// persson.berkeley.edu /distmesh/distmesh.zip ' , path);
mrstPath(' reregister ' , ' distmesh ' , path);
% Extrude a standard MATLAB dataset % Make and process simple corner−point description
load seamount grdecl = simpleGrdecl([20, 10, 5], 0.12)
*pi); g = triangleGrid([x(:) y (:)]); G = processGRDECL(grdecl);
; P = pebi(g); plotGrid(G, ' FaceAlpha',0.8);
.05 :1)); V = makeLayeredGrid(P, 5); plotFaces(G,find(G.faces.tag>0), 'FaceColor', ' red ' );
plotGrid(V), view(−40, 60), axis off view (40,40), axis off
44 / 117
Rock modelling in MRST
All flow and transport solvers in MRST require a rock structure, which by
convention is called rock, and contains two fields:
rock.poro – porosity, column vector with one entry per active cell
rock.perm – permeability in SI units
The rock object can also hold net-to-gross, ntg, consisting of a scalar or
a single column vector with one value per active cell
45 / 117
Example: homogeneous model
Because MRST works in SI units, we must convert from the field units
’darcy’ to the SI unit ’meters2 ’. Alternative: use the conversion function
convertFrom(200,milli*darcy)
Warning: It is better to use makeRock instead of setting rock.poro and rock.perm directly to
avoid unintentionally copying data elements from existing rock objects
46 / 117
Example: heterogeneous model
20
15
relation 0
0 5 10 15 20 25 30 35 40 45 50
1 φ3 d2p
K= , 0.2 0.22 0.24 0.26 0.28 0.3 0.32 0.34 0.36 0.38 0.4
15
geostatistics. For more realistic 10
5
5
10
0 0
47 / 117
Example: stratigraphic model
Four layers with mean values: 100, 400, 50, and 350 mD (top to
bottom), and layer thickness: one, three, two, and four grid cells.
plotCellData(G,log10(K),'EdgeColor','k' );
view(45,30); axis tight off,
set(gca,'DataAspect',[0.5 1 1])
h = colorbar('horiz' );
ticks = 25*2.ˆ[0:5];
set(h, ' XTick',log10(ticks),'XTickLabel',ticks);
48 / 117
Example: Model 2, 10th SPE Comparative Solution Project
Separate module, spe10, for downloading and accessing this model
mrstModule add spe10; rock = SPE10_rock();
4 4
x 10 x 10
2.5 3
Ness Tarbert
Tarbert Ness
2.5
2
1.5
1.5
0.5
0.5
0 0
−4 −3 −2 −1 0 1 2 3 4 5 −8 −6 −4 −2 0 2 4
49 / 117
Example: model from Eclipse input deck
grdecl =
cartDims: [40 120 20]
COORD: [29766x1 double]
ZCORN: [768000x1 double]
ACTNUM: [96000x1 int32]
PERMX: [96000x1 double]
PERMY: [96000x1 double]
PERMZ: [96000x1 double]
MULTX: [96000x1 double]
MULTY: [96000x1 double]
MULTZ: [96000x1 double]
PORO: [96000x1 double]
NTG: [96000x1 double]
SATNUM: [96000x1 double]
50 / 117
Example: synthetic shallow-marine model
51 / 117
Example: synthetic shallow-marine model
horizontal permeability vertical permeability
52 / 117
Grids in MRST: fully unstructured
53 / 117
Grid structure: cells
54 / 117
Grid structure: cells
Optional field:
indexMap – Nc × 1 array mapping internal cell indices to external
cell indices. For models with no inactive cells, indexMap equals
1 : Nc . For cases with inactive cells, indexMap contains the indices
of the active cells sorted in ascending order.
For logically Cartesian grids, a map of cell numbers to logical indices can be constructed
using the following statements in 3D:
55 / 117
Grid structure: faces
56 / 117
Grid structure: faces and nodes
Optional field:
tag – can contain user-defined face indicators
57 / 117
Example: grid structure
G = removeCells( cartGrid([3,2]), 2)
G =
cells: [1x1 struct]
faces: [1x1 struct]
nodes: [1x1 struct]
cartDims: [3 2]
type: {’tensorGrid’ ’cartGrid’ ’removeCells’}
griddim: 2
58 / 117
Geometry computation: basic steps
59 / 117
Computer exercises
List all tutorials in mrst-core and go through at least one of each of the
following types:
datasets/show<name>.m grids/gridTutorial<name>.m
Make the grid below. Hint: the grid spacing in the x-direction is given by
∆x(1 − 21 cos(πx)) and the colors signify cell volumes.
Create MRST grids from the standard data set trimesh2d. How would
you assign lognormal petrophysical parameters to these grids so that the
spatial correlation is preserved?
60 / 117
Outline
1 Introduction
4 Incompressible flow
5 Multiphase flow
6 Compressible flow
61 / 117
What you will learn in this section
We will go through:
discrete differential and averaging operators
finite volume methods for −∇ K∇p = q
automatic differentiation
flow solvers in the incomp family
You will also get a tast of efficient vectorization tricks in MATLAB
To learn more:
– watch the videos in Jolt1
– study the 1ph tutorials/examples in the incomp module
– read Lie et al. (COMG, 2012), doi: 10.1007/s10596-011-9244-4
– read Chapters 4 to 6 in the MRST book
62 / 117
Discrete differentiation operators
Idealized models Grid structure in MRST Industry models
c F(c) f C1 C2
1 1 1 3 1
7
8 1 2 2 1 2
8
1 3 3 1 8
3 1 4 4 9 1
7 2 5 5 4 2
6
2 6 6 2 5
9 4 1 2 7 7 2 6
2 2
2 8 8 2 7
.. .. ..
6 2 2 . . .
.. .. ..
1 5 3 1 . . .
5
.. ..
. .
.. ..
. .
3 4
Map: cell → faces Map: face → cells
Starting point: mapping F from cell to faces, and C from face to cells:
C = G.faces.neighbors; % Cells belonging to each face
C = C(all(C ∼= 0, 2), :); % Only interior faces
cn = gridCellNo(G); % Repeat cell number for all faces
F = G.cells.faces(:,1); % Faces making up each cell
[nf,nc] = deal(size(C,1), G.cells.num); % Number of faces/cells
63 / 117
Discrete differentiation operators
Idealized models Grid structure in MRST Industry models
c F(c) f C1 C2
1 1 1 3 1
7
8 1 2 2 1 2
8
1 3 3 1 8
3 1 4 4 9 1
7 2 5 5 4 2
6
2 6 6 2 5
9 4 1 2 7 7 2 6
2 2
2 8 8 2 7
.. .. ..
6 2 2 . . .
.. .. ..
1 5 3 1 . . .
5
.. ..
. .
.. ..
. .
3 4
Map: cell → faces Map: face → cells
Here, v[f ] denotes a discrete flux over face f with orientation from cell
C1 (f ) to cell C2 (f )
63 / 117
Discrete differentiation operators
Idealized models Grid structure in MRST Industry models
c F(c) f C1 C2
1 1 1 3 1
7
8 1 2 2 1 2
8
1 3 3 1 8
3 1 4 4 9 1
7 2 5 5 4 2
6
2 6 6 2 5
9 4 1 2 7 7 2 6
2 2
2 8 8 2 7
.. .. ..
6 2 2 . . .
.. .. ..
1 5 3 1 . . .
5
.. ..
. .
.. ..
. .
3 4
Map: cell → faces Map: face → cells
63 / 117
Discrete differentiation operators
Idealized models Grid structure in MRST Industry models
c F(c) f C1 C2
1 1 1 3 1
7
8 1 2 2 1 2
8
1 3 3 1 8
3 1 4 4 9 1
7 2 5 5 4 2
6
2 6 6 2 5
9 4 1 2 7 7 2 6
2 2
2 8 8 2 7
.. .. ..
6 2 2 . . .
.. .. ..
1 5 3 1 . . .
5
.. ..
. .
.. ..
. .
3 4
Map: cell → faces Map: face → cells
The div and grad operators are linear and can be represented as sparse
matrix multiplications:
D = sparse([(1:nf )'; (1:nf )'], C, ones(nf,1)*[−1 1], nf, nc);
grad = @(x) D*x;
div = @(x) −D'*x;
With no-flow boundaries, the two operators are adjoint of each other, as
in the continuous case
63 / 117
Finite-volume method: single-phase flow
Fundamental physics: Darcy’s law
Z Z
~v (x) · ~
nf ds = − K(x)∇p · ~
nf ds Ai,k
Ki Kk
Γf Γf ~ci,k ~ni,k
v[f ] = −T [f ] grad(p)[f ]
Conservation of mass:
Z Z Z
ci,k · Ki ~
~ ni,k
~v · ~
n ds = ∇ · ~v d~
x= qd~
x Ti,k = Ai,k
∂Ωc Ωc Ωc ci,k |2
|~
div(v)[c] = q[c] −1
Tik = [Ti,k + Tk,i ]
−1 −1
64 / 117
Finite-volume method: single-phase flow
Fundamental physics: Darcy’s law
Z Z
~v (x) · ~
nf ds = − K(x)∇p · ~
nf ds Ai,k
Ki Kk
Γf Γf ~ci,k ~ni,k
v[f ] = −T [f ] grad(p)[f ]
Conservation of mass:
Z Z Z
ci,k · Ki ~
~ ni,k
~v · ~
n ds = ∇ · ~v d~
x= qd~
x Ti,k = Ai,k
∂Ωc Ωc Ωc ci,k |2
|~
div(v)[c] = q[c] −1
Tik = [Ti,k + Tk,i ]
−1 −1
Here, the first line determines the correct sign of the face normal
64 / 117
Finite-volume method: single-phase flow
Fundamental physics: Darcy’s law
Z Z
~v (x) · ~
nf ds = − K(x)∇p · ~
nf ds Ai,k
Ki Kk
Γf Γf ~ci,k ~ni,k
v[f ] = −T [f ] grad(p)[f ]
Conservation of mass:
Z Z Z
ci,k · Ki ~
~ ni,k
~v · ~
n ds = ∇ · ~v d~
x= qd~
x Ti,k = Ai,k
∂Ωc Ωc Ωc ci,k |2
|~
div(v)[c] = q[c] −1
Tik = [Ti,k + Tk,i ]
−1 −1
Here, the first line determines the correct sign of the face normal
Extract permeability vector [Kxx , Kxy , Kyx , Kyy ] for each cell:
[K, i, j] = permTensor(rock, G.griddim);
64 / 117
Finite-volume method: single-phase flow
Fundamental physics: Darcy’s law
Z Z
~v (x) · ~
nf ds = − K(x)∇p · ~
nf ds Ai,k
Ki Kk
Γf Γf ~ci,k ~ni,k
v[f ] = −T [f ] grad(p)[f ]
Conservation of mass:
Z Z Z
ci,k · Ki ~
~ ni,k
~v · ~
n ds = ∇ · ~v d~
x= qd~
x Ti,k = Ai,k
∂Ωc Ωc Ωc ci,k |2
|~
div(v)[c] = q[c] −1
Tik = [Ti,k + Tk,i ]
−1 −1
64 / 117
Finite-volume method: single-phase flow
Fundamental physics: Darcy’s law
Z Z
~v (x) · ~
nf ds = − K(x)∇p · ~
nf ds Ai,k
Ki Kk
Γf Γf ~ci,k ~ni,k
v[f ] = −T [f ] grad(p)[f ]
Conservation of mass:
Z Z Z
ci,k · Ki ~
~ ni,k
~v · ~
n ds = ∇ · ~v d~
x= qd~
x Ti,k = Ai,k
∂Ωc Ωc Ωc ci,k |2
|~
div(v)[c] = q[c] −1
Tik = [Ti,k + Tk,i ]
−1 −1
64 / 117
Finite-volume method: single-phase flow
Fundamental physics: Darcy’s law
Z Z
~v (x) · ~
nf ds = − K(x)∇p · ~
nf ds Ai,k
Ki Kk
Γf Γf ~ci,k ~ni,k
v[f ] = −T [f ] grad(p)[f ]
Conservation of mass:
Z Z Z
ci,k · Ki ~
~ ni,k
~v · ~
n ds = ∇ · ~v d~
x= qd~
x Ti,k = Ai,k
∂Ωc Ωc Ωc ci,k |2
|~
div(v)[c] = q[c] −1
Tik = [Ti,k + Tk,i ]
−1 −1
Usually, you would not have to implement all this, but rather call a
function that also includes various safeguards:
S = setupOperatorsTPFA(G,rock);
S =
T_all: [220x1 double]
T: [180x1 double]
C: [180x100 double]
Grad: @(x)-C*x
Div: @(x)C’*x
:
64 / 117
Automatic differentiation
Automatic differentiation
Idea: keep track of variables and derivatives simultaneously
Any code, regardless of complexity, can be broken down to a limited
set of arithmetic operations (+, −, ∗, /,. . . ) and elementary functions
(sin, exp, power, . . . )
Derivative rules are known for these operations and functions
Combine these with the chain rule
65 / 117
Automatic differentiation
66 / 117
Implementation of AD in MRST
[x,y] = initVariablesADI(1,2);
z = 3*exp(−x*y)
∂x ∂x ∂y ∂y ∂z ∂z
∂x ∂y ∂x ∂y ∂x x=1,y=2 ∂y x=1,y=2
67 / 117
Applying AD to incompressible flow
In discrete form:
F (p) = div T grad(p) + q = Ap + q = 0
68 / 117
Solving the Poisson equation: −∆p = q
eq = S.Div(S.Grad(p))+q; % equation
eq(1) = eq(1) + p(1); % make solution unique
p = −eq.jac{1}\eq.val; % solve equation
plotCellData(G,p);
69 / 117
Solving the Poisson equation: non-rectangular domain
% Operators
S = setupOperatorsTPFA(G,rock);
spy(S.C); ∂
∂y
eq = S.Div(S.Grad(p))+q; % equation
eq(1) = eq(1) + p(1); % make solution unique
p = −eq.jac{1}\eq.val; % solve equation
plotCellData(G,p);
70 / 117
Solving the Poisson equation: unstructured grid
% Operators
S = setupOperatorsTPFA(G,rock);
spy(S.C);
eq = S.Div(S.T.*S.Grad(p))+q;
eq(1) = eq(1) + p(1);
p = −eq.jac{1}\eq.val;
plotCellData(G,p);
71 / 117
Switching between different dicretization schemes
v = −T_tp.*grad(p)
←→ eq = div(T_tp.*grad(p))+q;
eq = div(v)−q;
v = −T_mp*grad(p)
←→ eq = div(T_mp*grad(p))+q;
eq = div(v)−q;
72 / 117
Switching between different dicretization schemes, cont’d
... will work but involves applying M −1 to the nf × nc grad-matrix. Instead let flux v
be primary variable, and solve for both v and p:
[v,p] = initVariablesADI(zeros(nf, 1), zeros(nc, 1));
eq{1} = M*v+grad(p); % Darcy's law
eq{2} = div(v)−q; % continuity equation
eq = cat(eq{:}); % concatenate equations
x = −eq.jac{1}\eq.val; % solve, x contains both v and p
73 / 117
More advanced problems
74 / 117
Assembly of linear equation in incomp solvers
75 / 117
Basic data structures in simulation models
Fluid properties:
fluid = initSingleFluid('mu' , 1*centi*poise, ...
' rho ' , 1014*kilogram/meterˆ3);
Fluid sources
src = addSource(src, cells, rates);
src = addSource(src, cells, rates, 'sat' , sat);
76 / 117
Basic data structures in simulation models
Boundary conditions
bc = addBC(bc, faces, type, values);
bc = addBC(bc, faces, type, values, ' sat ' , sat);
77 / 117
Incompressible flow solvers in MRST
78 / 117
Example: quarter five-spot with source terms
gravity reset off
[nx,ny] = deal(20);
G = cartGrid([nx,ny ],[500,500]);
G = computeGeometry(G);
rock = makeRock(G, 100*milli*darcy, .2);
hT = computeTrans(G, rock);
pv = sum(poreVolume(G,rock));
src = addSource([], 1, pv);
src = addSource(src, G.cells.num, −pv);
plotCellData(G, state.pressure,'EdgeAlpha',.01,'FaceAlpha',.4);
plotWell(G, W(1), ' radius ' , 1, ' color ' , ' r ' );
plotWell(G, W(2), ' radius ' , .5, ' color ' , ' b ' );
view(3), camproj perspective, axis tight off
80 / 117
Computer exercises
81 / 117
Outline
1 Introduction
4 Incompressible flow
5 Multiphase flow
6 Compressible flow
82 / 117
What you will learn in this section
To learn more:
– study the 2ph tutorials/examples in the incomp module
– read Chapters 8 to 10 in the MRST book
83 / 117
Two-phase, incompressible flow
The solvers of the incomp family are designed to solve two-phase models
consisting of an elliptic pressure equation
∇ · ~v = q, ~v = −λ ∇pn − fw ∇Pc − (ρw fw + ρn fn )g∇z
∂Sw
φ + ∇ · fw ~v + λn (∆ρg∇z + ∇Pc ) = qw
∂t
84 / 117
Two-phase, incompressible flow
The solvers of the incomp family are designed to solve two-phase models
consisting of an elliptic pressure equation
∇ · ~v = q, ~v = −λ ∇pn − fw ∇Pc − (ρw fw + ρn fn )g∇z
∂Sw
φ + ∇ · fw ~v + λn (∆ρg∇z + ∇Pc ) = qw
∂t
84 / 117
Two-phase, incompressible flow
The solvers of the incomp family are designed to solve two-phase models
consisting of an elliptic pressure equation
∇ · ~v = q, ~v = −λ ∇pn − fw ∇Pc − (ρw fw + ρn fn )g∇z
∂Sw
φ + ∇ · fw ~v + λn (∆ρg∇z + ∇Pc ) = qw
∂t
For the pressure equation, we use same methods as discussed above with
obvious modifications. Solvers implemented for multiphase elliptic
pressure equation:
incompTPFA, incompMimetic, incompMPFA,...
The only changes are in how mobility and right-hand side are computed
84 / 117
Two-phase, incompressible flow
The solvers of the incomp family are designed to solve two-phase models
consisting of an elliptic pressure equation
∇ · ~v = q, ~v = −λ ∇pn − fw ∇Pc − (ρw fw + ρn fn )g∇z
∂Sw
φ + ∇ · fw ~v + λn (∆ρg∇z + ∇Pc ) = qw
∂t
84 / 117
~
Discretization of φSt + ∇ · H(S) =0
85 / 117
~
Discretization of φSt + ∇ · H(S) =0
1 X tn+1
Z Z
n+1 n ~ S(~x, t) · ~ni,k ds dt
Si − Si = H
φi |Ωi | tn Γik
k
85 / 117
~
Discretization of φSt + ∇ · H(S) =0
1 X tn+1
Z Z
n+1 n ~ S(~x, t) · ~ni,k ds dt
Si − Si = H
φi |Ωi | tn Γik
k
85 / 117
~
Discretization of φSt + ∇ · H(S) =0
85 / 117
~
Discretization of φSt + ∇ · H(S) =0
85 / 117
~
Discretization of φSt + ∇ · H(S) =0
85 / 117
~
Discretization of φSt + ∇ · H(S) =0
85 / 117
Implementation in MRST
Explicit scheme: S n+1 = S n − F (S n , S n ). Implicit scheme: F(S n+1 , S n ) = 0
∆t X
Fi (s, r) = si − ri + Hik (s) − max(qi , 0) − min(qi , 0)f (Si )
φi |Ωi | k
λuw (si , sk )
+ λu
Hik (s) = vik n (si , sk )(gik + Pik )]
λw (si , sk ) + λu
u
n (s i , s k )
86 / 117
Implementation in MRST
Explicit scheme: S n+1 = S n − F (S n , S n ). Implicit scheme: F(S n+1 , S n ) = 0
∆t X
Fi (s, r) = si − ri + Hik (s) − max(qi , 0) − min(qi , 0)f (Si )
φi |Ωi | k
λuw (si , sk )
+ λu
Hik (s) = vik n (si , sk )(gik + Pik )]
λw (si , sk ) + λu
u
n (s i , s k )
86 / 117
Implementation in MRST
Explicit scheme: S n+1 = S n − F (S n , S n ). Implicit scheme: F(S n+1 , S n ) = 0
∆t X
Fi (s, r) = si − ri + Hik (s) − max(qi , 0) − min(qi , 0)f (Si )
φi |Ωi | k
λuw (si , sk )
+ λu
Hik (s) = vik n (si , sk )(gik + Pik )]
λw (si , sk ) + λu
u
n (s i , s k )
86 / 117
Implementation in MRST
Explicit scheme: S n+1 = S n − F (S n , S n ). Implicit scheme: F(S n+1 , S n ) = 0
∆t X
Fi (s, r) = si − ri + Hik (s) − max(qi , 0) − min(qi , 0)f (Si )
φi |Ωi | k
λuw (si , sk )
+ λu
Hik (s) = vik n (si , sk )(gik + Pik )]
λw (si , sk ) + λu
u
n (s i , s k )
86 / 117
Implementation in MRST
Explicit scheme: S n+1 = S n − F (S n , S n ). Implicit scheme: F(S n+1 , S n ) = 0
∆t X
Fi (s, r) = si − ri + Hik (s) − max(qi , 0) − min(qi , 0)f (Si )
φi |Ωi | k
λuw (si , sk )
+ λu
Hik (s) = vik n (si , sk )(gik + Pik )]
λw (si , sk ) + λu
u
n (s i , s k )
86 / 117
Time-step control
mints = pow2(tf, −opt.tsref);
[t, dt] = deal(0.0, tf);
while t < tf && dt >= mints,
dt = min(dt, tf − t);
redo_newton = true;
while redo_newton,
sn_0 = resSol; sn = resSol; sn.s(:) = min(1,sn.s+0.05);
res = F(sn, sn_0, dt);
err = norm(res(:), inf);
[nwtfail, linfail, it] = deal(err>opt.nltol,false,0);
while nwtfail && ∼linfail && it < opt.maxnewt,
J = Jac(sn, sn_0, dt);
ds = −reshape(opt.LinSolve(J, reshape(res', [], 1)), ns, [])';
[sn, res, alph, linfail] = update(sn, sn_0, ds, dt, err);
it = it + 1;
err = norm(res(:), inf);
nwtfail = err > opt.nltol;
end
if nwtfail,
% Chop time step in two, or use previous successful dt
else
redo_newton = false;
t = t + dt;
% If five successful steps , increase dt by 50%
end
end
resSol = sn;
end
87 / 117
Example: Buckley–Leverett displacement
G = computeGeometry(cartGrid([100,1]));
rock = makeRock(G, 100*milli*darcy, 0.2);
fluid = initSimpleFluid('mu' , [1, 1].*centi*poise, ...
' rho ' , [1000, 1000].*kilogram/meterˆ3, 'n', [2,2]);
1
Expl: 199 steps
0.9 n= 4: 47 its
n= 10: 65 its
0.8 n= 20: 102 its
n= 40: 161 its
0.7 n=100: 301 its
n=200: 407 its
0.6
0.5
0.4
0.3
0.2
0.1
0
0 10 20 30 40 50 60 70 80 90 100 88 / 117
Example: inverted gravity column
gravity reset on
G = cartGrid([1, 1, 40], [1, 1, 10]);
G = computeGeometry(G);
rock = makeRock(G, 0.1*darcy, 1);
fluid = initCoreyFluid(...
' mu' , [0.30860, 0.056641]*centi*poise, ...
hT = computeTrans(G, rock);
89 / 117
Example: inverted gravity column
t
0
10
−1
10
−2
10
−3
10
−4
10
∆ t = 36.50 days
∆ t = 54.75 days
−5
10
0 1 2 3 4 5 6 7 8 9
91 / 117
Outline
1 Introduction
4 Incompressible flow
5 Multiphase flow
6 Compressible flow
92 / 117
What you will learn in this section
To learn more:
– study examples/tutorials in the ad-core and ad-blackoil modules
– read Chapter 9 in the MRST book
– read Krogstad et al. (SPE RSS, 2015), doi: 10.2118/173317-MS
– read Bao et al. (COMG, 2017), doi: 10.1007/s10596-017-9624-5
93 / 117
Single-phase weakly compressible flow
1 K n+1
c(pn+1 − pn ) − div grad(p) =0
∆t µ
94 / 117
Single-phase weakly compressible flow
load seamount
G = pebi(triangleGrid([x(:) y (:)]));
G.nodes.coords = G.nodes.coords*100;
:
c = 1e−4;
mu = 1*centi*poise;
clf, plotCellData(G,p.val);
caxis([100 200]*atm); drawnow;
end
95 / 117
Single-phase compressible flow
% Fluid properties
rho0 = 10ˆ3; c_f = 5e−5;
rho = @(p) (rho0*exp(c_f*(p − pref)));
mu = 1*centi*poise;
96 / 117
Adding effects: gravity
97 / 117
Adding effects: gravity
97 / 117
Adding effects: well model and controls
Peacemann well model, with hydrostatic pressure in well bore, and
control on bottom-hole pressure:
pc = pbh + g ∆zc ρ(pbh ),
ρ
pbh
qc = WI(pc − p),
µ
1 X qc
qS = S qc ,
ρ c
pbh = constant
Implemented in MRST:
wc = W(1).cells; % connection grid cells
WI = W(1).WI; % well−indices
dz = W(1).dZ; % connection depth relative to bottom−hole
98 / 117
Details of simulator: time loop and assembly of equations
% Newton loop
resNorm = 1e99;
p0 = double(p); % Previous step pressure
nit = 0;
while (resNorm > tol) && (nit < maxits)
% one Newton iteration
end
99 / 117
Details of simulator: time loop and assembly of equations
resNorm = norm(res);
nit = nit + 1;
99 / 117
Adding effects: pressure-dependent viscosity
µ(p) = µ0 [1 + cr (p − pr )]
100 / 117
Adding effects: pressure-dependent viscosity
µ(p) = µ0 [1 + cr (p − pr )]
Arithmetic averaging:
mu = @(p) mu0*(1+c mu*(p−pr));
v = @(p) −(T./mu(avg(p))).*(grad(p) − g*avg(rho(p)).*dz);
100 / 117
Adding effects: pressure-dependent viscosity
µ(p) = µ0 [1 + cr (p − pr )]
Harmonic averaging:
[cn,F] = getCellNoFaces(G);
hf2f = sparse(F ,(1: numel(cn ))',1);
hf2f = hf2f( all (C∼=0,2),:);
fmob = @(mu,p) 1./( hf2f*(mu(p(cn))./hT) )
100 / 117
Adding effects: thermal flow
∂ K
φρ(p, T ) + ∇ · ρ(p, T )~v = q, ~v = − ∇p − gρ(p, T )∇z
∂t µ(p, T )
∂
φρ(p, T )Ef (p, t) + (1 − φ)Er (p, T ) + ∇ · ρ(p, T )Hf (p, T )~v − ∇ · κ∇T = qe
∂t
101 / 117
Adding effects: thermal flow
∂ K
φρ(p, T ) + ∇ · ρ(p, T )~v = q, ~v = − ∇p − gρ(p, T )∇z
∂t µ(p, T )
∂
φρ(p, T )Ef (p, t) + (1 − φ)Er (p, T ) + ∇ · ρ(p, T )Hf (p, T )~v − ∇ · κ∇T = qe
∂t
101 / 117
Adding effects: multiple phases (without mass transfer)
102 / 117
Adding effects: multiple phases (without mass transfer)
102 / 117
Adding effects: multiple phases (without mass transfer)
102 / 117
Adding effects: multiple phases (without mass transfer)
∂O ∂O
∂p ∂Sw
∂W ∂W
∂p ∂Sw
102 / 117
Adding effects: multiple phases (without mass transfer)
102 / 117
Rapid prototyping in MRST
103 / 117
Outline
1 Introduction
4 Incompressible flow
5 Multiphase flow
6 Compressible flow
104 / 117
Advanced simulators: motivation
105 / 117
Advanced simulators: motivation
Bt
0.8
0.6
Bo
0.4
∂t (φbw Sw ) + ∇ · (bw ~
uw ) = bw q0.2
w
∂t [φ(bw So + bg rv Sg )]
pb+ ∇ · (b ~u
o o + bg r v ~
0
ug ) = bo q0o + bg rv0.2
qg 0.4 0.6 0.8 1
∂t [φ(bg Sg + bo rs So )]
+ ∇ · (bg ~
ug + bo rs ~
uo ) = bg qg + bo rs qo
106 / 117
Next step: object-orientation
Only expose needed details and enable more reuse of functionality that
has already been developed
107 / 117
Next step: object-orientation
107 / 117
The AD-OO modules
core functionality
ad-eor
Fully implicit simulators for water- utility module
based EOR: polymer and surfac-
tant AD-OO module
108 / 117
Example: two-phase Buckley–Leverett
109 / 117
Example: two-phase Buckley–Leverett
G = cartGrid([50, 1, 1], [1000, 10, 10]*meter);
G = computeGeometry(G);
rock = makeRock(1*darcy*ones, .3);
fluid = initSimpleADIFluid('phases', 'WO', 'n', [2 2]);
for i = 1:n
state = solver.solveTimestep(states{i}, dT, model, 'bc', bc);
states{i+1} = state;
end
plotToolbar(G, states, ' field ' , ' s :1 ' , ' plot1d ' , true, ...
' lockCaxis ' , true, ' startplayback ' ,true);
110 / 117
Example: two-phase Buckley–Leverett
G = cartGrid([50, 1, 1], [1000, 10, 10]*meter);
G = computeGeometry(G);
rock = makeRock(1*darcy*ones, .3);
fluid = initSimpleADIFluid('phases', 'WO', 'n', [2 2]);
for i = 1:n
state = solver.solveTimestep(states{i}, dT, model, 'bc', bc);
states{i+1} = state;
end
plotToolbar(G, states, ' field ' , ' s :1 ' , ' plot1d ' , true, ...
' lockCaxis ' , true, ' startplayback ' ,true);
110 / 117
Example: two-phase Buckley–Leverett
G = cartGrid([50, 1, 1], [1000, 10, 10]*meter);
G = computeGeometry(G);
rock = makeRock(1*darcy*ones, .3);
fluid = initSimpleADIFluid('phases', 'WO', 'n', [2 2]);
plotToolbar(G, sstates, ' field ' , ' s :1 ' , ' lockCaxis ' ,true),
caxis([0 1]), view(10,10)
colorbar
110 / 117
Example: two-phase Buckley–Leverett
G = cartGrid([50, 1, 1], [1000, 10, 10]*meter);
G = computeGeometry(G);
rock = makeRock(1*darcy*ones, .3);
fluid = initSimpleADIFluid('phases', 'WO', 'n', [2 2]);
The general solver has a hook, that visualizes the progress of the
simulation, enables you to stop it and continue running in ’debug’ mode:
fn = getPlotAfterStep(state0, model, schedule, ...
' plotWell ' , false, ' plotReservoir ' , true, ' field ' , ' s :1 ' , ...
' lockCaxis ' ,true, ' plot1d ' , true);
[∼,sstates,report] = ...
simulateScheduleAD(state0, model, schedule,'afterStepFn', fn);
110 / 117
More about the nonlinear solver
111 / 117
More about the nonlinear solver
Initial ministep:
Nonlinear solver ∆t Time step selector Type color legend
Solves nonlinear problems sub-divided Determines optimal time steps
into one or more mini steps using Class
Newton’s method SimpleTimeStepSelector,
Adjusted: Struct
IterationCountSelector,
∆t̃
StateChangeTimeStepSelector, ...
Input
Contains object
111 / 117
The layout of the AD solvers
Initial state Physical model
Schedule
simulateScheduleAD Function(s)
Initial ministep:
State(Ti ), ∆Ti , Controls(Ci ) Nonlinear solver ∆t Time step selector Input
Solves nonlinear problems sub-divided Determines optimal time steps
into one or more mini steps using Contains object
State(Ti + ∆Ti ) Newton’s method SimpleTimeStepSelector,
Adjusted:
∆t̃
IterationCountSelector, Optional output
StateChangeTimeStepSelector, ...
The framework is designed so that you can only work on the components you
are interested in: If you want to write a flow solver, you do not need to debug a
Newton solver.
112 / 117
Functionality through inheritance
PhysicalModel
Abstract base class for all MRST models.
Contains logic related to linearization and
updates.
Primary variables: None
ReservoirModel
Extends PhysicalModel with rock, fluid,
saturations, pressures, and temperature.
Base class for all reservoir models.
Added primary variables: sα , p, T, qα , pbh
ThreePhaseBlackOilModel
Extends ReservoirModel with optional so-
lution gas and vaporized oil. Base class for
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel PhysicalModel
Abstract base class for all MRST models. Properties:
Contains logic related to linearization and
updates. operators, G
Primary variables: None nonlinearTolerance, stepFunctionIsLinear
verbose
ReservoirModel
Extends PhysicalModel with rock, fluid,
saturations, pressures, and temperature.
Base class for all reservoir models.
Added primary variables: sα , p, T, qα , pbh
ThreePhaseBlackOilModel
Extends ReservoirModel with optional so-
lution gas and vaporized oil. Base class for
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel PhysicalModel
Abstract base class for all MRST models. Properties:
Contains logic related to linearization and
updates. operators, G
Primary variables: None nonlinearTolerance, stepFunctionIsLinear
verbose
Quality assurance:
ReservoirModel
Extends PhysicalModel with rock, fluid, state = model.validateState(state)
saturations, pressures, and temperature. model = model.validateModel(...)
Base class for all reservoir models.
Added primary variables: sα , p, T, qα , pbh
ThreePhaseBlackOilModel
Extends ReservoirModel with optional so-
lution gas and vaporized oil. Base class for
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel PhysicalModel
Abstract base class for all MRST models. Properties:
Contains logic related to linearization and
updates. operators, G
Primary variables: None nonlinearTolerance, stepFunctionIsLinear
verbose
Quality assurance:
ReservoirModel
Extends PhysicalModel with rock, fluid, state = model.validateState(state)
saturations, pressures, and temperature. model = model.validateModel(...)
Base class for all reservoir models.
Added primary variables: sα , p, T, qα , pbh Querying / setting model properties:
p = model.getProp(state, 'pressure')
[p,s] = model.getProps(state, 'pressure', ' s ' )
ThreePhaseBlackOilModel [f,i] = model.getVariableField(name)
Extends ReservoirModel with optional so-
state = model.setProp(model, state, 'pressure', 5)
lution gas and vaporized oil. Base class for state = model.incrementProp(state, 'pressure', 1)
two- and single-phase versions. state = model.capProperty(state,'saturation', 0, 1)
Added primary variables: rs , rv
These are examples of syntax for derived classes and
will not work on a PhysicalModel, which has no
associated variables 113 / 117
Functionality through inheritance
PhysicalModel PhysicalModel
Abstract base class for all MRST models. Get drive mechanisms:
Contains logic related to linearization and
updates. [..,ctrl] = model.getDrivingForces(model, ctrl)
Primary variables: None
ReservoirModel
Extends PhysicalModel with rock, fluid,
saturations, pressures, and temperature.
Base class for all reservoir models.
Added primary variables: sα , p, T, qα , pbh
ThreePhaseBlackOilModel
Extends ReservoirModel with optional so-
lution gas and vaporized oil. Base class for
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel PhysicalModel
Abstract base class for all MRST models. Get drive mechanisms:
Contains logic related to linearization and
updates. [..,ctrl] = model.getDrivingForces(model, ctrl)
Primary variables: None
Linearize and assemble discrete problem:
[problem, state] = ...
ReservoirModel model.getEquations(state0, state, ...
Extends PhysicalModel with rock, fluid, dt, drivingForces, varargin)
saturations, pressures, and temperature.
Base class for all reservoir models.
Added primary variables: sα , p, T, qα , pbh
ThreePhaseBlackOilModel
Extends ReservoirModel with optional so-
lution gas and vaporized oil. Base class for
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel PhysicalModel
Abstract base class for all MRST models. Get drive mechanisms:
Contains logic related to linearization and
updates. [..,ctrl] = model.getDrivingForces(model, ctrl)
Primary variables: None
Linearize and assemble discrete problem:
[problem, state] = ...
ReservoirModel model.getEquations(state0, state, ...
Extends PhysicalModel with rock, fluid, dt, drivingForces, varargin)
saturations, pressures, and temperature.
Base class for all reservoir models. Compute a linearized time step:
Added primary variables: sα , p, T, qα , pbh
[state, report] = ...
model.stepFunction(model, state, state0, ..
dt, drivingForces, linsolve, ...
ThreePhaseBlackOilModel nonlinsolve, iteration, varargin)
Extends ReservoirModel with optional so-
lution gas and vaporized oil. Base class for
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel PhysicalModel
Abstract base class for all MRST models. Update state from Newton increment:
Contains logic related to linearization and
updates. [state, report] = model.updateState(state, ...
Primary variables: None problem, dx, drivingForces)
ThreePhaseBlackOilModel
Extends ReservoirModel with optional so-
lution gas and vaporized oil. Base class for
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel ReservoirModel
Abstract base class for all MRST models. Properties:
Contains logic related to linearization and
updates. % Submodels
Primary variables: None fluid, rock, gravity
FacilityModel
% Physical properties
ReservoirModel water, gas, oil
Extends PhysicalModel with rock, fluid, saturationVarNames, componentVarNames
saturations, pressures, and temperature.
Base class for all reservoir models. % Iterations parameters
Added primary variables: sα , p, T, qα , pbh dpMaxRel, dpMaxAbs, dsMaxRel, dsMaxAbs
maximumPressure, minimumPressure
useCNVConvergence, toleranceCNV
toleranceMB
ThreePhaseBlackOilModel
Extends ReservoirModel with optional so- % Miscellaneous
lution gas and vaporized oil. Base class for :
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel ReservoirModel
Abstract base class for all MRST models. Declaration of physical variables:
Contains logic related to linearization and
updates. function [fn,ix] = getVariableField(model, name)
Primary variables: None switch(lower(name))
case { ' pressure ' , ' p ' }
ix = 1;
fn = ' pressure ' ;
ReservoirModel case { ' s ' , ' sat ' , ' saturation ' }
Extends PhysicalModel with rock, fluid, ix = ' : ' ;
saturations, pressures, and temperature. fn = 's ' ;
Base class for all reservoir models. case { ' sw' , ' water ' }
Added primary variables: sα , p, T, qα , pbh ix = model.satVarIndex('sw');
fn = 's ' ;
:
end
ThreePhaseBlackOilModel
Extends ReservoirModel with optional so- Plus a large number of utility functions to extract,
lution gas and vaporized oil. Base class for
update, and store these physical variables
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel ReservoirModel
Abstract base class for all MRST models. The class declares known drive mechanisms:
Contains logic related to linearization and
updates. function forces = getValidDrivingForces(model)
Primary variables: None forces = getValidDrivingForces
@PhysicalModel(model);
forces.W = [];
forces.bc = [];
ReservoirModel forces.src = [];
Extends PhysicalModel with rock, fluid, end
saturations, pressures, and temperature.
Base class for all reservoir models.
and define how to evaluate relative permeability,
Added primary variables: sα , p, T, qα , pbh
get surface densities, etc.
The class also specifies how to add well equations,
source terms, and boundary conditions to the
ThreePhaseBlackOilModel
equation system, but does not implement specific
Extends ReservoirModel with optional so-
lution gas and vaporized oil. Base class for
flow equations.
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel ReservoirModel
Abstract base class for all MRST models.
Contains logic related to linearization and Default discretization is a two-point method:
updates.
Primary variables: None function model = ...
setupOperators(model,G, rock, varargin)
model.operators = ...
setupOperatorsTPFA(G, rock, varargin{:});
ReservoirModel end
Extends PhysicalModel with rock, fluid,
saturations, pressures, and temperature.
Base class for all reservoir models.
Added primary variables: sα , p, T, qα , pbh
ThreePhaseBlackOilModel
Extends ReservoirModel with optional so-
lution gas and vaporized oil. Base class for
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Functionality through inheritance
PhysicalModel ThreePhaseBlackOilModel
Abstract base class for all MRST models. Implementes specific equations, which in this case
Contains logic related to linearization and
updates. is a general black-oil model with dissolved gas and
Primary variables: None vaporized oil.
Evaluation of residual equations:
[problem, state] = ...
ReservoirModel equationsBlackOil(state0, state,...
Extends PhysicalModel with rock, fluid, model, dt, drivingForces, varargin)
saturations, pressures, and temperature.
Base class for all reservoir models.
Details of this function is as given for two-phase
Added primary variables: sα , p, T, qα , pbh
case above, but with more features and logic that
switches unknowns depending on phases present
ThreePhaseBlackOilModel
Extends ReservoirModel with optional so-
lution gas and vaporized oil. Base class for
two- and single-phase versions.
Added primary variables: rs , rv
113 / 117
Constructing a simulation model from ECLIPSE input
Input deck
Data
Input parser
Class
Reads complete simulation decks:
grid and petrophysics, fluid and rock Struct
properties, region information, well
definitions, operating schedule, con- Function
vergence control, etc
Input
Contains
0.8
Physical variables inside
0.6
the wellbore
qsw , qso , qsg , qsp , pbh
0.4
0.2
0
0 0.2 0.4 0.6 0.8 1
114 / 117
ECLIPSE input decks
-- =====================================================================
-- THIS IS THE FIRST SPE COMPARISON PROBLEM,"COMPARISON OF SOLUTIONS TO A
RUNSPEC – simulation description (name of the case, grid -- THREE-DIMENSIONAL BLACK-OIL RESERVOIR SIMULATION PROBLEM", REPORTED
-- BY AZIS AND ODEH AT THE SPE SYMPOSIUM ON RESERVOIR SIMULATION ,
-- JANUARY 1981. IT IS A NON SWELLING AND SWELLING STUDY. A REGULAR
dimensions, phases and components present, number of -- GRID WITH TWO WELLS (INJECTOR AND PRODUCER)AND A IMPES SOLUTION METHOD
-- IS USED FOR THIS SIMULATION.THE PRODUCTION IS CONTROLLED BY FLOW RATE
wells, table dimensions, etc) -- AND MIN. BHP. OIL RATE, GOR, PRESSURE AND GAS SATURATION ARE TO BE REPO
-- =====================================================================
RUNSPEC
TITLE
GRID – grid geometry/topology and petrophysical properties ODEH PROBLEM - IMPLICIT OPTION - 1200 DAYS
DIMENS
(porosity, permeability, net-to-gross). 10 10 3 /
NONNC
GAS
FIELD
NUPCOL
START
curves, average pressure, etc) to summary file after each 19 ’OCT’ 1982 /
NSTACK
time step (optional) 24 /
--FMTOUT
UNIFIN
output of cell properties --NOSIM
--IMPES
wells, table dimensions, etc) -- PERMEABILITES ARE THEN SET FOR EACH LAYER. THE CELL TOP DEPTHS
-- ( TOPS ) ARE NEEDED ONLY IN THE TOP LAYER ( THOUGH THEY COULD BE.
-- SET THROUGHOUT THE GRID ). THE SPECIFIED MULTZ VALUES ACT AS
-- MULTIPLIERS ON THE TRANSMISSIBILITIES BETWEEN THE CURRENT LAYER
GRID – grid geometry/topology and petrophysical properties -- AND THE LAYER BELOW.
INIT
PERMX
100*500.0
PROPS – rock-fluid and PVT properties 100*50.0
100*200.0
/
wells, table dimensions, etc) -- Generated with MRST’s family_1() function from the original deck.
-- SWAT
SWOF
KRW KRO PCOW
0.120000000000000 0 1.000000000000000
SGOF
REGIONS – spatial dependence for initialization, rock-fluid 0
0.001000000000000
0
0
1.000000000000000
1.000000000000000
0.020000000000000 0 0.997000000000000
and PVT properties (optional) 0.050000000000000
0.120000000000000
0.005000000000000
0.025000000000000
0.980000000000000
0.700000000000000
0.200000000000000 0.075000000000000 0.350000000000000
14.7 3.0E-6 /
Data file: SPE1 benchmark -- PVT PROPERTIES OF DRY GAS (NO VAPOURISED OIL)
-- WE WOULD USE PVTG TO SPECIFY THE PROPERTIES OF WET GAS
--
-- PGAS BGAS VISGAS 115 / 117
ECLIPSE input decks
SOLUTION ===============================================================
-------- THE SOLUTION SECTION DEFINES THE INITIAL STATE OF THE SOLUTION
RUNSPEC – simulation description (name of the case, grid -------- VARIABLES (PHASE PRESSURES, SATURATIONS AND GAS-OIL RATIOS)
------------------------------------------------------------------------
-- DATA FOR INITIALISING FLUIDS TO POTENTIAL EQUILIBRIUM
dimensions, phases and components present, number of --
-- DATUM DATUM OWC OWC GOC GOC RSVD RVVD SOLN
0 8200
PCOG TABLE TABLE
0 1 0
METH
0 /
GRID – grid geometry/topology and petrophysical properties -- VARIATION OF INITIAL RS WITH DEPTH
--
-- DEPTH RS
(porosity, permeability, net-to-gross). -- RSVD
-- 8200 1.270
-- 8500 1.270 /
SGAS
-- RS
SUMMARY – specifies output of reservoir responses (well -- 300*226.1966570852417
-- /
RS
curves, average pressure, etc) to summary file after each 300*1.27
/
time step (optional) -- OUTPUT CONTROLS (SWITCH ON OUTPUT OF INITIAL GRID BLOCK PRESSURES)
RPTSOL
1 11*0 /
SOLUTION – specifies how the model is to be initialized -- PRESSURE IN INJECTION AND PRODUCTION CELL
BPR
10 10 3 /
SUMMARY – specifies output of reservoir responses (well 1 1 1 /
/
--IMPES
curves, average pressure, etc) to summary file after each -- PRODUCTION WELL CONTROLS
--
-- WELL OPEN/ CNTL OIL WATER GAS LIQU RES BHP
time step (optional) --
WCONPROD
NAME SHUT MODE RATE RATE RATE RATE RATE
-- YEAR 1
Data file: SPE1 benchmark TSTEP
--0.2343 0.1393 0.1840 0.2189 0.2235
1.0 2*2.0 2*5.0 5*10.0 11*25.0 115 / 117
Example: the SPE 9 benchmark
J. E. Killough (1995). Ninth SPE comparative solution project: A reexamination of black-oil simulation, doi: 10.2118/29110-MS 116 / 117
Example: the SPE 9 benchmark
G = initEclipseGrid(deck);
G = computeGeometry(G);
rock = initEclipseRock(deck);
rock = compressRock(rock, G.cells.indexMap);
fluid = initDeckADIFluid(deck);
J. E. Killough (1995). Ninth SPE comparative solution project: A reexamination of black-oil simulation, doi: 10.2118/29110-MS 116 / 117
Example: the SPE 9 benchmark
state = struct('s', s0, ' rs ' , rs0, ' rv ' , rv0, ' pressure ' , p0);
Generally, one may have to solve an equilibrium problem to set the initial state.
J. E. Killough (1995). Ninth SPE comparative solution project: A reexamination of black-oil simulation, doi: 10.2118/29110-MS 116 / 117
Example: the SPE 9 benchmark
J. E. Killough (1995). Ninth SPE comparative solution project: A reexamination of black-oil simulation, doi: 10.2118/29110-MS 116 / 117
Example: the SPE 9 benchmark
J. E. Killough (1995). Ninth SPE comparative solution project: A reexamination of black-oil simulation, doi: 10.2118/29110-MS 116 / 117
Example: the SPE 9 benchmark
J. E. Killough (1995). Ninth SPE comparative solution project: A reexamination of black-oil simulation, doi: 10.2118/29110-MS 116 / 117
Example: the SPE 9 benchmark
Solving timestep 01/35: -> 1 Day
Well INJE1: Control mode changed from rate to bhp.
Grid: 24×25×15, 9000 cells ==================================================
| It # | CNV_W | CNV_O | CNV_G | MB_W
3-phase model, dissolved gas but no vaporized oil ==================================================
| 1 | 2.82e-02 | 1.10e+00 | 5.00e-03 | 1.03e-05
1 water injector, rate controlled, switches to bhp | 2 | 1.14e-01 | 7.25e-02 | 8.13e-02 | 5.21e-06
Well PROD26: Control mode changed from orat to bhp
25 producers, oil-rate controlled, most switch to bhp | 3 | 7.29e-03 | 1.29e-02 | 7.41e-02 | 3.40e-06
| 4 | 1.68e-03 | 3.79e-03 | 1.85e-02 | 7.87e-06
Appearance of free gas due to pressure drop | 5 |*9.60e-04 | 6.20e-03 | 4.29e-03 | 1.64e-06
| 6 |*6.79e-04 | 1.45e-03 |*9.00e-04 | 1.19e-06
From: ad-blackoil/examples/spe9/blackOilTutorialSPE9 | 7 |*2.66e-04 |*8.31e-04 |*5.90e-04 | 2.56e-07
| 8 |*8.83e-05 |*3.48e-04 |*8.72e-05 |*4.58e-08
| 9 |*2.08e-05 |*7.35e-05 |*4.96e-05 |*1.05e-08
==================================================
Solving timestep 02/35: 1 Day -> 2 Day
Run the schedule :
:
model.verbose = true;
fn = getPlotAfterStep(state0, model, schedule, ...
' plotWell ' , false, ' plotReservoir ' , false);
We give the schedule with well controls and control time steps. The simulator may use
other timesteps internally, but it will always return values at the specified control steps.
Setting model.verbose=false removes extensive reports about convergence, etc.
J. E. Killough (1995). Ninth SPE comparative solution project: A reexamination of black-oil simulation, doi: 10.2118/29110-MS 116 / 117
Example: the SPE 9 benchmark
Here, you can plot bottom-hole pressures, reservoir and surface rates, oil and water
cut, gas-oil ratio, etc. Plots are versus time or time step, and can be instantaneous or
cummulative.
J. E. Killough (1995). Ninth SPE comparative solution project: A reexamination of black-oil simulation, doi: 10.2118/29110-MS 116 / 117
Example: the SPE 9 benchmark
MRST
2.5
Grid: 24×25×15, 9000 cells ECL
From: ad-blackoil/examples/spe9/blackOilTutorialSPE9
0
0 0.5 1 1.5 2
Time (years)
MRST also offers functionality for processing ECLIPSE output. We can use
this to compare results from the two simulators:
compare = fullfile(mrstPath('ad−blackoil'), 'examples', ' spe9 ' , ' compare' );
smry = readEclipseSummaryUnFmt(fullfile(compare, 'SPE9'));
compd = 1:(size(smry.data, 2));
Tcomp = smry.get(':+:+:+:+', 'YEARS', compd);
comp = convertFrom(smry.get('PROD13', 'WBHP', compd), psia)';
T = convertTo(cumsum(schedule.step.val), year);
mrst = getWellOutput(wellsols, 'bhp', 'PROD13');
117 / 117