DFNE Examples

DFNE Examples, ADFNE series

Using ADFNE for generating, simulation and characterization of fracture networks is quite straightforward and easy. In the following examples, you can see how short, readable and sensible its applications are. Read the License at Rights page.

% Alghalandis Discrete Fracture Network Engineering (ADFNE)
% Author: Younes Fadakar Alghalandis
% Copyright (c) 2016 Alghalandis Computing @ http://alghalandis.net
% All rights reserved.

% Example Applications of ADFNE:
% Density Analysis of 2D Fracture Networks

n = 200; %number of fractures
gn = 20; %block number
lines = GenFNM2D(n, 0, 0, 0.05, 0.5); %fracture network
[dn, x, y] = Density2D(lines, gn, gn); %true density
sdn = Smooth(dn, 1); %smoothing
[X, Y] = LinesToXYnan2D(lines); %for performance
clf; %
subplot(121); %
imagesc(x, y, dn); %block map
set(gca, 'YDir', 'normal'); %match axes
hold on; %
plot(X, Y, 'k-', 'LineWidth', 0.7); %overlay fracture network
Titles2D('-=['); %
subplot(122); %
contourf(0:1/(gn-1):1, linspace(0, 1, gn), sdn, 30); %contouring
shading flat; %
hold on; %
plot(X, Y, 'k-', 'LineWidth', 0.7); %
Titles2D('-=['); %
FullScreen(); %fullscreen
SaveFig('density.png', '-r300'); %save resulting graph

% Alghalandis Discrete Fracture Network Engineering (ADFNE)
% Author: Younes Fadakar Alghalandis
% Copyright (c) 2016 Alghalandis Computing @ http://alghalandis.net
% All rights reserved.
% Example Applications of ADFNE:
% Simulation of 3D Fracture Networks
clc;
fnm = GenFNM3DE5(5000, Rad(45), Rad(45), Rad(180), Rad(180));
clf;
DrawPolys3D(fnm);
colors = rand(size(fnm, 1), 4);
SavePolysToVTK3D(fnm, colors, 'FNM3D_5000.vtk');
SaveFig('fnm3d_5000.png');

In this example, a complex 3D fracture network with 5000 fracture is generated. The fractures are oriented towards 180 degree with tolerance of 180 degrees (i.e., omnidirectional). Their dip angles follow 45 degree with tolerance of 45 degrees resulting in a full omnidirectional fracture network. Adjusting the mentioned parameters as apparent from the code above would result in any desired oriented fracture network. The above code plots and saves the resulting fracture networks in graphics format (PNG) and numerical format (VTK). The latter can be imported directly into other applications such ParaView, VisIt and so on.

In this example the Connectivity Field (CF) for 2D fracture networks is demonstrated. The results are shown in the accompanying figure.

function CF2D_demo
% Alghalandis Discrete Fracture Network Engineering (ADFNE)
% Author: Younes Fadakar Alghalandis
% Copyright (c) 2016 Alghalandis Computing @ http://alghalandis.net
% All rights reserved.

% Example Applications of ADFNE:
% Connectivity Field (CF) for 2D Fracture Networks

fnm = GenFNM2D(150, 0, 0, 0.05, 0.5); %fracture network
La = LinesToClusters2D(fnm); %clustering info
gn = 20;
[CF, ~, ~, x, y] = ConnectivityField2DE(fnm, La, gn, gn); %CF
zcf = Resize2D(CF, 3*gn, 3*gn);
scf = Smooth(zcf, 1);
[I, J] = size(zcf);
sx = 0:1/(J-1):1;
sy = linspace(0, 1, I);
[X, Y] = LinesToXYnan2D(fnm);

clf;
set(gcf, 'Colormap', hot)
subplot(221);
FNM('k-');
SET();

subplot(222);
hold on;
BLOCK();
FNM('w-');
SET();

subplot(223);
hold on;
BLOCK();
CONTOUR(0);
FNM('w-');
SET();

subplot(224);
hold on;
CONTOUR(1);
FNM('w-');
SET();

SaveFig('CF2D_demo.png');

function FNM(c) %FNM map
plot(X, Y, c, 'LineWidth', 1); 
end
function BLOCK() %CF block map
imagesc(x, y, CF); 
end
function CONTOUR(t) %CF contour maps
if t==0
contour(sx, sy, scf, 7, 'LineColor', [0.5 0.5 0.5]);
else
contourf(sx, sy, scf, 7);
end
end
function SET()
Titles2D('-=[');
end
end

aa

ADFNE provides an efficient Backbone extraction function for 2D fracture networks. The resulting backbone (skeleton) can be exported as HTML and SVG vector formats.
% Alghalandis Discrete Fracture Network Engineering (ADFNE)
% Author: Younes Fadakar Alghalandis
% Copyright (c) 2016 Alghalandis Computing @ http://alghalandis.net
% All rights reserved.

% Example Applications of ADFNE:
% Extraction of Backbone Structure of 2D Fracture Networks

fnm = GenFNM2D(300); %fracture network
bbn = Backbone2D(fnm, true); %backbone extraction

n = size(bbn, 1); %remove zero length lines
b = false(n, 1);
for i=1:n
line = bbn(i, :);
if all(line==0); continue; end
b(i) = true;
end
bbn = bbn(b, :);

clf
if isempty(bbn)
DrawLines2D(fnm, 0, 0, '-=['); %visualisation of fnm
else
subplot(121);
DrawLines2D(fnm, 0, 0, '-=['); %visualisation of fnm
subplot(122);
DrawLines2D(bbn, 0, 0, '-=['); %visualisation of the backbone
SaveLinesAsHTML2D('backbone.html', bbn); %save Backbone as HTML file
SaveLinesAsSVG2D('backbone.svg', bbn); %save Backbone as SVG file
end
Utilizing Connectivity Field (CF) concept with some adaptation to work with images such as porous media inputs proposes “Connectivity Field Image (CFi) extension” which is implemented as CFPix2D function. The following shows an example application.
% Alghalandis Discrete Fracture Network Engineering (ADFNE)
% Author: Younes Fadakar Alghalandis
% Copyright (c) 2016 Alghalandis Computing @ http://alghalandis.net
% All rights reserved.

% Example Applications of ADFNE:
% Connectivity Field Image (CFi) for 2D Porous Model

mdl = randi([0,1], 100); %porous model
cf = CFPix2D(mdl, 5, false, 4); %CFi

clf;
subplot(121);
imagesc(mdl);
axis image off
subplot(122);
imagesc(cf);
axis image off
Left: input porous media image, Right: resulting CFi map. By setting the resolution to 1 pixel (i.e., equal to the input image) as the following a more interesting finding comes out.
cf = CFPix2D(mdl, 1, false, 4);
So by application of Connectivity Field concept in the format of CFi (Connectivity Field Image) to the input image at the left, the resulting classification map at the right is obtained. This is a brand new topic and has just been discovered by me (14 Jul 2016). While I am still working on its utmost beneficial interpretation, it can shortly be mentioned here that the above classification map demonstrates locations on the input image (i.e., data map) as classified based on their potential connected area size. For the term “potential” refer to the original paper “{Connectivity Field: A Measure for Characterising Fracture Networks}” for details and concepts (pay enough attention to the concept of “support” and its characteristics). Another interesting finding here is that the location classes are spatially localized as shown as islands. Indeed, there are much more interesting interpretations and uses yet to be developed. In the following practice CFi is applied to spatially correlated porous media.
mdl = round(Scale(Smooth(mdl, 1), 0, 1));
Monitoring Connectivity Changes
In the following example, an input sample data shown on the left figure is subject to be examined by CFi for connectivity map. Note, there is one pixel abnormal (disorder) in the data. The resulting CFi map shows how effective the added one pixel is on the connectivity. And for two added pixels check out the following results. These two examples showed the effectiveness of CFi in detecting changes in the connectivity caused by small changes in the input maps.

In the following example, pipe model of 3D fracture network is constructed. (New function FNMPipes3D).

% Alghalandis Discrete Fracture Network Engineering (ADFNE)
% Author: Younes Fadakar Alghalandis
% Copyright (c) 2016 Alghalandis Computing @ http://alghalandis.net
% All rights reserved.

% Example Applications of ADFNE:
% Pipe Model of 3D Fracture Networks

clear all; clc

fnm = GenFNM3DE5(100, Rad(45), Rad(45), Rad(180), Rad(180), [], 0.35);
[pip, cas] = FNMPipes3D(fnm); %pipes, clusters
c = Colorise(cas);
mc = max(cas); %largest cluster

clf
subplot(121); %fnm
ShowFNM(fnm);
subplot(122); %pipe model
hold on
for i=1:size(pip, 1)
if cas(i)==mc
fc = 'r';
al = 1;
else
fc = [0.7, 0.7, 0.7];
al = 0.3;
end
drawCylinder([pip(i, :), 0.011], 16, 'FaceColor', fc, 'FaceAlpha', al);
end
light('Position', [-1, -1, 1]);
SetAxes3D();
FullScreen();
SaveFig('PipeModel.png');

And here are the results.

The FNMPipes3D function works smoothly on even more complex fracture network such as the following (500 fractures with high interconnection rate) under couple of minutes. Much higher complexities and larger sizes are straightforwardly handled as well, however, would require longer times for execution.

The following figure shows a 3D fracture network with 2000 fractures omnidirectionally oriented which has resulted in 20116 pipes. Max size for fractures was 0.2.

In this example, I will show you how to add inlet and outlet properties into a fracture network model in order to extract its proper pipe model. I will also then show you the extraction of “backbone” for 3D pipe model. Finally, a graph will be built by means of extraction of “nodes” and “edges” from the backbone. Some graph analysis such as popularity index will also be shown.

% Alghalandis Discrete Fracture Network Engineering (ADFNE)
% Author: Younes Fadakar Alghalandis
% Copyright (c) 2016 Alghalandis Computing @ http://alghalandis.net
% All rights reserved.

% Example Applications of ADFNE:
% Fluid Flow through 3D Fracture Networks, Pipe Model (model preparation)

clear all; clc;

% 3D fracture network
fnm = GenFNM3DE5(43, Rad(45), Rad(45), Rad(180), Rad(180), [], 0.5);

% inlet and outlet polygonal sides
p = 0.001; % clipped polygons will intersect
inlet.poly = {[p,0,0; p,0,1; p,1,1; p,1,0]};
outlet.poly = {[1-p,0,0; 1-p,0,1; 1-p,1,1; 1-p,1,0]};

% entire domain
dfn = vertcat(inlet.poly, fnm, outlet.poly);

% pipe model
[pip, cas, cts, xts, ids, La] = FNMPipes3DE(dfn);

if La(1)~=La(end) % check if inlet and outlet are connected
disp('no path found between inlet and outlet!');
return
end

% backbone extraction
bbn = Backbone3D(pip); % 3D backbone

% graph preparation
[nodes, edges] = BackboneToNodesEdges3D(bbn); % backbone to nodes and edges
pul = cellfun(@numel, nodes.values); % popularity index
pts = Stack(nodes.keys); % node locations

As you can see in the above program, GenFNM3DE5 generates 3D fracture network, FNMPipes3DE extracts pipe model from the network, Backbone3D extracts backbone from the pipe model, and finally BackboneToNodesEdges3D generates a graph (nodes and edges). I have also added another new function DrawPipes3D that handles visualization of pipes, backbone and more for your convenience. It distinguishes between inlet, outlet and backbone paths (pipes). See an example code below.

ii = 1; % inlet index
oi = size(dfn, 1); % outlet index
DrawPipes3D(pip, ids, cas, [], {ii, 'r', 0.007}, {oi, 'g', 0.007}, {[0.7, 0.7, 0.7], 0.007}, false)

And so here are the results.

Note that how stage by stage isolated pipes are removed. In the last figure, for example, you can see that even those pipes (light blue) that do not contribute to the fluid flow are removed from the backbone (red) and they do not appear in the graph as well. Having nodes and edges (graph) structure built, the next stage for fluid flow modeling is to initialize inlet, outlet and backbone nodes and edges values. A {simple finite difference} method would suffice this stage.

The following example shows a full framework of the fluid flow modeling through fracture network.
Discrete Fracture Network Model (n=150, Omnidirectional, L(max)=0.4) Pipe Model, Determined Inlet and Outlet from the rest

Graph (Nodes and Edges) + Relationships (nn, etc). Fluid Flow using Finite Difference Method (Red to Blue, High to Low Pressures)