Contents
require coarsegrid
Partition a Cartesian 2D grid
We use partitionUI which exploits the logical structure and creates a uniform grid in logical space.
clf; G = cartGrid([20,20]); p = partitionUI(G, [5,5]); plotCellData(G, p, 'EdgeColor', 'w'); colorbar

Partition a 3D grid in much the same manner
G = cartGrid([20,20,8]); p = partitionUI(G, [5,5,3]); clf plotCellData(G, p, 'Edgecolor', 'w') view(60,30);

Create a faulted grid and partition it
We create a grid and partition it logically in ij-space and along specific layers along the k-space.
grdecl = simpleGrdecl([10 10 7], .15); G = processGRDECL(grdecl); % Layer 1 will go from 1 to 3 - 1, layer 2 from 3 to 6 - 1 and so on L = [1 3 6 8]; % We can easily find the thickness of the layers diff(L) %#ok intentional display % The partition is disconnected across the fault. processPartition can % amend this by adding new coarse blocks. p_initial = partitionLayers(G, [5,5], L); p = processPartition(G, p_initial); figure(1); clf plotCellData(G, mod(p_initial, 7), 'Edgecolor', 'w') title(['Before processPartition (Total blocks: ' num2str(numel(unique(p_initial))) ')']) view(60,30); figure(2); clf plotCellData(G, mod(p, 7), 'Edgecolor', 'w') title(['After processPartition (Total blocks: ' num2str(numel(unique(p))) ')']) view(60,30);
ans = 2 3 2


Geometry information can be added to a coarse grid
By calling coarsenGeometry on a grid which has been returned from processGeometry, we can get coarse centroids, volumes and so on.
G = computeGeometry(G); CG = generateCoarseGrid(G, p); CG = coarsenGeometry(CG); clf cg_cent = CG.cells.centroids; g_cent = G.cells.centroids; hold on; plotPts = @(pts, varargin) plot3(pts(:,1), pts(:,2), pts(:,3), varargin{:}); plotPts(cg_cent, '*r'); plotPts(g_cent, '.') plotGrid(G, 'FaceColor', 'none', 'EdgeAlpha', .1) outlineCoarseGrid(G, p, 'facealpha', .1); hold off view(15,85); % axis tight off legend({'Coarse centroids', 'Fine Centroids'}, 'Location', 'NorthOutside')

The coarse grid contains maps to fine scale
%The coarse grid also contains lookup tables for mapping the coarse grid to %fine scales. Here we visualize a single coarse face consisting of several %fine faces along with its neighbors in red and blue respectively on the %fine grid. i = 300; sub = CG.faces.connPos(i):CG.faces.connPos(i+1)-1; finefaces = CG.faces.fconn(sub); neighbors = CG.faces.neighbors(i,:); clf plotFaces(G, finefaces) plotGrid(G, p == neighbors(1), 'facec', 'red', 'facea', .3) plotGrid(G, p == neighbors(2), 'facec', 'blue', 'facea', .3) view(-50, 10)

No need for logical indices
The partition vector is just that - a vector with one entry for each fine cell containing the partition the cell belongs to. We can generate an arbitrary coarse grid without using any information relating to a structured grid.
For instance, if we want to partition a grid uniformly in space based on cell coordinates, the product of two periodic functions will do nicely. We divide the grid into a 3x3 coarse grid in this way by exploiting that the sine function changes sign in intervals of pi.
nx = 3; ny = 3; G = cartGrid([20, 20], [1 1]); G = computeGeometry(G); % First create the periodic function f = @(v) sin(pi*nx*v(:,1)) .* sin(pi*ny*v(:,2)); % Evaluate it in the centroids fval = f( G.cells.centroids); % We divide the grid into two parts based on the sign of the function p = double(fval > 0) + 1; % Which is then postprocessed to create connected domains. p = processPartition(G, p); % This vector can generate coarse grids just as partitionUI did. CG = generateCoarseGrid(G, p); clf % Plot the function values subplot(1,2,1); v = reshape(f(G.cells.centroids), G.cartDims(1), G.cartDims(2)); surf(v) title('f(x)') subplot(1,2,2); % Plot the resulting partitions title('Resulting partition') plotCellData(G, mod(p, 13), 'EdgeColor', 'w');

Solvers using coarse grids
Some solvers may use the coarse grids. Utilities such as coarsenBC make it easier to solve problems at several scales.
% Trivial fluid fluid = initSingleFluid('mu', 1, 'rho', 1); % Uniform permeability and a pressure drop rock.perm = ones(G.cells.num, 1); T = computeTrans(G, rock); state = initState(G, [], 0); bc = pside([], G, 'left', 100*barsa); bc = pside(bc, G, 'right', 0*barsa); % Solve for fine scale state = incompTPFA(state, G, T, fluid, 'bc', bc); % Use the provided coarse grid CG = coarsenGeometry(CG); % Create the same trivial permeability. This could be replaced by for % example an upscaling routine from the upscaling module if the % permeability was non-uniform. rock.perm = ones(CG.cells.num, 1); T_coarse = computeTrans(CG, rock); state_coarse = initState(CG, [], 0); % Take the existing boundary condition and sample it in the coarse grid. bc_coarse = coarsenBC(CG, bc); state_coarse = incompTPFA(state_coarse, CG, T_coarse, fluid, 'bc', bc_coarse); % Plot the solutions subplot(2,1,1) plotCellData(G, state.pressure, 'edgec', 'k') title('Fine scale solution') subplot(2,1,2) plotCellData(G, state_coarse.pressure(p), 'edgec', 'k') title('Coarse scale solution')
