Discrete Fracture Network (DFN) User Guide
This guide covers the Discrete Fracture Network (DFN) modeling capabilities in VRGS, including generation, visualization, and analysis features.
If you have interpreted trace polylines or structural measurements and want the DFN to match them — derived Fisher statistics, observation-driven P32, placement biased toward your outcrop, validation against observed traces — see the companion DFN Interpretation Matching guide.
Overview
A Discrete Fracture Network (DFN) is a stochastic representation of fracture systems in rock masses. VRGS allows you to:
- Generate statistically-controlled fracture networks from orientation data
- Compute fracture-fracture intersections and fracture traces on outcrop meshes
- Analyze network connectivity and topology using graph theory
- Model stress-controlled fracture propagation
- Create cross-sections through the network
- Filter fractures by proximity to outcrops
- Colour fractures by computed geometric, connectivity, topology, and stress attributes
- Keep mapped fractures where you mapped them while the rest of the network is regenerated
- Solve steady flow through the connected fractures, track particles through it, close apertures under stress, and run ensembles of realisations
Creating a DFN
A DFN is created from orientation (plane attitude) groups, project Sets, or both:
- In the Interpretation tree, right-click an orientation measurement or group, or the Orientation branch header, and choose Create DFN from Groups or Sets...
- Tick the rows you want. Each ticked row becomes one fracture set, named after it.
- Leave Shape each set from its measured lengths and heights ticked to give each set the fracture shape its planes show, or untick it for circular fractures.
- Click OK, read the confirmation box, and click Yes.
The dialog lists every orientation folder holding planes, by its path, and then every Set holding planes, as Set: J1, each with its number of planes.
- A folder takes every plane in it and in its subfolders.
- A Set takes every plane tagged with it, wherever the plane sits in the tree. Use this when the planes are tagged but not sorted into folders, such as straight after Auto-cluster.
- What starts ticked comes from the selection in the tree. A selected folder with planes of its own is ticked, and takes its subfolders with it. A selected folder holding planes only in subfolders stands for those subfolders, so a group that Group by Set has fully sorted ticks one row per set.
- A plane two ticked rows reach counts once, for the first of them, so ticking a folder and a Set that share planes can leave the second short or skipped. The confirmation box shows what each row ended up with.
For each set, VRGS derives the mean orientation and Fisher concentration (K) from the measured poles. If its planes carry trace geometry, a size distribution is also fitted to the trace lengths (see Distribution Fitting); otherwise sensible defaults are used. The source of each derived value is shown in the properties panel (P32 Source, Size Distribution Source, Shape Source).
The names of the source groups and Sets are stored with the DFN, so you can later right-click the DFN and choose Re-derive from Source Orientation Groups to re-run the derivation against updated data.
A set needs three or more measurements, or at least one mapped fracture, and is skipped otherwise. A set with fewer than three measurements takes default dispersion and size parameters. Lineations are left out.
Mapped fractures
A measurement with digitised positions becomes a mapped fracture of its set: a disc at its position, with its measured dip and azimuth and the radius of the smallest sphere round its vertices (1 m for a single point). In a set shaped by its lengths and heights it is an ellipse of its own measured length and height instead. A measurement with no position feeds the statistics only.
- They stay where they were mapped. Regenerate places them first, unchanged, and draws only the rest afresh. The termination rule does not clip or remove them. They are saved with the DFN and come back on load.
- They count toward the target intensity. The stochastic fractures fill the set's P32 Intensity less the area of its mapped fractures. A set whose mapped fractures already reach the target gets no stochastic ones, and keeps every mapped fracture even if that takes it over the target.
- They count toward the generation budget. A set switched off with Enable Set generates nothing, mapped fractures included.
- They are part of the network wherever it is used. Attributes, intersections, flow and Score DFN against Selected Traces... all include them, so a score against the traces the fractures were mapped from is partly circular.
How big a network will be
Before anything is generated, the confirmation box lists each ticked row with its number of measurements and mapped fractures, its mean dip and azimuth and its K, and the number of fractures its set is expected to need, and gives the total and roughly how much memory it would take. The estimate comes from the set statistics alone: the target P32 times the domain volume, less the mapped area, divided by the mean area of one fracture, plus the mapped fractures.
The domain starts as the extent of the whole project and the fracture sizes come from the digitised patches, so a large project with small patches can ask for tens of millions of fractures. One generation places at most what a gigabyte of memory holds, about 1.4 million fractures. When the estimate is over that budget the box says so, and its default answer is No. Choosing Yes creates the DFN capped at the budget: the set that reaches it is cut short, any sets after it get none, and the log carries a warning naming the set and how far short it fell, because its realised P32 is below the target. Then lower each set's P32 Intensity or shrink the Domain in the properties panel, and Regenerate.
Generation can be stopped with the progress bar's Terminate button. A stopped Create DFN leaves nothing in the project.
Setting the Domain
The DFN domain defines the 3D bounding box where fractures are generated. It is set from the extent of the whole project at creation and can be edited in the properties panel under Domain (Min/Max X, Y, Z). A Min above its Max swaps them.
Fit Model Domain to Displayed Data on the DFN's right-click menu sets it to the box around what is displayed in the active 3D window, so ticking only the outcrop you are modelling confines the network to it. It leaves out other DFNs, and what is in a view without being data about the rock: photographs, scan positions and SfM cameras, waypoints, viewpoints and flight paths, scale bars and labels. With several DFNs selected, all of them take the same box. Data with no extent in one direction cannot make a domain, and the command says so.
The fractures stay as they are until they are regenerated, which the command offers. Changing the domain changes the volume P32 is measured against, so a larger box means more fractures. Re-derive from Source Orientation Groups keeps the domain the DFN has.
Fracture Sets
A DFN consists of one or more fracture sets, each with distinct statistical properties. Sets correspond to the orientation groups and project Sets the DFN was created from; each can be enabled/disabled individually (Enable Set).
Fracture Set Parameters
All parameters are edited in the properties panel under Fracture Sets.
Orientation (Fisher Distribution)
| Parameter | Description |
|---|---|
| Mean Dip | Average dip angle (0-90 degrees from horizontal) |
| Mean Azimuth | Average dip direction (0-360 degrees, 0=North) |
| Fisher K | Fisher concentration parameter. Higher values = tighter clustering around mean |
- Fisher K ≈ 1-5: Strongly dispersed orientations
- Fisher K = 10-20: Moderate clustering
- Fisher K = 50+: Tight clustering around mean
When derived from measurements, K is estimated from the resultant length of the pole population using the spherical (3D) Fisher maximum-likelihood estimator and clamped to the range [0.1, 1000].
Size Distribution
| Parameter | Description |
|---|---|
| Size Distribution | Power Law, Lognormal, Exponential, or Uniform |
| Min Radius | Minimum fracture radius, or half the length under Length-Height Fit |
| Max Radius | Maximum fracture radius, or half the length under Length-Height Fit |
| Exponent | For power law distribution (typically 2.0-3.5) |
| Lognormal Mean / Stddev | Parameters of ln(r) for the lognormal distribution. Sampled by exact inverse-CDF truncation to [Min Radius, Max Radius] |
| Exponential Rate | Rate λ of P(r) ~ exp(-λ·r) for the exponential distribution. Larger λ means more small fractures. Leave at 0 to derive it from the size bounds; fitting a size distribution from measurements sets it automatically |
Fracture shape
| Parameter | Description |
|---|---|
| Shape Model | Fixed Aspect Ratio gives every fracture the same shape. Length-Height Fit draws each fracture's height from its length |
| Aspect Ratio | Length along strike / height down dip, for a fixed ratio (1.0 = circular, below 1.0 taller than long) |
| Height Coefficient, Height Exponent | a and b in Height = a × Length^b |
| Height Scatter | Standard deviation of log10 height about that line, in log10 units. 0 puts every fracture on the line |
| Shape Source | Where the relationship came from: the number of measurements and R² it was fitted to, or manual once typed over |
Fractures are rarely one shape at every size: on a log-log plot of length against height they follow a line, with scatter about it. Under Length-Height Fit the set reproduces both. It draws a size from the size distribution, which then means half the fracture's length, and takes the height from the line plus a normal residual of Height Scatter, cut off at three standard deviations. The line and the scatter together are what the covariance of log length and log height describes, so long fractures are not simply scaled-up short ones, and two of the same length can differ in height. No shape goes beyond 1000:1. Each fracture is an ellipse of that length along strike and that height down dip, and the number of fractures P32 asks for allows for its area.
Where the numbers come from. With the box in the Create DFN dialog ticked, each set fits them to its own planes, using a plane's Length and Height attributes when it has both (Create Dimension Attributes, or your own values), or else measuring its digitised vertices, of which it needs three. Five such planes are enough for the set to use the fit, as long as they differ in length; a set with fewer stays circular. The confirmation box gives each set's equation. From ten planes, the size distribution is fitted to their half-lengths. The numbers are the same as a Power best-fit line of Length against Height for those planes, so you can read them off the Charts panel, or type in a published relationship.
Changing an existing DFN. Change the rows and Regenerate. A DFN created with the box unticked still holds the fit, so switching its Shape Model is enough, though its size distribution still describes the circumcircles of the patches rather than half-lengths; Re-derive from Source Orientation Groups on a set using the fit refits both.
Checking it. Generate the Length and Height attributes of the network and plot them on log-log axes with a Power fit: the line should come back to the set's numbers. They are the extents of the whole fracture, before any clipping by the domain.
Rather than typing sizes and intensities, Derive DFN Statistics… (right-click the DFN) lets each set take each statistic from a named source — an orientation group, a trace group, a scanline, or a P21/P32 attribute layer — and cross-checks the intensity routes against each other.
It also handles the fact that a mapped trace is a chord, not a fracture diameter, so sizes fitted from traces are not systematically too small. See DFN — Matching Interpretations §4.
Intensity (P32)
| Parameter | Description |
|---|---|
| P32 Intensity | Fracture area per unit volume (m²/m³) |
P32 is the most robust intensity measure as it is scale-independent. The generator calibrates the fracture count from the expected fracture area of the size distribution (not the mean radius), computed in closed form, so the realized P32 matches the target even for broad power-law size distributions.
Under boundary truncation, fractures centred outside the domain that cross into it are generated too — for every spatial model, not just Poisson. Without that buffer, clipping removes fracture area near the faces with nothing flowing in to replace it, and the realized intensity lands below target (measured at about 11% low for the clustered, stratified and region-mask models before this was added).
The Set Statistics to CSV export reports target against realized P32 per set, and the validation report shows the same comparison graphically.
Spatial Model
| Model | Description |
|---|---|
| Poisson | Completely random (uniform) fracture centres |
| Clustered | Neyman-Scott clustering: a reduced set of parent centres each spawns several fractures within Cluster Radius; Fractures per Cluster sets the mean number of fractures per parent |
| Stratified | Grid-stratified sampling — more even spatial coverage than Poisson |
| Region Mask | Placement biased toward a mask mesh with a Gaussian falloff (Region Mask Falloff); see the Interpretation Matching guide |
Termination Rule
| Rule | Description |
|---|---|
| None | Fractures extend beyond the domain unmodified |
| Truncate at Boundary | Fracture polygons are clipped to the domain box |
| Abutting | Younger fractures terminate against older ones with probability Abutting Probability |
Modelled surfaces are handled separately from this rule — see Model Surfaces below. A set normally wants boundary truncation and bed confinement at the same time, so they are independent settings rather than alternatives.
Model Surfaces
Surfaces produced by the surface gridding can be attached to a DFN to give it a shape other than a box. Right-click the DFN and choose Model Surfaces….
Each attached surface has a role:
| Role | Effect |
|---|---|
| Upper limit | The model exists below the surface. Fractures are clipped at it. |
| Lower limit | The model exists above the surface. |
| Internal barrier | A fracture reaching the surface either crosses it or stops, decided by the crossing probability. |
An upper and a lower limit together define a bed, and a set generated inside it comes out with fractures as high as the bed rather than as high as its fitted size distribution. That is the point: bed-confined (stratabound) fracturing is one of the commonest fabrics in outcrop, and a box cannot express it.
Crossing probability
An internal barrier's crossing probability is the chance that a fracture reaching it carries on through:
- 1.0 — transparent. The surface changes nothing. This is the default, so attaching a surface never alters a model until you tell it to.
- 0.0 — impermeable. No fracture crosses; every set is confined between barriers.
- Anything between — that fraction of fractures crosses.
Each fracture set also has a Surface Crossing Probability in the property bar, which overrides the surface's own value:
| Set value | Meaning |
|---|---|
| -1 (default) | Use whatever each surface says |
| 0 | This set is bed-confined, whatever the surfaces say |
| 1 | This set cuts straight through every surface |
The set wins rather than the two being multiplied together, because a product could never express a through-going master joint set cutting a strong bedding plane — and that is a real and common fabric. With an override, a weak bedding plane can stop the bed-confined sets while the master joints cut it.
Coverage, and where a surface is not mapped
A modelled surface rarely spans the whole domain footprint. Where it does not, it is simply not there: fractures pass through freely and bounding surfaces do not clip. VRGS never extrapolates a surface beyond the data it was gridded from.
That is the honest behaviour, but it is invisible in the result — a bed boundary covering a third of the model produces a network that looks perfectly reasonable and is only bed-confined in a third of its volume. The dialog therefore shows a Coverage column for every surface. If it reads 35%, only 35% of your model is constrained by it.
The volume, and what P32 now means
P32 is fracture area per unit volume, and bounding surfaces change the volume.
Once upper/lower limits are attached, intensity is measured against the bounded volume — the rock between the surfaces — not against the domain box. The dialog states the bounded volume and its share of the box for exactly this reason.
This is the right behaviour: a target P32 of 2 m²/m³ in a 10 m bed means 2 m² of fracture per cubic metre of that bed, which is what a geologist means by it. But it does mean that attaching a bounding surface to an existing model changes what its intensity numbers refer to, so re-check any P32 you derived before.
Target and realised intensity both use the bounded volume, so the two stay comparable and the validation report's intensity panel stays meaningful.
Surfaces that cannot be used
| Source | How its side is decided |
|---|---|
Gridded surface (Grid, from surface gridding) | The mesh is rasterised into a height field in the surface's own frame — its normal, not vertical, so a steep surface works |
| Implicit surface (from the 3D potential field) | The potential field itself, carried straight through. A level set has no preferred axis, so an overturned or recumbent fold works |
Overturned folds therefore bound a DFN correctly. That comes from using the potential rather than the triangles: the sign is stratigraphic, not geometric, so "below the upper limit" means below it in the sequence. On an overturned limb that is the only reading that makes sense — a vertical line crosses the same contact three times, and a geometric "below" would get the middle crossing wrong.
Two cases are still refused, both with a message rather than a silent approximation:
- A gridded surface that folds back on itself. The gridding cannot produce one, but an imported or hand-edited mesh can. Use an implicit surface instead.
- An implicit surface that has not been generated yet. After reopening a project the generator is re-attached but not re-solved. Regenerate the surface and the DFN will pick it up.
Beyond the region the implicit surface was solved over, the potential is extrapolation rather than data, so the constraint lapses there exactly as a gridded surface lapses outside its footprint — visible in the Coverage column.
Generating the Network
- Right-click on the DFN in the Interpretation tree
- Select Regenerate
Each regeneration draws a new statistical realization with the same parameters; mapped fractures stay where they are. The Grow menu item does not regenerate: it runs fracture propagation on the fractures already there, with preset parameters (see Fracture Propagation).
A regeneration clears what described the old fractures: every attribute layer, the intersection lines, the fracture graph and the outcrop-constrained subset. The messages panel says which attribute layers to generate again. It also names any set whose positions fell back to uniform instead of following its Spatial Model, and why: no usable Region Mask Source, a mask too tight to place fractures, or cluster children outside the domain.
When the parameters now ask for more than the generation budget, Regenerate says so and asks first, and so do Override P32 from Selected Traces… and the regeneration offered after Derive DFN Statistics… and Model Surfaces… (see How big a network will be). A regeneration stopped with Terminate leaves the DFN empty rather than holding part of a network; regenerate it again when you are ready.
Visualization
Visibility Options
- The DFN's tick box in the Interpretation tree shows and hides the fracture network
- Show Vertices: Toggle rendering of fracture intersection points
Render Mode
The Render Mode selector in the properties panel controls how fractures are drawn:
| Mode | Description |
|---|---|
| Disks | Filled fracture polygons, coloured by fracture set |
| Outlines | Polygon edges only |
| Colour by Property | Filled polygons coloured by the active attribute layer through the colour map |
Generating an attribute automatically switches to Colour by Property so the result is visible immediately; switch back to Disks at any time without losing the attribute layer.
Stereonet and Rose Diagram
A visible DFN plots on any stereonet — the Charts panel's, or a stereonet window opened from Home → Windows → Stereonet Window — just like measured orientation data (see the Stereonet User Guide):
- Poles: each fracture's pole is plotted, coloured by fracture set (a fixed per-set palette, distinct from the bedding/fracture/cleavage colours used for measured data). Very large networks are uniformly decimated to keep the display responsive while remaining statistically representative.
- Density contours: the Kamb/Schmidt contouring includes DFN poles.
- Rose diagram: fracture azimuths (or strikes, with Strike Values) contribute to the rose petals, density ring, and azimuth dots.
- SVG export includes the DFN poles, mirroring the on-screen display.
To validate a generated network against its source data, check both the DFN and its source orientation groups in the stereonet window — generated and observed poles plot together with distinguishable colours.
Slicers and proximity filtering
See Slicers and Proximity Filtering below.
Intersection Analysis
Fracture-Fracture Intersections
Compute where fractures intersect each other:
- Right-click on the DFN
- Select Fracture Intersections
This creates line segments at all fracture-fracture intersections and automatically builds the connectivity graph from them. The progress bar's Terminate button stops it, and the previous run's lines are then cleared rather than left on screen.
Mesh Intersections
Compute where fractures intersect mesh surfaces (e.g., outcrop models):
- Ensure the target mesh(es) are visible
- Right-click on the DFN
- Select Mesh Intersections
This creates polylines representing the fracture traces on the mesh surface. Each fracture's intersection segments are automatically merged into continuous polylines. Stopped with the progress bar's Terminate button, it creates no polyline group.
It also records which fractures reached the mesh, so they can be displayed on their own — see Outcrop-Constrained Display below.
Outcrop-Constrained Display
Show Outcrop-Constrained Fractures Only (right-click menu) hides every fracture that does not cut the outcrop, leaving only the ones that should correspond to mapped traces. Most of a network never reaches the exposure, so this is the difference between eyeballing a comparable subset and eyeballing a cloud.
The subset comes from the last cut against a mesh (Mesh Intersections, or Score DFN against Selected Traces…), so run one of those first. Regenerating the DFN clears it — fracture identities are reused on rebuild, so a stale subset would name the wrong fractures.
Full guide: DFN — Validating Against Outcrop.
Truncating Against the Boundary
Truncate Against Boundary is on the right-click menu but does nothing at present. To clip fractures to the domain box, set a set's Termination Rule to Truncate at Boundary and Regenerate.
Connectivity Graph
The fracture graph represents network topology using nodes (intersection points) and edges (intersection-line segments between nodes). It is built automatically when you run Fracture Intersections.
Topology classification
Nodes are classified following Sanderson & Nixon (2015):
- I-nodes — free ends of intersection lines (degree 1)
- Y-nodes — abutments, where the end of one intersection line meets the interior of another (degree 3)
- X-nodes — crossings of two intersection lines (degree 4)
The reported proportions P_I, P_Y, P_X are computed over the classified nodes and sum to 1. Connections per line (C_L = 2(N_Y + N_X)/N_lines) and connections per branch (C_B) are also computed.
Graph Analysis
The graph provides:
- Connected component identification
- Node degree analysis (I, Y, X nodes)
- Per-fracture topology and connectivity attributes (see Attributes)
Fracture Propagation
VRGS includes a stress-controlled fracture propagation model that extends fracture tips incrementally.
Propagation Parameters
These are fixed and are not in the properties panel. Grow and the Propagation submenu use different values:
| Parameter | Description | Grow | Propagation submenu |
|---|---|---|---|
| Step length | Distance each tip advances per step | 0.5 m | 1 m |
| Maximum total length | Maximum length a tip can grow | 50 m | 100 m |
| Maximum steps | Maximum propagation iterations | 200 | 1000 |
| Abutting distance | Distance at which tips terminate against other fractures | 0.2 m | 0.1 m |
| Abutting probability | Probability of termination when within abutting distance | 0.9 | 1 |
| Stress shadow distance | Zone of influence around existing fractures | 3 m | 5 m |
| Stress shadow angle | Parallelism threshold: a tip growing within this angular tolerance of a nearby fracture's orientation (and within the shadow distance) terminates | 15° | 20° |
| Direction noise | Random variation in growth direction | 3° | 5° |
Stress Tensor
The propagation direction is influenced by a built-in stress field, not by the project's stress tensors. Grow takes σ1 horizontal and north-south, with σ3 east-west; the Propagation submenu takes σ1 east-west, with σ3 vertical.
- Sigma1: Maximum principal stress direction — in-plane growth is deflected toward it, weighted by the stress anisotropy (σ1 − σ3)/σ1
- Sigma2: Intermediate principal stress
- Sigma3: Minimum principal stress (fractures propagate perpendicular to this)
Running Propagation
Grow on the DFN's right-click menu runs propagation to completion in one go. For more control, from the Attributes node under the DFN, under Propagation:
- Initialize from Tips — creates two growth tips per fracture at the ends of its strike axis
- Either:
- Step: Single growth iteration
- Run to Completion: Run until all tips terminate or Max Steps is reached
The spatial index is refreshed as fractures grow, so abutting and stress-shadow checks always see the current geometry.
Slicers (Cross-Sections)
Create 2D cross-sections through the DFN to visualize fracture traces on orthogonal planes.
Enabling Slicers
In the DFN properties panel:
- Enable X Axis Slicer, Y Axis Slicer, or Z Axis Slicer
- Adjust the slider position (0-100% of domain extent)
Slicer Display
When a slicer is active:
- Fracture disks are hidden
- Intersection lines with the slicer plane are displayed
Multiple slicers can be active simultaneously.
Proximity Filtering
Filter fractures based on their distance to outcrop data (meshes or point clouds).
Enabling Proximity Filter
- In DFN properties, enable Enable Filter under Proximity Filter
- Set the Distance Threshold (meters)
- Optionally enable Invert Filter to show only distant fractures
How It Works
- Distances are computed from fracture centroids to the nearest visible mesh/point cloud
- A distance grid accelerates lookups for large datasets
- Filtering is performed in the GPU shader for smooth interaction
Attributes
DFN fractures support computed attributes for analysis and colour mapping. Generate them by right-clicking the Attributes node under the DFN; the fracture display is coloured by the most recently generated attribute. Connection Mesh for Flow adds layers of its own.
Geometry Attributes
| Attribute | Description |
|---|---|
| Dip | Dip angle (0-90°) |
| Azimuth | Dip direction (0-360°) |
| Length | Fracture extent along strike, before any clipping (called Width before 3.4.20) |
| Height | Fracture extent down dip, before any clipping |
| Area | Fracture polygon area |
| Distance | Distance from the fracture to the nearest visible outcrop |
Connectivity Attributes
| Attribute | Description |
|---|---|
| Fracture Intersections | Number of fractures intersecting this one |
| Connected Groups | Connected-component ID of the fracture |
| Component Size | Number of fractures in this fracture's connected component |
| Total Intersection Length | Summed length of this fracture's intersection lines |
| Intersection Density | Intersection length per unit fracture area |
| Mean Intersection Angle | Mean dihedral angle with intersecting fractures |
Topology Attributes
| Attribute | Description |
|---|---|
| Node Count | Graph nodes on this fracture |
| I-Node Count (Tips) | Free ends (degree 1) |
| Y-Node Count (Abutments) | Abutting junctions (degree 3) |
| X-Node Count (Crossings) | Crossing junctions (degree 4) |
| Branch Count | Graph edges on this fracture |
| Connections Per Line | Y+X junction count for this fracture |
Stress Attributes
Stress attributes are resolved on each fracture plane from the full 3D stress tensor of one of the project's stress tensors (principal magnitudes and plunge/trend directions). Each DFN chooses its tensor, and the stress parameters are shown in the properties panel under Stress Parameters:
| Parameter | Description |
|---|---|
| Stress Tensor | Which tensor's principal stresses to use. The default is Active tensor, which follows Set as Active in the Collections tree. Choosing a tensor by name keeps this network on it whichever tensor is active, and through a rename. Only a valid tensor can be chosen. Needs the Geomechanics licence feature; without it the row is not shown and the network uses the active tensor. If the chosen tensor is deleted the network goes back to the active one, and the messages panel says so. Recompute the stress attributes after changing it. Closure under stress in the connection mesh uses the same tensor. |
| Pore Pressure | Pore fluid pressure Pp (MPa) for effective-stress calculations. |
| Friction Coefficient | Coulomb friction coefficient μ. |
| Cohesion | Cohesive strength C0 (MPa) in the Coulomb criterion. |
The three failure parameters are read-only here: they come from the stress tensor, so edit them in Collections → Stress Tensors. A DFN no longer keeps values of its own. When a project saved with a DFN whose values differed from its tensor's is opened, the DFN is given its own copy of the tensor, named DFN name stress, holding its old values, and the messages panel says so; without the Geomechanics module it takes the project tensor's values, and the messages panel warns that they changed.
| Attribute | Formula | Description |
|---|---|---|
| Normal Stress (σn) | t·n with t = S·n | Stress normal to the fracture plane (MPa) |
| Shear Stress (τ) | √(|t|² − σn²) | Shear stress on the fracture plane (MPa) |
| Slip Tendency (Ts) | τ / σn | Shear reactivation potential (Morris et al. 1996) |
| Dilation Tendency (Td) | (σ1 − σn) / (σ1 − σ3) | Tendency to dilate and conduct fluid |
| Slip Tendency (norm), Dilation Tendency (norm) | Rescaled to 0–1 | The same, over the network's own range, so the colouring uses the full ramp |
| Reduced-Risk Dilation Tendency | Td × (1 − Ts/Ts,max) | Favoured to open, with little risk of shear |
| Opening Angle | atan(τ / (Pp − σn)) | Jolly & Sanderson (1997), in degrees. Needs a non-zero pore pressure |
| Fracture Susceptibility | (σn − Pp) − (τ − C0)/μ | Pore-pressure increase required to reach Coulomb failure (MPa). Negative values indicate critically stressed fractures |
| Critically Stressed | τ ≥ C0 + μ·(σn − Pp) | Boolean Mohr-Coulomb failure flag |
Interpretation
- High Slip Tendency (Ts > 0.6): Fracture likely to slip under the current stress
- High Dilation Tendency (Td > 0.6): Fracture likely open/conductive
- Low or negative Fracture Susceptibility: Fracture at or near the failure envelope — candidate for reactivation and induced seismicity risk
Export
All exports live under the DFN's right-click Export submenu.
Fractures to FAB...
Writes the fracture geometry in FracMan ASCII (.fab) format: one record per active fracture (polygon vertices plus the plane normal), with fracture-set names in the SETS section and each fracture tagged with its set number. The file imports directly into FracMan and other DFN tools that read the format (e.g. Itasca codes, porepy).
Fractures to 3DEC (Itasca Geometry)...
Writes the fractures as an Itasca geometry file (.geom, text form ITASCA GEOMETRY3D) for 3DEC
(and FLAC3D). Each active fracture is one polygon, written with its corner coordinates. Its set
name goes in group slot 1, and four extra values travel with it: 1 the set number (from 1), 2 the
radius in m, 3 the dip and 4 the dip direction in degrees. In 3DEC, import the file as fracture
geometry. The group names then pick out each set, for example to give each set its own joint
properties. UDEC is two-dimensional and is not exported to.
Set Statistics to CSV...
One row per fracture set: orientation statistics (mean dip/azimuth, Fisher K), size-distribution parameters, spatial model and termination settings, target vs realized P32, total fracture area, fracture count, and the provenance tags shown in the properties panel.
Fractures to CSV...
One row per fracture: id, set, centroid coordinates, dip, azimuth, radius, polygon area, vertex count, and active flag — ready for external statistical analysis.
Intersection Lines as Polylines
Creates a polyline group in the project tree (DFN-Intersection Lines) from the fracture-fracture intersection segments, with each fracture pair's segments merged into continuous chains. Run Fracture Intersections first. The polylines are ordinary project objects, so they can be exported onward via the standard polyline export.
Analysis
The DFN's right-click Analysis submenu provides quantitative network analyses.
Virtual Scanlines to CSV...
Samples the network along three virtual scanlines through the domain centre (one per axis) — the numerical equivalent of a scanline survey or vertical borehole. The CSV report contains:
- Per-set summary: intersection count, raw P10 (fractures/m), and Terzaghi-corrected P10 for each scanline. The Terzaghi correction weights each intersection by 1/|cos θ| (θ = angle between the scanline and the fracture pole) to compensate for the orientation sampling bias; weights are capped at 7 (≈8° blind zone, Priest 1993).
- Per-intersection detail: fracture id, set, position, distance along the line, cos θ, and weight — ready for spacing analysis.
Compare the Terzaghi-corrected P10 of a vertical scanline against real borehole fracture frequencies to validate intensity.
Percolation Analysis
Builds connected clusters from the fracture-fracture intersections (run Fracture Intersections first) and reports:
- Cluster count and the number of isolated (non-intersecting) fractures
- The largest-cluster fraction of fractures and of area — the percolation order parameter
- Whether any cluster spans the domain along X, Y, and Z (its geometry reaches both opposite faces)
A network that spans the domain is above the percolation threshold and can support large-scale flow; details for the top clusters are written to the log.
Oda Permeability Tensor...
Computes the upscaled equivalent permeability tensor (Oda 1985) for a user-specified hydraulic aperture, treating each fracture as a parallel-plate conduit (cubic law):
k_ij = (a³ / 12V) · Σ A_k (δ_ij − n_i n_j)
The report gives the principal permeabilities k1 ≥ k2 ≥ k3 (m²) with their plunge/trend directions, the fracture porosity (a·P32), and the full tensor in the log. Note this assumes every fracture is hydraulically connected — an upper bound; combine with the Percolation Analysis for context, or solve the flow with Connection Mesh for Flow....
Connection Mesh for Flow
Connection Mesh for Flow... builds one triangle mesh of the connected backbone of the network and, if you ask, solves steady flow through it. Oda's tensor assumes every fracture is connected. This gives the permeability of the fractures that can carry flow, and shows which ones do.
It works on the visible, active fractures, so a set with Enable Set off is left out. It works out the intersections itself, so Fracture Intersections need not be run first. With several DFNs selected, one dialog, filled from the first, serves them all.
The run goes on in the background, one at a time, with its progress on a line in the messages panel. To stop it, right-click that line and choose Terminate Process: nothing is added. The project cannot be closed while it runs. If the network is regenerated, or deleted, during the run, the mesh is still added, but nothing is written to the DFN and the messages panel says so.
The mesh
Every fracture with two or more connections is triangulated in its own plane, over the area its intersections span. The fractures share their vertices along the intersection lines, so they join into one mesh.
| Field | Default | Description |
|---|---|---|
| Remove dead-end chains (repeat until every fracture has two connections) | Ticked | Dropping a dead end can leave its neighbour with one connection, so this repeats until none is left. Unticked, it takes one pass, and a fracture it keeps is meshed with all its intersections. |
| Domain boundary counts as a connection | Ticked | Where a fracture meets the domain boundary becomes a mesh edge, and its vertices are tagged by face for inflow and outflow. The flow solve needs it. |
| Target edge length (m) | A tenth of the median fracture radius | Coarser when the mesh would pass about half a million triangles. 0 gives triangles between the intersections only. Past about two million triangles it asks before building. |
The result is a mesh in the Data tree, ‹DFN› - Connection Mesh, with FractureID, SetID, ClusterID, Aperture_mm, Transmissivity and Log10Transmissivity layers on its triangles and BoundaryFaces on its vertices. When no fracture has two connections spanning an area, a message says so and nothing is added.
Apertures
Apertures, per fracture set has a group for each set, headed with its number of fractures and median radius. A fracture's aperture is the aperture at the median radius × (radius / set's median radius) ^ exponent, scattered log-normally. Its transmissivity follows from the cubic law for water at 20 °C, T = ρg b³ / 12μ. A set's values are remembered by its name for the session.
| Field | Default | Description |
|---|---|---|
| Aperture at median radius (mm) | 0.1 | Hydraulic aperture of a fracture of this set's median radius. |
| Size exponent | 0 | 0 gives the same aperture at every size, 0.5 grows with the square root of size, 1 in proportion to it. |
| Scatter (std. dev. of ln) | 0 | Log-normal spread about the size trend. At 0.5, most apertures lie within a factor of 2.7 of it. |
| Random seed: | 1 | The same seed gives the same scatter, and the same particle releases. |
Steady flow
Tick Solve steady flow along X, Y and Z to solve for head through the mesh, along each axis in turn. It needs Domain boundary counts as a connection. A summary box and the messages panel give three permeabilities, in m² and mD:
| Result | Boundary | Reads |
|---|---|---|
| Side faces closed (kxx, kyy, kzz) | 1 m of head across each pair of opposite faces, the other four closed | The lower values. An axis with no connected path says so. |
| Full tensor (k1, k2, k3 with plunge and trend) | Head falling linearly on every face | The upper values, with the principal directions. Fracture flow can leave through the side faces. |
| Oda (k1, k2, k3 with plunge and trend) | None: every fracture taken as connected | At least as high as both, for the same fractures and apertures. |
A large gap between Oda and the other two says connectivity, not aperture, limits the flow. The full tensors go to the messages panel. Each solved axis adds these layers, from the closed-side solve:
| Layer | On | Holds |
|---|---|---|
| Head_X, Head_Y, Head_Z | The mesh's vertices | Head, m. No value where a part of the mesh reaches neither face. |
| Log10Flow_X, Log10Flow_Y, Log10Flow_Z | The mesh's triangles | Log of the flow per unit width. |
| FlowRate_X, FlowRate_Y, FlowRate_Z | The DFN's fractures | What the fracture carries, m³/s. |
| FlowShare_X, FlowShare_Y, FlowShare_Z | The DFN's fractures | The same, as a share of that axis's inflow. Fractures in series each carry all of it, so the shares add to more than 1. |
The DFN is coloured by the first FlowShare layer. A visible, active fracture the mesh left out reads 0; inactive fractures and hidden sets have no value. The summary says how concentrated the flow is, per axis: X: 12 of 300 fractures carry 90% of the flow; 85 carry any.
Track particles
Tick Track particles from each inflow face to the opposite one to carry particles through the closed-side flow. It needs the flow solve. Particles start on the inflow face in proportion to the flow entering there, and travel at the mean velocity in each fracture, the flow divided by its aperture.
| Field | Default | Description |
|---|---|---|
| Particles per axis: | 1000 | From 1 to 100000. |
| At intersections: | Complete mixing | Complete mixing picks a way out in proportion to the flow leaving by it. Streamline routing keeps flow lines from crossing, so a particle leaves by the outflow next to the side it came in on. It falls back on mixing where the local flow gives no route. |
Each axis adds a mesh, ‹DFN› - Particle Paths X, of the first 100 paths as thin tubes, coloured by TravelTime_days with a PathID layer, and ParticleVisits_X on the DFN: how many particles passed through each fracture. A breakthrough table, ‹DFN› - Particle Breakthrough ‹time›.csv, goes in the project folder (the temporary folder for an unsaved project), with each particle's status, travel time, path length, fractures visited and cumulative fraction. The summary gives the arrivals, median, t10 and t90 for each axis.
The times are for the solve's 1 m of head across the domain and scale as 1 / head difference. Scale them to your gradient before you quote them. The messages panel warns when more than 1% of an axis's particles stop in stagnant flow or leave back through the inflow face.
Apertures under stress
Tick Close apertures under the project's stresses, by and choose a law to close each fracture's aperture under the effective normal stress on its plane before the flow is solved, so the permeability follows the in-situ stress. The apertures you gave become the unstressed ones. The stress comes from the DFN's Stress Tensor, which the dialog shows, at each fracture's centre if the tensor varies with depth.
Each set's closure values are under Closure under stress in its group, and only the chosen law's are enabled:
| Field | Default | Description |
|---|---|---|
| Barton-Bandis: Normal stiffness Kn (MPa/mm) | 30 | The initial normal stiffness: the aperture first closes by 1 / Kn mm per MPa, then ever more slowly, towards the residual. |
| Exponential: Closure coefficient alpha (1/MPa) | 0.15 | The aperture above the residual falls by a factor e for every 1 / alpha MPa. |
| Residual aperture (fraction of unstressed) | 0.1 | What is left at very high stress, from 0 to below 1. |
| Critically stressed fractures stay open; aperture x | 1 | A fracture critically stressed by the Coulomb rule is not closed, and keeps its unstressed aperture times this. Raise it above 1 for dilation. |
Oda, the flow and the particles then all use the closed apertures. The run adds EffectiveNormalStress_MPa to the mesh, and Aperture_mm and EffectiveNormalStress_MPa to the DFN. The summary says how far the apertures closed and how many fractures were critically stressed. With a pore pressure of 0 the messages panel suggests setting one, since apertures then close as in dry rock.
Ensemble
One realisation can mislead, because where the fractures fall decides what connects. Set Realisations: above 1, up to 1000, to regenerate each DFN that many times, mesh and solve each with these settings, and report the spread. It needs the flow solve, and tracks no particles. Seed: (default 1) starts the sequence, each realisation taking the next seed, so a run can be repeated.
The DFN itself is not changed and nothing is added to the project. Mapped fractures stay in every realisation. A summary box gives P10, P50 and P90 in mD of kxx, kyy and kzz, with how many realisations connected along each axis; a realisation with no connected path counts as 0 there. It gives the same for the full tensor's k1 and k3, Oda's k1, P32 and, with stress closure, the share of fractures critically stressed. A table, ‹DFN› - Permeability Ensemble ‹time›.csv, goes in the project folder, one row per realisation.
Stopped with Terminate Process, it reports the realisations already finished. The messages panel warns when a realisation placed fractures uniformly instead of by its set's Spatial Model: its P32 still looks right, but it describes a different network.
Validating against mapped traces
Where the DFN is meant to represent a real outcrop, Score DFN against Selected Traces… cuts the network with the outcrop mesh, compares the resulting synthetic traces against your interpretation, and writes a visual report covering length distribution, orientation fabric and intensity — per fracture set as well as pooled.
See DFN — Validating Against Outcrop.
Best Practices
For Realistic Networks
- Base parameters on field measurements when available — use Create DFN from Groups or Sets... so orientation statistics come from your data
- Use multiple fracture sets to represent different deformation events
- Validate P32 intensity against borehole or scanline data
- Compare generated orientation distributions with stereonet data
- Use the Match Quality panel (see the Interpretation Matching guide) to score the DFN against observed traces
For Performance
- Start with low P32 during parameter tuning
- Use proximity filtering to focus on relevant fractures
- Run Fracture Intersections only when needed — intersection and graph computation scale with fracture count
For Analysis
- Run Fracture Intersections before generating connectivity or topology attributes
- Use attributes for quantitative comparisons between realizations
Troubleshooting
No fractures generated
- Check that domain bounds are set correctly
- Verify P32 intensity is greater than 0
- Ensure at least one fracture set is enabled
Slow intersection computation
- Reduce fracture count (lower P32 or smaller domain)
- Use proximity filtering to limit active fractures
Mesh intersections disconnected
- Segments from the same fracture are automatically merged
- If gaps exist, the mesh may have holes or the fracture doesn't fully intersect
Slicers not showing
- Ensure slicer is enabled AND position slider is moved
- Check that fractures exist within the slice plane
Advanced Statistical Analysis
VRGS includes statistical tools for analyzing fracture data, based on techniques from the literature and FracPaQ. Distribution fitting runs automatically when a DFN is created from groups that carry trace geometry; the Fisher statistics below underpin set derivation and the match-quality scoring.
Distribution Fitting
Fit statistical distributions to fracture size data using Maximum Likelihood Estimation (MLE) with Kolmogorov-Smirnov goodness-of-fit testing.
Supported Distributions
| Distribution | Parameters | Use Case |
|---|---|---|
| Power Law | α (exponent), x_min | Scale-invariant fracture lengths (most common) |
| Lognormal | μ, σ, x_min | Natural log-normal processes |
| Exponential | λ (rate), x_min | Constant spacing/fragmentation |
How It Works
- MLE Fitting: Parameters estimated by maximizing likelihood
- x_min Optimization: Lower bound automatically selected to minimize the K-S statistic; all theoretical CDFs are conditioned on x ≥ x_min so the three families compete fairly
- Bootstrap K-S Testing: The selected fit's p-value comes from a semi-parametric bootstrap (Clauset et al. 2009) — synthetic datasets are drawn from the fitted model and refitted, so the p-value correctly accounts for the parameters having been estimated from the same data. p > 0.05 indicates an acceptable fit
Power Law MLE
For power law P(x) ~ x^(-α):
α = 1 + n / Σ[ln(x_i / x_min)]
The finite-size correction is applied for small samples.
Interpretation
| p-value | Interpretation |
|---|---|
| > 0.10 | Good fit |
| 0.05 - 0.10 | Marginal fit |
| < 0.05 | Poor fit - distribution may not apply |
Fitting a tail vs fitting a generator
The x_min search answers "is some tail of this data a power law?" — the right question for testing a hypothesis, and the reason each family is free to choose its own cutoff.
It is the wrong question when the fit becomes a generator's size distribution, because the model is then used across the whole range rather than above a cutoff. Using the searched x_min as the generator's minimum size discards the body of the population, and shape parameters estimated on a tail extrapolate badly downwards.
So when a DFN is created from measurements, the families are re-fitted and re-selected over the full observed range, with the lower bound pinned to the smallest measurement. The generated size population then spans, and matches, what was measured.
References
- Clauset et al. (2009) "Power-Law Distributions in Empirical Data"
- Newman (2006) "Power Laws, Pareto Distributions and Zipf's Law"
Fisher Concentration from Pole Data
When orientation statistics are derived from measurements (set creation and match-quality scoring), the Fisher concentration is estimated from the mean resultant length R of the 3D pole population:
K ≈ R(3 − R²) / (1 − R²)
This is the spherical (3D) maximum-likelihood estimator — appropriate for poles on the sphere, unlike the 2D von Mises estimator used for circular (strike/azimuth-only) data, which would underestimate K by roughly half at high concentration. Estimates are clamped to [0.1, 1000].
R is computed axially, via the orientation tensor T = (1/n) Σ p pᵀ, whose
principal eigenvector gives the mean axis; each pole is folded into that
hemisphere before the resultant is summed. Averaging poles as plain vectors
lets two descriptions of the same plane cancel — and because dip is reported in
[0, 90], a subvertical set has exactly that problem: its two valid descriptions
sit at opposite ends of one near-horizontal axis. Steep sets, which are the
common case in outcrop, are the ones a vector average gets most wrong.
Circular Statistics
For circular (2D angular) data such as strikes and paleocurrent directions:
Axial vs Vectorial Data
| Type | Range | Examples |
|---|---|---|
| Axial | 0-180° (headless) | Fracture strikes, lineation trends |
| Vectorial | 0-360° (directed) | Dip directions, current azimuths |
For axial data, angles are doubled before analysis and results halved.
Computed Statistics
| Statistic | Description |
|---|---|
| Mean Direction | Circular mean of angles |
| Resultant Length (R) | 0-1, measures concentration (0 = uniform, 1 = identical) |
| Circular Variance | 1 - R |
| Circular Std Dev | √(-2·ln(R)) |
| Concentration (κ) | von Mises dispersion parameter (2D circular estimator) |
Uniformity Tests
| Test | Output |
|---|---|
| Rayleigh Test | Tests for unimodal concentration (Z = nR² against a critical value) |
| Watson U² Test | p-value for non-uniformity on the circle |
| Kuiper Test | Test statistic V_n (compare against published critical values) |
References
- Fisher (1993) "Statistical Analysis of Circular Data"
- Mardia & Jupp (2000) "Directional Statistics"
Fabric Tensor Analysis
Quantify fracture network anisotropy using Oda's 2nd-rank fabric tensor (crack tensor).
Fabric Tensor (F2)
The tensor is computed as:
F2_ij = (1/V) * Σ[A_p * n_i * n_j]
Where:
- V = domain volume
- A_p = fracture area
- n = unit pole vector (normal to fracture)
Output Properties
| Property | Description |
|---|---|
| F2 Matrix | 3x3 symmetric tensor |
| Eigenvalues | Principal anisotropy magnitudes (λ1 ≥ λ2 ≥ λ3) |
| Eigenvectors | Principal anisotropy directions |
| Trace | λ1 + λ2 + λ3 (proxy for P32) |
| Anisotropy Ratio | λ1 / λ3 (1 = isotropic, higher = anisotropic) |
| Shape Factor | (λ1 - λ2) / (λ1 - λ3) (0 = prolate, 1 = oblate) |
Interpretation
| Anisotropy Ratio | Interpretation |
|---|---|
| 1.0 - 1.5 | Nearly isotropic |
| 1.5 - 3.0 | Moderately anisotropic |
| 3.0 - 10.0 | Strongly anisotropic |
| > 10.0 | Highly anisotropic (single dominant set) |
Reference
- Oda (1982) "Fabric tensor for discontinuous geological materials"