This example demonstrates how to perform a single-phase upscaling of the absolute permeability for a 2D Cartesian model. The routines we use are also applicable in 3D.
We consider two different grids: a fine scale grid that represents the original model and a coarse-scale grid that represents the upscaled model in a way that is independent of the original fine-scale model. For the fine-scale model we define a lognormal permeability field.
To compute the upscaled permeability, we need to define a coarse-grid structure that describes how the coarse grid relates to the fine grid. In our case, this is simple: the coarse grid is uniform partition of the fine grid.
p = partitionUI(G, upscaled);
p = processPartition (G, p, 'Verbose', verbose);
CG = generateCoarseGrid(G, p, 'Verbose', verbose);
rockUps.perm = upscalePerm(G, CG, rock, 'Verbose', verbose);
Elapsed time is 0.079428 seconds.
Computing upscaled permeabilities... Elapsed time is 0.274742 seconds.
Plot permeabilities
Whereas the fine-scale permeability field is isotropic, the upscaled permeability field is anisotropic and we therefore plot both the components in both directions. In addition, we present a histogram of the original permeability and the upscaled permeability projected back onto the fine grid to more clearly show how upscaling reduces the span and tends to cluster values around the median of the fine-scale distribution.
To compare the models, we set up a simple case with a unit pressure drop from south to north and compare the normal velocities on the outflow boundary to the north. Fluid parameters are typical for water.
The smoothing effect of the upscaling procedure is apparent. Whereas the total outflow is very close in the two models, we see that there is significant variation in the fine-scale model that is not captured by the coarse-scale model.
flux1 = sum(xRef.flux(faces));
flux2 = sum(xUps.flux(faces_ups));
disp(['Sum outflux on fine scale : ', num2str(flux1)]);
disp(['Sum outflux on coarse scale : ', num2str(flux2)]);
flux1_face = xRef.flux(faces) ./G.faces.areas(faces);
flux2_face = xUps.flux(faces_ups)./G_ups.faces.areas(faces_ups);
clf; hold on
x = G.faces.centroids(faces,1); dx = diff(x);
stairs([x-.5*dx(1); x(end)+.5*dx(end)], flux1_face([1:end end]), 'r-')
x = G_ups.faces.centroids(faces_ups,1); dx = diff(x);
stairs([x-.5*dx(1); x(end)+.5*dx(end)], flux2_face([1:end end]), 'b-')
hold off
title('Normal velocity on outflow boundary')
legend({'Fine scale', 'Upscaled'},'Location','best')
Sum outflux on fine scale : 2.6179e-07
Sum outflux on coarse scale : 2.4211e-07