Carbon Sequestration Using the MATLAB Reservoir Simulation Toolbox (MRST)
Francesca Watson, SINTEF Digital
Modeling geological storage of carbon dioxide is characterized by scarce data, large spans in spatial and temporal scales, and delicate balances between different physical flow mechanisms. The MATLAB® Reservoir Simulation Toolbox (MRST) offers a set of simulators and workflow tools that have been specially designed to meet these challenges. The software combines results from more than a decade of academic research and development in CO2 storage modeling into a unified toolchain that is easy and intuitive to use.
You’ll see a demonstration of functionality from MRST applied to studying hypothetical carbon storage in large-scale aquifer systems from the Norwegian continental shelf. You’ll also discover tools and GUIs which can be used in a workflow from regional scale estimates to a detailed characterization of a specific storage site, including:
- Static capacity estimates
- Basic analysis of CO2 trapping mechanisms at a specific reservoir
- Interactive simulation of CO2 injection where various simulation parameters (well locations, injection rates, and boundary conditions) can be varied through a GUI
- Detailed simulation of a specific CO2 injection site
The reference application is free to download.
Published: 21 Nov 2021
Hi, I'm Francesca. I work in the Computational Geosciences department of Sintef Digital in Oslo. And we are the primary developers behind the MATLAB Reservoir Simulation toolbox.
In this presentation, I'm going to give you a quick demonstration of some of the functionality we have for carbon sequestration modeling. This presentation is actually a shortened version of the webinar that I've been giving for the MathWorks Oil and Gas Webinar series. So if you're interested in more detail, you can have a look at the videos for that on the internet.
So the first parts of the talk will be an introduction to the MRST software. And I'll also gave a brief introduction to the CO2 lab module, which we have for modeling CO2 storage in saline aquifers. And then the main part of the presentation will be a demonstration of the carbon sequestration reference application, which can be downloaded for free from the MathWorks website. So you can download this and run the code yourself.
So MATLAB Reservoir Simulation Toolbox, or MRST for short, is a set of open source tools for reservoir simulation, which had been written in MATLAB. And we designed the toolbox so that you only need a basic MATLAB license. So no external libraries are needed.
The unique thing about this is that we can actually use it for very quick prototyping. Because everything is written in MATLAB, so you can use the MATLAB debugger and quickly change things. But we also have industry standard data formats. So if you had, for instance, an eclipse deck, you could input that into the software and, using a few commands, run a simulation on that deck.
Within our research group, we research state-of-the-art methods for reservoir simulation. And quite a lot of these methods end up in the code very quickly for people to use. It's also fully differentiable. And we have C and C++ acceleration, which means that if we have larger models, we can use the compile backend and run them in reasonable time. We also have quite a wide user base all over the world with several academic publications written about using the software, and also a couple of open-access textbooks.
The design of the software is modular. So we have a small MRST core, which has some of the functionality that's needed for most of the things that people will need. And then we also have add-on modules that do different things. So we have modules, for instance, for gridding or for fractures or flow diagnostics, and many more.
And if you're interested in finding out what they are, I suggest you go to our website, which is www.mrst.no, and you'll find a lot more information there about all the modules that we have. In the latest release, which is MRST 2021b, we have 60 add-on modules. And we also have modules that have been contributed by external people who are outside our group in different institutions.
So for the CO2 modeling part, we have a module called co2lab. One of the main things about this is that we use the vertical equilibrium modeling within co2lab. And this allows us to model large reservoirs very quickly.
So for vertical equilibrium modeling, we assume that the vertical fluxes happen instantaneously and the system is in equilibrium very fast. And this is something that applies when you have large contrasts in buoyancy between the fluids that you're modeling. So for instance, CO2 is much less dense in the water, so it will move vertically very quickly.
So this way, we can model the horizontal fluxes numerically. And then we can assume the system is in equilibrium and use that assumption to work out how thick the CO2 layer is, which means that we can run simulations of large areas very quickly, because we're only modeling in 2D instead of 3D.
Within the co2lab module, we have functionality for doing large scale regional models, static capacity estimates, all the way down to more detailed dynamic capacity estimates of specific reservoir sites. And we have lots of graphical user interfaces that help me to do this in a relatively simple way. And I'm going to show you some of those now.
So the model that I'm going to be showing is the reference application that is available on MathWorks' website. And you can go to the link at the bottom and download it. And then you should be able to run the code that I am about to show you.
So if we go to my MATLAB screen here, so when you download the reference application, you'll end up with a folder which contains an M file and an HTML file. But here I've just opened the M file as a live script in the left-hand window.
The other thing that you need to download is the MRST software itself. So that to do that, you need to go to the website at mrst.no, download the latest release, which will come as a zip file, unzip the file, and navigate to the folder where you unzipped it, and run the startup command.
When you do that, you'll get a startup message that looks like this. And that sets up all the paths for you, and also has some useful information and links that you can have a look at.
So first of all, when you want to run this application, the first thing you need to do is run this first line here, which will add the modules that we need. So I will run this here. And here, we can add the co2lab module, the modules for gridding, and some other modules that we need for the simulation.
So the first graphical user interface I'm going to show you is called exploreCapacity. And if you run this part of the code, then we should have a graphical window which will pop up. And that will show us some static storage capacity estimates, if I just run this here.
And static storage capacity estimates are the theoretical total amount of CO2 that could be stored within a reservoir site. So if you filled all the whole reservoir with CO2 in the areas where it would pull, and then the rest of it was filled with water, we'll have dissolved CO2 up to the maximum amount, and then also a maximum amount of residual saturation.
So you can see here, on the left, we have loaded a reservoir model. In this case, it's the Utsira formation. We also have a dropdown box here so you can choose different formations from the Norwegian North Sea. But here we'll stick with Utsira.
We also have some buttons on the right here, which can plot different things. So I'll plot the structural traps, which are the bumps in the surface where the CO2 can pull. And we can see we have an estimate of the trapping capacity down here and the different types of trapping mechanisms.
And so basically, we can use this GUI and move these sliders around. And that will change the total static capacity estimates. And we can play around with these and see what our maximum capacity is.
So that was a brief introduction to the first GUI. If you look on this live script, there are many links. So you can have a look and find out a lot more information about all the different inputs to the user interface. And we have a lot of information on our website.
The next user interface will look at the structural charts. And in this case, we're going to be using the Johansen formation. So I'll will run this bit of script to create the grid.
And we can see the grid down here. So this is a 3D grid. For the vertical equilibrium assumption, we need a top surface grid, so a 2D grid. So here, you can see that it's plotted on top of the 3D grid in blue.
And here we run the trap analysis algorithm. So this analysis is analogous to if you had watershed analysis. So for that, we would look at water moving down a surface and pooling at the bottom. The CO2, we look at water moving up the top surface upslope and pooling at the top of the reservoir in the box.
So this is a plan view of the reservoir. The areas in red are the CO2 traps. And we can see that we have quite a lot of small traps and a few big traps.
So we also want to have a look at the flow path between the traps. And we can see those here. And these are the black lines that show how the CO2 would move along the surface of the reservoir and pool in the traps. And this plot here shows that we have quite a lot of small traps down here with small volume, and a few large ones up here.
So we can also have a look at that a little bit more interactively. So we run the interactive trapping user interface. And that comes up with a picture that looks something like this.
So this is the same reservoir on the left. And if you can see this red line here, this is the well. And if I click anywhere in this GUI, I can move the location of the well.
So when I move it to here, you can see that this gray trap is where we would inject. And then we would also be able to connect these other traps, if we had an injection location here.
So if you look at the pie chart on the right, you can see that 60% of the trapping capacity of the reservoir is in the primary trap, the first trap that we inject into. 2% is in the migration, so these traps that the CO2 is migrated into.
And then up here, we have 37% of the total tracking capacity that isn't accessed. So we can move the well around by clicking within this grid. And we can see, if we put the well down here, we can access a little bit more of the trapping capacity. . If we put it down here, because we're much further down slope, we can access all of these traps here.
So in this case, 90% of the traps are accessed by a migration. And 7% of the storage capacity is not filled, which is not much better than where we had the well in the first place.
So you can also run simulations from this GUI by clicking up here. And we can also change some of the plotting. But I don't have time to show you that now. There's more information about that in the longer webinar, which is on the website.
So that was looking at static storage capacity estimates. Now we're going to set up a simulation using a graphical user interface, and get some more information about the dynamic properties of the reservoir and a dynamic simulation.
So here we have same, again, on the left, the Utsira Formation. We have green boundaries, which indicate that these are open boundaries. First of all, I'm going to click this button here. And this shows where the traps are. So these are the structural traps, the bumps in the cap rock.
So to set up a simulation, first thing I'm going to do is edit the boundaries. So if I click here to edit boundaries and here to close, I can click within this grid and set, for instance, a closed boundary on this bit here.
The next thing I want to do is add some wells, so I'll put a well here and maybe a well here. And then I'm going to change the injection time and the number of injections steps, and then the migration time, so something like this. And then click Launch Simulation.
So you can actually change quite a lot of the properties here. You can have different wells. And you can have different boundaries. And this image here, you can see how the CO2 is migrating throughout the injection period as the simulation is running. So here we are getting updated results as the simulation is running.
And as you can see, it's not actually all that exciting where I've stuck this well, because I've put a closed boundary up here. And also the CO2 is just migrating up towards this closed boundary, because this is upslope from the well injection point.
But that's how to set up a simulation that way. And once the simulation is finished, it will get a plot that looks something like this. So here we can see time along the bottom. And then this is mass. But this is talking about different trapping mechanisms.
So as time goes along, we see that the amount of CO2 that's injected in the free plume increases, up to a point. And also the amount of residually trapped CO2 increases through time. So this gives us an indication of the time series of how the trapping changes through time in a reservoir.
And this GUI also allows us to do more complicated setups so we can have a capillary fringe or we could do subscale trapping or dissolution. But these are just things that you can play around with here.
So now we've set up a simulation interactively, finally, I'm going to show you how to set up a simulation using more programmatically. So in this case, we're going to use the Johansen Formation again. And this model has quite a lot of information about it in several publications. And you can click through these links within the live script to find out all about it.
But first, this bit of code that I have just run, it sets up some CO2 parameters and some fluid parameters for the CO2 in the water, and also for the rock. And here for the CO2 properties, we're using the CO2props function, which caused the coolProps library, where we have some tabulated data over the pressures and temperature ranges that we might be interested in. So we can specify the pressure and temperature, and we'd get the CO2 properties that we need.
This next set of code makes the grid here. So here we're using the Johansen grid, which is one we already have within MRST. But it's also possible to load your own grid in if you have a deck file. And there's other tutorials on the MRST website that will show you how to do this.
We also have this bit of code here, which sets up the wells. So we're having an injection well, this one, that will inject CO2. And then we also need to set up the grid and the rocks. And then we need to set up the initial state. So I haven't got time to go through these in detail, but we can set them up and see what happens.
So now we have the grid set up and the well set up, if I run this section of code, we get a nice plot of the reservoir. So here we can see the 2D VE grid in blue. And underneath, just to show you, is the original grid in yellow.
So we'll be simulating on this blue grid. And we have an injection well here at the bottom of this, the reservoir, and then we have a fault here.
So next, we need to set up a fluid model when we have some properties of fluid that we calculated before. And we collect them all together in this fluid structure. We also are using a capillary fringe model in this case. But if you have a look in this function here, makeVEFluid, there's a lot more information in there, which will tell you about the different fluid models that we have.
So the next part of the code sets up some boundary conditions. And we set up the schedule. So we'll have some injection at the start of the simulation. And then we will shut off the injection. And we will just have some migration and see what happens. We also set up some of the time steps. And we tell the schedule which control to use at which time step.
And so this section of code here will actually run the simulation. So I'll set it going while I talk. And while we're running the simulation, what we need to do is we need to first create a model. And to do that, we need the grid, the rock, and the fluid.
And then into the simulateSchedule function, we have the initial state, which is set to be fully filled with water, the model, which we defined here, and the schedule, which we defined in the previous section. But you can go back and look at the code to find out how we set the initial state and look at it in a bit more detail. But there's not enough time to go through it here.
OK, so now the simulation has run through, so we solved 120 years of simulation. And it took about 20 seconds this time. And then we can have a look at the results.
So this bit of code will plot the results like this. So these are the results through time. We can see the CO2 migrates upslope. And we also have a quite thick bit of CO2 here where we have a bump in the cap rock. And if we let the simulation run further, this CO2 would migrate even further upslope.
So that was basically how to set up a simulation from scratch, as opposed to setting up a simulation using the user interface that I showed previously. The final thing to show is that we can take the results from this simulation and we can run the trapping analysis function again.
And we can get a plot similar to what we had last time, which shows us how the different trapping mechanisms have changed through time. So in this, again, we have the time along the bottom. And you can see, very similar to the previous simulation, we have an increase in the CO2 in the free plume up until the injection stops. And then this decreases, and more of the CO2 is trapped in the residual trapping.
So thank you very much. That was all I would like to show you. But I would encourage you to go and look at the reference application on the MathWorks website and download it and play around. And also, have a look at the other webinars that I've given on this, as they go into a lot more detail. I think you'll find that a lot more about it.
Thank you very much.