PageSourceSearch

https://docs-vrgeo-version3.netlify.app/assets/js/c701d8cd.dff83773.js

js docs-vrgeo-version3.netlify.app collected 2026-10-03 10:41:42 UTC 72,722 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkvrgs_docs_v_3_1=globalThis.webpackChunkvrgs_docs_v_3_1||[]).push([[15757],{29738(e,t,r){r.r(t),r.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"general/fractures-structure/dfn-user-guide","title":"Discrete Fracture Network (DFN) User Guide","description":"Generating, visualising and analysing Discrete Fracture Networks in VRGS. Requires the DFN licence feature.","source":"@site/docs/general/fractures-structure/dfn-user-guide.md","sourceDirName":"general/fractures-structure","slug":"/general/fractures-structure/dfn-user-guide","permalink":"/docs/next/general/fractures-structure/dfn-user-guide","draft":false,"unlisted":false,"editUrl":"https://github.com/vrgeoscience/vrgs_docs_v3/tree/master/docs/general/fractures-structure/dfn-user-guide.md","tags":[],"version":"current","sidebarPosition":4,"frontMatter":{"sidebar_position":4,"description":"Generating, visualising and analysing Discrete Fracture Networks in VRGS. Requires the DFN licence feature."},"sidebar":"docs","previous":{"title":"Fracture Intensity Mapping (P21 / P32 / P33)","permalink":"/docs/next/general/fractures-structure/fracture-intensity-mapping"},"next":{"title":"DFN \u2014 Matching Interpretations","permalink":"/docs/next/general/fractures-structure/dfn-interpretation-matching"}}');var i=r(74848),s=r(28453);const a={sidebar_position:4,description:"Generating, visualising and analysing Discrete Fracture Networks in VRGS. Requires the DFN licence feature."},l="Discrete Fracture Network (DFN) User Guide",d={},o=[{value:"Overview",id:"overview",level:2},{value:"Creating a DFN",id:"creating-a-dfn",level:2},{value:"Setting the Domain",id:"setting-the-domain",level:3},{value:"Fracture Sets",id:"fracture-sets",level:2},{value:"Fracture Set Parameters",id:"fracture-set-parameters",level:3},{value:"Orientation (Fisher Distribution)",id:"orientation-fisher-distribution",level:4},{value:"Size Distribution",id:"size-distribution",level:4},{value:"Intensity (P32)",id:"intensity-p32",level:4},{value:"Spatial Model",id:"spatial-model",level:4},{value:"Termination Rule",id:"termination-rule",level:4},{value:"Model Surfaces",id:"model-surfaces",level:2},{value:"Crossing probability",id:"crossing-probability",level:3},{value:"Coverage, and where a surface is not mapped",id:"coverage-and-where-a-surface-is-not-mapped",level:3},{value:"The volume, and what P32 now means",id:"the-volume-and-what-p32-now-means",level:3},{value:"Surfaces that cannot be used",id:"surfaces-that-cannot-be-used",level:3},{value:"Generating the Network",id:"generating-the-network",level:3},{value:"Visualization",id:"visualization",level:2},{value:"Visibility Options",id:"visibility-options",level:3},{value:"Render Mode",id:"render-mode",level:3},{value:"Stereonet and Rose Diagram",id:"stereonet-and-rose-diagram",level:3},{value:"Slicers and proximity filtering",id:"slicers-and-proximity-filtering",level:3},{value:"Intersection Analysis",id:"intersection-analysis",level:2},{value:"Fracture-Fracture Intersections",id:"fracture-fracture-intersections",level:3},{value:"Mesh Intersections",id:"mesh-intersections",level:3},{value:"Outcrop-Constrained Display",id:"outcrop-constrained-display",level:3},{value:"Truncating Against the Boundary",id:"truncating-against-the-boundary",level:3},{value:"Connectivity Graph",id:"connectivity-graph",level:2},{value:"Topology classification",id:"topology-classification",level:3},{value:"Graph Analysis",id:"graph-analysis",level:3},{value:"Fracture Propagation",id:"fracture-propagation",level:2},{value:"Propagation Parameters",id:"propagation-parameters",level:3},{value:"Stress Tensor",id:"stress-tensor",level:3},{value:"Running Propagation",id:"running-propagation",level:3},{value:"Slicers (Cross-Sections)",id:"slicers-cross-sections",level:2},{value:"Enabling Slicers",id:"enabling-slicers",level:3},{value:"Slicer Display",id:"slicer-display",level:3},{value:"Proximity Filtering",id:"proximity-filtering",level:2},{value:"Enabling Proximity Filter",id:"enabling-proximity-filter",level:3},{value:"How It Works",id:"how-it-works",level:3},{value:"Attributes",id:"attributes",level:2},{value:"Geometry Attributes",id:"geometry-attributes",level:3},{value:"Connectivity Attributes",id:"connectivity-attributes",level:3},{value:"Topology Attributes",id:"topology-attributes",level:3},{value:"Stress Attributes",id:"stress-attributes",level:3},{value:"Interpretation",id:"interpretation",level:4},{value:"Export",id:"export",level:2},{value:"Fractures to FAB...",id:"fractures-to-fab",level:3},{value:"Set Statistics to CSV...",id:"set-statistics-to-csv",level:3},{value:"Fractures to CSV...",id:"fractures-to-csv",level:3},{value:"Intersection Lines as Polylines",id:"intersection-lines-as-polylines",level:3},{value:"Analysis",id:"analysis",level:2},{value:"Virtual Scanlines to CSV...",id:"virtual-scanlines-to-csv",level:3},{value:"Percolation Analysis",id:"percolation-analysis",level:3},{value:"Oda Permeability Tensor...",id:"oda-permeability-tensor",level:3},{value:"Validating against mapped traces",id:"validating-against-mapped-traces",level:3},{value:"Best Practices",id:"best-practices",level:2},{value:"For Realistic Networks",id:"for-realistic-networks",level:3},{value:"For Performance",id:"for-performance",level:3},{value:"For Analysis",id:"for-analysis",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"No fractures generated",id:"no-fractures-generated",level:3},{value:"Slow intersection computation",id:"slow-intersection-computation",level:3}
1,{value:"Mesh intersections disconnected",id:"mesh-intersections-disconnected",level:3},{value:"Slicers not showing",id:"slicers-not-showing",level:3},{value:"Advanced Statistical Analysis",id:"advanced-statistical-analysis",level:2},{value:"Distribution Fitting",id:"distribution-fitting",level:3},{value:"Supported Distributions",id:"supported-distributions",level:4},{value:"How It Works",id:"how-it-works-1",level:4},{value:"Power Law MLE",id:"power-law-mle",level:4},{value:"Interpretation",id:"interpretation-1",level:4},{value:"Fitting a tail vs fitting a generator",id:"fitting-a-tail-vs-fitting-a-generator",level:4},{value:"References",id:"references",level:4},{value:"Fisher Concentration from Pole Data",id:"fisher-concentration-from-pole-data",level:3},{value:"Circular Statistics",id:"circular-statistics",level:3},{value:"Axial vs Vectorial Data",id:"axial-vs-vectorial-data",level:4},{value:"Computed Statistics",id:"computed-statistics",level:4},{value:"Uniformity Tests",id:"uniformity-tests",level:4},{value:"References",id:"references-1",level:4},{value:"Fabric Tensor Analysis",id:"fabric-tensor-analysis",level:3},{value:"Fabric Tensor (F2)",id:"fabric-tensor-f2",level:4},{value:"Output Properties",id:"output-properties",level:4},{value:"Interpretation",id:"interpretation-2",level:4},{value:"Reference",id:"reference",level:4}];function c(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"discrete-fracture-network-dfn-user-guide",children:"Discrete Fracture Network (DFN) User Guide"})}),"\n",(0,i.jsx)(t.p,{children:"This guide covers the Discrete Fracture Network (DFN) modeling capabilities in VRGS, including generation, visualization, and analysis features."}),"\n",(0,i.jsx)(t.admonition,{title:"Building a DFN from interpreted data?",type:"tip",children:(0,i.jsxs)(t.p,{children:["If you have interpreted trace polylines or structural measurements and want\nthe DFN to match them \u2014 derived Fisher statistics, observation-driven P32,\nplacement biased toward your outcrop, validation against observed traces \u2014\nsee the companion ",(0,i.jsx)(t.a,{href:"/docs/next/general/fractures-structure/dfn-interpretation-matching",children:"DFN Interpretation Matching guide"}),"."]})}),"\n",(0,i.jsx)(t.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(t.p,{children:"A Discrete Fracture Network (DFN) is a stochastic representation of fracture systems in rock masses. VRGS allows you to:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Generate statistically-controlled fracture networks from orientation data"}),"\n",(0,i.jsx)(t.li,{children:"Compute fracture-fracture intersections and fracture traces on outcrop meshes"}),"\n",(0,i.jsx)(t.li,{children:"Analyze network connectivity and topology using graph theory"}),"\n",(0,i.jsx)(t.li,{children:"Model stress-controlled fracture propagation"}),"\n",(0,i.jsx)(t.li,{children:"Create cross-sections through the network"}),"\n",(0,i.jsx)(t.li,{children:"Filter fractures by proximity to outcrops"}),"\n",(0,i.jsx)(t.li,{children:"Colour fractures by computed geometric, connectivity, topology, and stress attributes"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"creating-a-dfn",children:"Creating a DFN"}),"\n",(0,i.jsx)(t.p,{children:"A DFN is created from one or more orientation (plane attitude) groups:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["In the ",(0,i.jsx)(t.strong,{children:"Interpretation"})," tree, select the orientation group(s) you want to base the network on (each group becomes one fracture set)"]}),"\n",(0,i.jsxs)(t.li,{children:["Right-click and choose ",(0,i.jsx)(t.strong,{children:"Create DFN from Selected Groups"})]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["For each group, VRGS derives the set's mean orientation and Fisher concentration (K) from the measured poles. If the group's plane
1s carry trace geometry, a size distribution is also fitted to the trace lengths (see ",(0,i.jsx)(t.a,{href:"#distribution-fitting",children:"Distribution Fitting"}),"); otherwise sensible defaults are used. The source of each derived value is shown in the properties panel (",(0,i.jsx)(t.code,{children:"P32 Source"}),", ",(0,i.jsx)(t.code,{children:"Size Distribution Source"}),")."]}),"\n",(0,i.jsxs)(t.p,{children:["The names of the source orientation groups are stored with the DFN, so you can later right-click the DFN and choose ",(0,i.jsx)(t.strong,{children:"Re-derive from Source Orientation Groups"})," to re-run the derivation against updated data."]}),"\n",(0,i.jsx)(t.h3,{id:"setting-the-domain",children:"Setting the Domain"}),"\n",(0,i.jsxs)(t.p,{children:["The DFN domain defines the 3D bounding box where fractures are generated. It is set from the data extents at creation and can be edited in the properties panel under ",(0,i.jsx)(t.strong,{children:"Domain"})," (Min/Max X, Y, Z)."]}),"\n",(0,i.jsx)(t.h2,{id:"fracture-sets",children:"Fracture Sets"}),"\n",(0,i.jsxs)(t.p,{children:["A DFN consists of one or more ",(0,i.jsx)(t.strong,{children:"fracture sets"}),", each with distinct statistical properties. Sets correspond to the orientation groups the DFN was created from; each can be enabled/disabled individually (",(0,i.jsx)(t.strong,{children:"Enable Set"}),")."]}),"\n",(0,i.jsx)(t.h3,{id:"fracture-set-parameters",children:"Fracture Set Parameters"}),"\n",(0,i.jsxs)(t.p,{children:["All parameters are edited in the properties panel under ",(0,i.jsx)(t.strong,{children:"Fracture Sets"}),"."]}),"\n",(0,i.jsx)(t.h4,{id:"orientation-fisher-distribution",children:"Orientation (Fisher Distribution)"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Parameter"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Mean Dip"})}),(0,i.jsx)(t.td,{children:"Average dip angle (0-90 degrees from horizontal)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Mean Azimuth"})}),(0,i.jsx)(t.td,{children:"Average dip direction (0-360 degrees, 0=North)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Fisher K"})}),(0,i.jsx)(t.td,{children:"Fisher concentration parameter. Higher values = tighter clustering around mean"})]})]})]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Fisher K \u2248 1-5: Strongly dispersed orientations"}),"\n",(0,i.jsx)(t.li,{children:"Fisher K = 10-20: Moderate clustering"}),"\n",(0,i.jsx)(t.li,{children:"Fisher K = 50+: Tight clustering around mean"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"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]."}),"\n",(0,i.jsx)(t.h4,{id:"size-distribution",children:"Size Distribution"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Parameter"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Size Distribution"})}),(0,i.jsx)(t.td,{children:"Power Law, Lognormal, Exponential, or Uniform"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Min Radius"})}),(0,i.jsx)(t.td,{children:"Minimum fracture radius"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Max Radius"})}),(0,i.jsx)(t.td,{children:"Maximum fracture radius"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Exponent"})}),(0,i.jsx)(t.td,{children:"For power law distribution (typically 2.0-3.5)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Lognormal Mean / Stddev"})}),(0,i.jsx)(t.td,{children:"Parameters of ln(r) for the lognormal distribution. Sampled by exact inverse-CDF truncation to [Min Radius, Max Radius]"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Exponential Rate"})}),(0,i.jsxs)(t.td,{children:["Rate \u03bb of ",(0,i.jsx)(t.code,{children:"P(r) ~ exp(-\u03bb\xb7r)"})," for the exponential distribution. Larger \u03bb means more small fractures. Leave at 0 to derive it from the size bounds; fitting a size distribution from measurements sets it automatically"]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Aspect Ratio"})}),(0,i.jsx)(t.td,{children:"Major/minor axis ratio for elliptical fractures (1.0 = circular)"})]})]})]}),"\n",(0,i.jsxs)(t.admonition,{title:"Deriving these from measurements",type:"tip",children:[(0,i.jsxs)(t.p,{children:["Rather than typing sizes and intensities, ",(0,i.jsx)(t.strong,{children:"Derive DFN Statistics\u2026"})," (right-click the DFN) lets each set take each statistic from a named source \u2014 an orientation group, a trace group, a scanline, or a P21/P32 attribute layer \u2014 and cross-checks the intensity routes against each other."]}
1),(0,i.jsxs)(t.p,{children:["It also handles the fact that a mapped trace is a ",(0,i.jsx)(t.em,{children:"chord"}),", not a fracture diameter, so sizes fitted from traces are not systematically too small. See ",(0,i.jsx)(t.a,{href:"/docs/next/general/fractures-structure/dfn-interpretation-matching",children:"DFN \u2014 Matching Interpretations \xa74"}),"."]})]}),"\n",(0,i.jsx)(t.h4,{id:"intensity-p32",children:"Intensity (P32)"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Parameter"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"P32 Intensity"})}),(0,i.jsx)(t.td,{children:"Fracture area per unit volume (m\xb2/m\xb3)"})]})})]}),"\n",(0,i.jsxs)(t.p,{children:["P32 is the most robust intensity measure as it is scale-independent. The generator calibrates the fracture count from the ",(0,i.jsx)(t.em,{children:"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."]}),"\n",(0,i.jsx)(t.p,{children:"Under boundary truncation, fractures centred outside the domain that cross into it are generated too \u2014 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)."}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.strong,{children:"Set Statistics to CSV"})," export reports target against realized P32 per set, and the validation report shows the same comparison graphically."]}),"\n",(0,i.jsx)(t.h4,{id:"spatial-model",children:"Spatial Model"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Model"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Poisson"})}),(0,i.jsx)(t.td,{children:"Completely random (uniform) fracture centres"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Clustered"})}),(0,i.jsxs)(t.td,{children:["Neyman-Scott clustering: a reduced set of parent centres each spawns several fractures within ",(0,i.jsx)(t.strong,{children:"Cluster Radius"}),"; ",(0,i.jsx)(t.strong,{children:"Fractures per Cluster"})," sets the mean number of fractures per parent"]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Stratified"})}),(0,i.jsx)(t.td,{children:"Grid-stratified sampling \u2014 more even spatial coverage than Poisson"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Region Mask"})}),(0,i.jsxs)(t.td,{children:["Placement biased toward a mask mesh with a Gaussian falloff (",(0,i.jsx)(t.strong,{children:"Region Mask Falloff"}),"); see the ",(0,i.jsx)(t.a,{href:"/docs/next/general/fractures-structure/dfn-interpretation-matching",children:"Interpretation Matching guide"})]})]})]})]}),"\n",(0,i.jsx)(t.h4,{id:"termination-rule",children:"Termination Rule"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Rule"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"None"})}),(0,i.jsx)(t.td,{children:"Fractures extend beyond the domain unmodified"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Truncate at Boundary"})}),(0,i.jsx)(t.td,{children:"Fracture polygons are clipped to the domain box"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Abutting"})}),(0,i.jsxs)(t.td,{children:["Younger fractures terminate against older ones with probability ",(0,i.jsx)(t.strong,{children:"Abutting Probability"})]})]})]})]}),"\n",(0,i.jsxs)(t.p,{children:["Modelled surfaces are handled separately from this rule \u2014 see ",(0,i.jsx)(t.a,{href:"#model-surfaces",children:"Model Surfaces"})," below. A set normally wants boundary truncation ",(0,i.jsx)(t.em,{children:"and"})," bed confinement at the same time, so they are independent settings rather than alternatives."]}),"\n",(0,i.jsx)(t.h2,{id:"model-surfaces",children:"Model Surfaces"}),"\n",(0,i.jsxs)(t.p,{children:["Surfaces produced by the ",(0,i.jsx)(t.a,{href:"/docs/next/general/fractures-structure/surface-gridding",children:"surface gridding"})," can be attached to a DFN to give it a shape other than a box. Right-click the DFN and choose ",(0,i.jsx)(t.strong,{children:"Model Surfaces\u2026"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Each attached surface has a ",(0,i.jsx)(t.strong,{children:"role"}),":"]}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Role"}),(0,i.jsx)(t.th,{children:"Effect"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Upper limit"})}),(0,i.jsx)(t.td,{children:"The model exists below the surface. Fractures are clipped at it."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Lower limit"})}),(0,i.jsx)(t.td,{children:"The model exists above the surface."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Internal barrier"})}),(0,i.jsxs)(t.td,{children:["A fracture reaching the surface either crosses it or stops, decided by the ",(0,i.jsx)(t.strong,{children:"crossing probability"}),"."]})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"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."}),"\n",(0,i.jsx)(t.h3,{id:"crossing-probability",children:"Crossing probability"}),"\n",(0,i.jsx)(t.p,{children:"An internal barrier's crossing probability is the chance that a fracture reaching it carries on through:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"1.0"})," \u2014 transparent. The surface changes nothing. This is the default, so attaching a surface never alters a model until you tell it to."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"0.0"})," \u2014 impermeable. No fracture crosses; every set is confined between barriers."]}),"\n",(0,i.jsx)(t.li,{children:"Anything between \u2014 that fraction of fractures crosses."}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["Each ",(0,i.jsx)(t.strong,{children:"fracture set"})," also has a ",(0,i.jsx)(t.strong,{children:"Surface Crossing Probability"})," in the property bar, which ",(0,i.jsx)(t.strong,{children:"overrides"})," the surface's own value:"]}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Set value"}),(0,i.jsx)(t.th,{children:"Meaning"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsxs)(t.td,{children:[(0,i.jsx)(t.strong,{children:"-1"})," (default)"]}),(0,i.jsx)(t.td,{children:"Use whatever each surface says"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"0"})}),(0,i.jsx)(t.td,{children:"This set is bed-confined, whatever the surfaces say"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"1"})}),(0,i.jsx)(t.td,{children:"This set cuts straight through every surface"})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"The set wins rather than the two being multiplied together, be
1cause a product could never express a through-going master joint set cutting a strong bedding plane \u2014 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."}),"\n",(0,i.jsx)(t.h3,{id:"coverage-and-where-a-surface-is-not-mapped",children:"Coverage, and where a surface is not mapped"}),"\n",(0,i.jsxs)(t.p,{children:["A modelled surface rarely spans the whole domain footprint. Where it does not, ",(0,i.jsx)(t.strong,{children:"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."]}),"\n",(0,i.jsxs)(t.p,{children:["That is the honest behaviour, but it is invisible in the result \u2014 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 ",(0,i.jsx)(t.strong,{children:"Coverage"})," column for every surface. If it reads 35%, only 35% of your model is constrained by it."]}),"\n",(0,i.jsx)(t.h3,{id:"the-volume-and-what-p32-now-means",children:"The volume, and what P32 now means"}),"\n",(0,i.jsx)(t.admonition,{type:"caution",children:(0,i.jsxs)(t.p,{children:["P32 is fracture area per unit ",(0,i.jsx)(t.strong,{children:"volume"}),", and bounding surfaces change the volume."]})}),"\n",(0,i.jsxs)(t.p,{children:["Once upper/lower limits are attached, intensity is measured against the ",(0,i.jsx)(t.strong,{children:"bounded"})," volume \u2014 the rock between the surfaces \u2014 not against the domain box. The dialog states the bounded volume and its share of the box for exactly this reason."]}),"\n",(0,i.jsxs)(t.p,{children:["This is the right behaviour: a target P32 of 2 m\xb2/m\xb3 in a 10 m bed means 2 m\xb2 of fracture per cubic metre ",(0,i.jsx)(t.em,{children:"of that bed"}),", which is what a geologist means by it. But it does mean that ",(0,i.jsx)(t.strong,{children:"attaching a bounding surface to an existing model changes what its intensity numbers refer to"}),", so re-check any P32 you derived before."]}),"\n",(0,i.jsx)(t.p,{children:"Target and realised intensity both use the bounded volume, so the two stay comparable and the validation report's intensity panel stays meaningful."}),"\n",(0,i.jsx)(t.h3,{id:"surfaces-that-cannot-be-used",children:"Surfaces that cannot be used"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Source"}),(0,i.jsx)(t.th,{children:"How its side is decided"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsxs)(t.td,{children:[(0,i.jsx)(t.strong,{children:"Gridded surface"})," (",(0,i.jsx)(t.code,{children:"Grid"}),", from ",(0,i.jsx)(t.a,{href:"/docs/next/general/fractures-structure/surface-gridding",children:"surface gridding"}),")"]}),(0,i.jsx)(t.td,{children:"The mesh is rasterised into a height field in the surface's own frame \u2014 its normal, not vertical, so a steep surface works"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsxs)(t.td,{children:[(0,i.jsx)(t.strong,{children:"Implicit surface"})," (from the 3D potential field)"]}),(0,i.jsxs)(t.td,{children:["The ",(0,i.jsx)(t.strong,{children:"potential field itself"}),", carried straight through. A level set has no preferred axis, so an overturned or recumbent fold works"]})]})]})]}),"\n",(0,i.jsxs)(t.p,{children:["Overturned folds therefore bound a DFN correctly. That comes from using the potential rather than the triangles: the sign is ",(0,i.jsx)(t.strong,{children:"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 \u2014 a vertical line crosses the same horizon three times, and a geometric "below" would get the middle crossing wrong.']}),"\n",(0,i.jsx)(t.p,{children:"Two cases are still refused, both with a message rather than a silent approximation:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"A gridded surface that folds back on itself."}
1)," The gridding cannot produce one, but an imported or hand-edited mesh can. Use an implicit surface instead."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["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 \u2014 visible in the ",(0,i.jsx)(t.strong,{children:"Coverage"})," column."]}),"\n",(0,i.jsx)(t.h3,{id:"generating-the-network",children:"Generating the Network"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Right-click on the DFN in the Interpretation tree"}),"\n",(0,i.jsxs)(t.li,{children:["Select ",(0,i.jsx)(t.strong,{children:"Regenerate"})]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["Each regeneration uses a fresh random seed, producing a new statistical realization with the same parameters. The ",(0,i.jsx)(t.strong,{children:"Grow"})," menu item regenerates and then runs fracture propagation (see below)."]}),"\n",(0,i.jsx)(t.h2,{id:"visualization",children:"Visualization"}),"\n",(0,i.jsx)(t.h3,{id:"visibility-options",children:"Visibility Options"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Visible"}),": Toggle the fracture network on/off"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Show Vertices"}),": Toggle rendering of fracture intersection points"]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"render-mode",children:"Render Mode"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.strong,{children:"Render Mode"})," selector in the properties panel controls how fractures are drawn:"]}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Mode"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Disks"})}),(0,i.jsx)(t.td,{children:"Filled fracture polygons, coloured by fracture set"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Outlines"})}),(0,i.jsx)(t.td,{children:"Polygon edges only"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Colour by Property"})}),(0,i.jsx)(t.td,{children:"Filled polygons coloured by the active attribute layer through the colour map"})]})]})]}),"\n",(0,i.jsxs)(t.p,{children:["Generating an attribute automatically switches to ",(0,i.jsx)(t.em,{children:"Colour by Property"})," so the result is visible immediately; switch back to ",(0,i.jsx)(t.em,{children:"Disks"})," at any time without losing the attribute layer."]}),"\n",(0,i.jsx)(t.h3,{id:"stereonet-and-rose-diagram",children:"Stereonet and Rose Diagram"}),"\n",(0,i.jsxs)(t.p,{children:["A visible DFN plots on any stereonet \u2014 the ",(0,i.jsx)(t.strong,{children:"Charts"})," panel's, or a stereonet window opened from ",(0,i.jsx)(t.strong,{children:"Home \u2192 Windows \u2192 Stereonet Window"})," \u2014 just like measured orientation data (see the ",(0,i.jsx)(t.a,{href:"/docs/next/general/fractures-structure/stereonet-user-guide",children:"Stereonet User Guide"}),"):"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"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."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Density contours"}),": the Kamb/Schmidt contouring includes DFN poles."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Rose diagram"}),": fracture azimuths (or strikes, with ",(0,i.jsx)(t.strong,{children:"Strike Values"}),") contribute to the rose petals, density ring, and azimuth dots."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"SVG export"})," includes the DFN poles, mirroring the on-screen display."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"To validate a generated network against its source data, check both the DFN and its source orientation groups in the stereonet window \u2014 generated and observed poles plot together with distinguishable colours."}
1),"\n",(0,i.jsx)(t.h3,{id:"slicers-and-proximity-filtering",children:"Slicers and proximity filtering"}),"\n",(0,i.jsxs)(t.p,{children:["See ",(0,i.jsx)(t.a,{href:"#slicers-cross-sections",children:"Slicers"})," and ",(0,i.jsx)(t.a,{href:"#proximity-filtering",children:"Proximity Filtering"})," below."]}),"\n",(0,i.jsx)(t.h2,{id:"intersection-analysis",children:"Intersection Analysis"}),"\n",(0,i.jsx)(t.h3,{id:"fracture-fracture-intersections",children:"Fracture-Fracture Intersections"}),"\n",(0,i.jsx)(t.p,{children:"Compute where fractures intersect each other:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Right-click on the DFN"}),"\n",(0,i.jsxs)(t.li,{children:["Select ",(0,i.jsx)(t.strong,{children:"Fracture Intersections"})]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"This creates line segments at all fracture-fracture intersections and automatically builds the connectivity graph from them."}),"\n",(0,i.jsx)(t.h3,{id:"mesh-intersections",children:"Mesh Intersections"}),"\n",(0,i.jsx)(t.p,{children:"Compute where fractures intersect mesh surfaces (e.g., outcrop models):"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Ensure the target mesh(es) are visible"}),"\n",(0,i.jsx)(t.li,{children:"Right-click on the DFN"}),"\n",(0,i.jsxs)(t.li,{children:["Select ",(0,i.jsx)(t.strong,{children:"Mesh Intersections"})]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"This creates polylines representing the fracture traces on the mesh surface. Each fracture's intersection segments are automatically merged into continuous polylines."}),"\n",(0,i.jsxs)(t.p,{children:["It also records which fractures reached the mesh, so they can be displayed on their own \u2014 see ",(0,i.jsx)(t.a,{href:"#outcrop-constrained-display",children:"Outcrop-Constrained Display"})," below."]}),"\n",(0,i.jsx)(t.h3,{id:"outcrop-constrained-display",children:"Outcrop-Constrained Display"}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Show Outcrop-Constrained Fractures Only"})," (right-click menu) hides every fracture that does ",(0,i.jsx)(t.em,{children:"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."]}),"\n",(0,i.jsxs)(t.p,{children:["The subset comes from the last cut against a mesh (",(0,i.jsx)(t.strong,{children:"Mesh Intersections"}),", or ",(0,i.jsx)(t.em,{children:"Score DFN against Selected Traces\u2026"}),"), so run one of those first. Regenerating the DFN clears it \u2014 fracture identities are reused on rebuild, so a stale subset would name the wrong fractures."]}),"\n",(0,i.jsxs)(t.p,{children:["Full guide: ",(0,i.jsx)(t.a,{href:"/docs/next/general/fractures-structure/dfn-validating-against-outcrop",children:"DFN \u2014 Validating Against Outcrop"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"truncating-against-the-boundary",children:"Truncating Against the Boundary"}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Truncate Against Boundary"})," (right-click menu) clips all existing fracture polygons to the current domain box without regenerating the network."]}),"\n",(0,i.jsx)(t.h2,{id:"connectivity-graph",children:"Connectivity Graph"}),"\n",(0,i.jsxs)(t.p,{children:["The fracture graph represents network topology using nodes (intersection points) and edges (intersection-line segments between nodes). It is built automatically when you run ",(0,i.jsx)(t.strong,{children:"Fracture Intersections"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"topology-classification",children:"Topology classification"}),"\n",(0,i.jsx)(t.p,{children:"Nodes are classified following Sanderson & Nixon (2015):"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"I-nodes"})," \u2014 free ends of intersection lines (degree 1)"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Y-nodes"})," \u2014 abutments, where the end of one intersection line meets the interior of another (degree 3)"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"X-nodes"})," \u2014 crossings of two intersection lines (degree 4)"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"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."}),"\n",(0,i.jsx)(t.h3,{id:"graph-analysis",children:"Graph Analysis"}),"\n",(0,i.jsx)(t.p,{children:"The graph provides:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Connected component identification"}),"\n",(0,i.jsx)(t.li,{children:"Node degree analysis (I, Y, X nodes)"}),"\n",(0,i.jsxs)(t.li,{children:["Per-fracture topology and connectivity attributes (see ",(0,i.jsx)(t.a,{href:"#attributes",children:"Attributes"}),")"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"fracture-propagation",children:"Fracture Propagation"}),"\n",(0,i.jsx)(t.p,{children:"VRGS includes a stress-controlled fracture propagation model that extends fracture tips incrementally."}),"\n",(0,i.jsx)(t.h3,{id:"propagation-parameters",children:"Propagation Parameters"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Parameter"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Step Length"})}),(0,i.jsx)(t.td,{children:"Distance each tip advances per step"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Max Total Length"})}),(0,i.jsx)(t.td,{children:"Maximum length a fracture can grow"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Max Steps"})}),(0,i.jsx)(t.td,{children:"Maximum propagation iterations"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Abutting Distance"})}),(0,i.jsx)(t.td,{children:"Distance at which tips terminate against other fractures"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Abutting Probability"})}),(0,i.jsx)(t.td,{children:"Probability of termination when within abutting distance"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Stress Shadow Distance"})}),(0,i.jsx)(t.td,{children:"Zone of influence around existing fractures"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Stress Shadow Angle"})}),(0,i.jsx)(t.td,{children:"Parallelism threshold: a tip growing within this angular tolerance of a nearby fracture's orientation (and within the shadow distance) terminates"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Direction Noise"})}),(0,i.jsx)(t.td,{children:"Random variation in growth direction (degrees)"})]})]})]}),"\n",(0,i.jsx)(t.h3,{id:"stress-tensor",children:"Stress Tensor"}),"\n",(0,i.jsx)(t.p,{children:"The propagation direction is influenced by the regional stress field:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Sigma1"}),": Maximum principal stress direction \u2014 in-plane growth is deflected toward it, weighted by the stress anisotropy (\u03c31 \u2212 \u03c33)/\u03c31"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Sigma2"}),": Intermediate principal stress"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Sigma3"}),": Minimum principal stress (fractures propagate perpendicular to this)"]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"running-propagation",children:"Running Propagation"}),"\n",(0,i.jsxs)(t.p,{children:["From the DFN's ",(0,i.jsx)(t.strong,{children:"Attribute"})," menu, under ",(0,i.jsx)(t.strong,{children:"Propagation"}),":"]}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Initialize from Tips"})," \u2014 creates two growth tips per fracture at the ends of its strike axis"]}),"\n",(0,i.jsxs)(t.li,{children:["Either:","\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Step"}),": Single growth iteration"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Run to Completion"}),": Run until all tips terminate or Max Steps is reached"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The spatial index is refreshed as fractures grow, so abutting and stress-shadow checks always see the current geometry."}),"\n",(0,i.jsx)(t.h2,{id:"slicers-cross-sections",children:"Slicers (Cross-Sections)"}),"\n",(0,i.jsx)(t.p,{children:"Create 2D cross-sections through the DFN to visualize fracture traces on orthogonal planes."}),"\n",(0,i.jsx)(t.h3,{id:"enabling-slicers",children:"Enabling Slicers"}),"\n",(0,i.jsx)(t.p,{children:"In the DFN properties panel:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Enable ",(0,i.jsx)(t.strong,{children:"X Axis Slicer"}),", ",(0,i.jsx)(t.strong,{children:"Y Axis Slicer"}),", or ",(0,i.jsx)(t.strong,{children:"Z Axis Slicer"})]}),"\n",(0,i.jsx)(t.li,{children:"Adjust the slider position (0-100% of domain extent)"}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"slicer-display",children:"Slicer Display"}),"\n",(0,i.jsx)(t.p,{children:"When a slicer is active:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Fracture disks are hidden"}),"\n",(0,i.jsx)(t.li,{children:"Intersection lines with the slicer plane are displayed"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Multiple slicers can be active simultaneously."}
1),"\n",(0,i.jsx)(t.h2,{id:"proximity-filtering",children:"Proximity Filtering"}),"\n",(0,i.jsx)(t.p,{children:"Filter fractures based on their distance to outcrop data (meshes or point clouds)."}),"\n",(0,i.jsx)(t.h3,{id:"enabling-proximity-filter",children:"Enabling Proximity Filter"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["In DFN properties, enable ",(0,i.jsx)(t.strong,{children:"Enable Filter"})," under Proximity Filter"]}),"\n",(0,i.jsxs)(t.li,{children:["Set the ",(0,i.jsx)(t.strong,{children:"Distance Threshold"})," (meters)"]}),"\n",(0,i.jsxs)(t.li,{children:["Optionally enable ",(0,i.jsx)(t.strong,{children:"Invert Filter"})," to show only distant fractures"]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"how-it-works",children:"How It Works"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Distances are computed from fracture centroids to the nearest visible mesh/point cloud"}),"\n",(0,i.jsx)(t.li,{children:"A distance grid accelerates lookups for large datasets"}),"\n",(0,i.jsx)(t.li,{children:"Filtering is performed in the GPU shader for smooth interaction"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"attributes",children:"Attributes"}),"\n",(0,i.jsxs)(t.p,{children:["DFN fractures support computed attributes for analysis and colour mapping. Generate them from the DFN's ",(0,i.jsx)(t.strong,{children:"Attribute"})," right-click menu; the fracture display is coloured by the most recently generated attribute."]}),"\n",(0,i.jsx)(t.h3,{id:"geometry-attributes",children:"Geometry Attributes"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Attribute"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Dip"})}),(0,i.jsx)(t.td,{children:"Dip angle (0-90\xb0)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Azimuth"})}),(0,i.jsx)(t.td,{children:"Dip direction (0-360\xb0)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Width"})}),(0,i.jsx)(t.td,{children:"Fracture extent along strike"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Height"})}),(0,i.jsx)(t.td,{children:"Fracture extent down dip"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Area"})}),(0,i.jsx)(t.td,{children:"Fracture polygon area"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Distance"})}),(0,i.jsx)(t.td,{children:"Distance from the fracture to the nearest visible outcrop"})]})]})]}),"\n",(0,i.jsx)(t.h3,{id:"connectivity-attributes",children:"Connectivity Attributes"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Attribute"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Fracture Intersections"})}),(0,i.jsx)(t.td,{children:"Number of fractures intersecting this one"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Connected Groups"})}),(0,i.jsx)(t.td,{children:"Connected-component ID of the fracture"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Component Size"})}),(0,i.jsx)(t.td,{children:"Number of fractures in this fracture's connected component"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Total Intersection Length"})}),(0,i.jsx)(t.td,{children:"Summed length of this fracture's intersection lines"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Intersection Density"})}),(0,i.jsx)(t.td,{children:"Intersection length per unit fracture area"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Mean Intersection Angle"})}),(0,i.jsx)(t.td,{children:"Mean dihedral angle with intersecting fractures"})]})]})]}),"\n",(0,i.jsx)(t.h3,{id:"topology-attributes",children:"Topology Attributes"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Attribute"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Node Count"})}),(0,i.jsx)(t.td,{children:"Graph nodes on this fracture"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"I-Node Count (Tips)"})}),(0,i.jsx)(t.td,{children:"Free ends (degree 1)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Y-Node Count (Abutments)"})}),(0,i.jsx)(t.td,{children:"Abutting junctions (degree 3)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"X-Node Count (Crossings)"})}),(0,i.jsx)(t.td,{children:"Crossing junctions (degree 4)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Branch Count"})}),(0,i.jsx)(t.td,{children:"Graph edges on this fracture"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Connections Per Line"})}),(0,i.jsx)(t.td,{children:"Y+X junction count for this fracture"})]})]})]}),"\n",(0,i.jsx)(t.h3,{id:"stress-attributes",children:"Stress Attributes"}),"\n",(0,i.jsxs)(t.p,{children:["Stress attributes are resolved on each fracture plane from the full 3D stress tensor configured in the project's stress settings (principal magnitudes and plunge/azimuth directions). Three failure parameters are configurable ",(0,i.jsx)(t.strong,{children:"per DFN"})," in the properties panel under ",(0,i.jsx)(t.strong,{children:"Stress Parameters"}),":"]}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Parameter"}),(0,i.jsx)(t.th,{children:"Default"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Pore Pressure (Pp)"})}),(0,i.jsx)(t.td,{children:"0 MPa"}),(0,i.jsx)(t.td,{children:"Pore fluid pressure for effective-stress calculations"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Friction Coefficient (\u03bc)"})}),(0,i.jsx)(t.td,{children:"0.6"}),(0,i.jsx)(t.td,{children:"Coulomb friction coefficient"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Cohesion (C0)"})}),(0,i.jsx)(t.td,{children:"0 MPa"}),(0,i.jsx)(t.td,{children:"Cohesive strength in the Coulomb criterion"})]})]})]}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Attribute"}),(0,i.jsx)(t.th,{children:"Formula"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Normal Stress (\u03c3n)"})}),(0,i.jsx)(t.td,{children:"t\xb7n with t = S\xb7n"}),(0,i.jsx)(t.td,{children:"Stress normal to the fracture plane (MPa)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Shear Stress (\u03c4)"})}),(0,i.jsx)(t.td,{children:"\u221a(|t|\xb2 \u2212 \u03c3n\xb2)"}),(0,i.jsx)(t.td,{children:"Shear stress on the fracture plane (MPa)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Slip Tendency (Ts)"})}),(0,i.jsx)(t.td,{children:"\u03c4 / \u03c3n"}),(0,i.jsx)(t.td,{children:"Shear reactivation potential (Morris et al. 1996)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Dilation Tendency (Td)"})}),(0,i.jsx)(t.td,{children:"(\u03c31 \u2212 \u03c3n) / (\u03c31 \u2212 \u03c33)"}),(0,i.jsx)(t.td,{children:"Tendency to dilate and conduct fluid"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Fracture Susceptibility"})}),(0,i.jsx)(t.td,{children:"(\u03c3n \u2212 Pp) \u2212 (\u03c4 \u2212 C0)/\u03bc"}),(0,i.jsxs)(t.td,{children:["Pore-pressure increase required to reach Coulomb failure (MPa). ",(0,i.jsx)(t.strong,{children:"Negative values indicate critically stressed fractures"})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Critically Stressed"})}),(0,i.jsx)(t.td,{children:"\u03c4 \u2265 C0 + \u03bc\xb7(\u03c3n \u2212 Pp)"}),(0,i.jsx)(t.td,{children:"Boolean Mohr-Coulomb failure flag"})]})]})]}),"\n",(0,i.jsx)(t.h4,{id:"interpretation",children:"Interpretation"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"High Slip Tendency (Ts > 0.6)"}),": Fracture likely to slip under the current stress"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"High Dilation Tendency (Td > 0.6)"}),": Fracture likely open/conductive"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Low or negative Fracture Susceptibility"}),": Fracture at or near the failure envelope \u2014 candidate for reactivation and induced seismicity risk"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"export",children:"Export"}),"\n",(0,i.jsxs)(t.p,{children:["All exports live under the DFN's right-click ",(0,i.jsx)(t.strong,{children:"Export"})," submenu."]}),"\n",(0,i.jsx)(t.h3,{id:"fractures-to-fab",children:"Fractures to FAB..."}),"\n",(0,i.jsxs)(t.p,{children:["Writes the fracture geometry in FracMan ASCII (",(0,i.jsx)(t.code,{children:".fab"}),") format: one record per active fracture (polygon vertices plus the plane normal), with fracture-set names in the ",(0,i.jsx)(t.code,{children:"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)."]}),"\n",(0,i.jsx)(t.h3,{id:"set-statistics-to-csv",children:"Set Statistics to CSV..."}),"\n",(0,i.jsxs)(t.p,{children:["One row per fracture set: orientation statistics (mean dip/azimuth, Fisher K), size-distribution parameters, spatial model and termination settings, target vs ",(0,i.jsx)(t.strong,{children:"realized"})," P32, total fracture area, fracture count, and the provenance tags shown in the properties panel."]}),"\n",(0,i.jsx)(t.h3,{id:"fractures-to-csv",children:"Fractures to CSV..."}),"\n",(0,i.jsx)(t.p,{children:"One row per fracture: id, set, centroid coordinates, dip, azimuth, radius, polygon area, vertex count, and active flag \u2014 ready for external statistical analysis."}),"\n",(0,i.jsx)(t.h3,{id:"intersection-lines-as-polylines",children:"Intersection Lines as Polylines"}),"\n",(0,i.jsxs)(t.p,{children:["Creates a polyline group in the project tree (",(0,i.jsx)(t.code,{children:"DFN-Intersection Lines"}),") from the fracture-fracture intersection segments, with each fracture pair's segments merged into continuous chains. Run ",(0,i.jsx)(t.strong,{children:"Fracture Intersections"})," first. The polylines are ordinary project objects, so they can be exported onward via the standard polyline export."]}
1),"\n",(0,i.jsx)(t.h2,{id:"analysis",children:"Analysis"}),"\n",(0,i.jsxs)(t.p,{children:["The DFN's right-click ",(0,i.jsx)(t.strong,{children:"Analysis"})," submenu provides quantitative network analyses."]}),"\n",(0,i.jsx)(t.h3,{id:"virtual-scanlines-to-csv",children:"Virtual Scanlines to CSV..."}),"\n",(0,i.jsx)(t.p,{children:"Samples the network along three virtual scanlines through the domain centre (one per axis) \u2014 the numerical equivalent of a scanline survey or vertical borehole. The CSV report contains:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Per-set summary"}),": intersection count, raw P10 (fractures/m), and ",(0,i.jsx)(t.strong,{children:"Terzaghi-corrected P10"})," for each scanline. The Terzaghi correction weights each intersection by 1/|cos \u03b8| (\u03b8 = angle between the scanline and the fracture pole) to compensate for the orientation sampling bias; weights are capped at 7 (\u22488\xb0 blind zone, Priest 1993)."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Per-intersection detail"}),": fracture id, set, position, distance along the line, cos \u03b8, and weight \u2014 ready for spacing analysis."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Compare the Terzaghi-corrected P10 of a vertical scanline against real borehole fracture frequencies to validate intensity."}),"\n",(0,i.jsx)(t.h3,{id:"percolation-analysis",children:"Percolation Analysis"}),"\n",(0,i.jsxs)(t.p,{children:["Builds connected clusters from the fracture-fracture intersections (run ",(0,i.jsx)(t.strong,{children:"Fracture Intersections"})," first) and reports:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Cluster count and the number of isolated (non-intersecting) fractures"}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"largest-cluster fraction"})," of fractures and of area \u2014 the percolation order parameter"]}),"\n",(0,i.jsxs)(t.li,{children:["Whether any cluster ",(0,i.jsx)(t.strong,{children:"spans the domain"})," along X, Y, and Z (its geometry reaches both opposite faces)"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"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."}),"\n",(0,i.jsx)(t.h3,{id:"oda-permeability-tensor",children:"Oda Permeability Tensor..."}),"\n",(0,i.jsx)(t.p,{children:"Computes the upscaled equivalent permeability tensor (Oda 1985) for a user-specified hydraulic aperture, treating each fracture as a parallel-plate conduit (cubic law):"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"k_ij = (a\xb3 / 12V) \xb7 \u03a3 A_k (\u03b4_ij \u2212 n_i n_j)\n"})}),"\n",(0,i.jsx)(t.p,{children:"The report gives the principal permeabilities k1 \u2265 k2 \u2265 k3 (m\xb2) with their plunge/trend directions, the fracture porosity (a\xb7P32), and the full tensor in the log. Note this assumes every fracture is hydraulically connected \u2014 an upper bound;
1 combine with the Percolation Analysis for context."}),"\n",(0,i.jsx)(t.h3,{id:"validating-against-mapped-traces",children:"Validating against mapped traces"}),"\n",(0,i.jsxs)(t.p,{children:["Where the DFN is meant to represent a real outcrop, ",(0,i.jsx)(t.strong,{children:"Score DFN against\nSelected Traces\u2026"})," cuts the network with the outcrop mesh, compares the\nresulting synthetic traces against your interpretation, and writes a visual\nreport covering length distribution, orientation fabric and intensity \u2014 per\nfracture set as well as pooled."]}),"\n",(0,i.jsxs)(t.p,{children:["See ",(0,i.jsx)(t.a,{href:"/docs/next/general/fractures-structure/dfn-validating-against-outcrop",children:"DFN \u2014 Validating Against Outcrop"}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,i.jsx)(t.h3,{id:"for-realistic-networks",children:"For Realistic Networks"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Base parameters on field measurements when available \u2014 use ",(0,i.jsx)(t.strong,{children:"Create DFN from Selected Groups"})," so orientation statistics come from your data"]}),"\n",(0,i.jsx)(t.li,{children:"Use multiple fracture sets to represent different deformation events"}),"\n",(0,i.jsx)(t.li,{children:"Validate P32 intensity against borehole or scanline data"}),"\n",(0,i.jsx)(t.li,{children:"Compare generated orientation distributions with stereonet data"}),"\n",(0,i.jsxs)(t.li,{children:["Use the Match Quality panel (see the ",(0,i.jsx)(t.a,{href:"/docs/next/general/fractures-structure/dfn-interpretation-matching",children:"Interpretation Matching guide"}),") to score the DFN against observed traces"]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"for-performance",children:"For Performance"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Start with low P32 during parameter tuning"}),"\n",(0,i.jsx)(t.li,{children:"Use proximity filtering to focus on relevant fractures"}),"\n",(0,i.jsxs)(t.li,{children:["Run ",(0,i.jsx)(t.strong,{children:"Fracture Intersections"})," only when needed \u2014 intersection and graph computation scale with fracture count"]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"for-analysis",children:"For Analysis"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Run ",(0,i.jsx)(t.strong,{children:"Fracture Intersections"})," before generating connectivity or topology attributes"]}),"\n",(0,i.jsx)(t.li,{children:"Use attributes for quantitative comparisons between realizations"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsx)(t.h3,{id:"no-fractures-generated",children:"No fractures generated"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Check that domain bounds are set correctly"}),"\n",(0,i.jsx)(t.li,{children:"Verify P32 intensity is greater than 0"}),"\n",(0,i.jsx)(t.li,{children:"Ensure at least one fracture set is enabled"}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"slow-intersection-computation",children:"Slow intersection computation"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Reduce fracture count (lower P32 or smaller domain)"}),"\n",(0,i.jsx)(t.li,{children:"Use proximity filtering to limit active fractures"}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"mesh-intersections-disconnected",children:"Mesh intersections disconnected"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Segments from the same fracture are automatically merged"}),"\n",(0,i.jsx)(t.li,{children:"If gaps exist, the mesh may have holes or the fracture doesn't fully intersect"}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"slicers-not-showing",children:"Slicers not showing"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Ensure slicer is enabled AND position slider is moved"}),"\n",(0,i.jsx)(t.li,{children:"Check that fractures exist within the slice plane"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"advanced-statistical-analysis",children:"Advanced Statistical Analysis"}),"\n",(0,i.jsx)(t.p,{children:"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."}),"\n",(0,i.jsx)(t.h3,{id:"distribution-fitting",children:"Distribution Fitting"}),"\n",(0,i.jsx)(t.p,{children:"Fit statistical distributions to fracture size data using Maximum Likelihood Estimation (MLE) with Kolmogorov-Smirnov goodness-of-fit testing."}),"\n",(0,i.jsx)(t.h4,{id:"supported-distributions",children:"Supported Distributions"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Distribution"}),(0,i.jsx)(t.th,{children:"Parameters"}),(0,i.jsx)(t.th,{children:"Use Case"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Power Law"})}),(0,i.jsx)(t.td,{children:"\u03b1 (exponent), x_min"}),(0,i.jsx)(t.td,{children:"Scale-invariant fracture lengths (most common)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Lognormal"})}),(0,i.jsx)(t.td,{children:"\u03bc, \u03c3, x_min"}),(0,i.jsx)(t.td,{children:"Natural log-normal processes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Exponential"})}),(0,i.jsx)(t.td,{children:"\u03bb (rate), x_min"}),(0,i.jsx)(t.td,{children:"Constant spacing/fragmentation"})]})]})]}),"\n",(0,i.jsx)(t.h4,{id:"how-it-works-1",children:"How It Works"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"MLE Fitting"}),": Parameters estimated by maximizing likelihood"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"x_min Optimization"}),": Lower bound automatically selected to minimize the K-S statistic; all theoretical CDFs are conditioned on x \u2265 x_min so the three families compete fairly"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Bootstrap K-S Testing"}),": The selected fit's p-value comes from a semi-parametric bootstrap (Clauset et al. 2009) \u2014 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"]}),"\n"]}),"\n",(0,i.jsx)(t.h4,{id:"power-law-mle",children:"Power Law MLE"}),"\n",(0,i.jsx)(t.p,{children:"For power law P(x) ~ x^(-\u03b1):"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"\u03b1 = 1 + n / \u03a3[ln(x_i / x_min)]\n"})}),"\n",(0,i.jsx)(t.p,{children:"The finite-size correction is applied for small samples."}),"\n",(0,i.jsx)(t.h4,{id:"interpretation-1",children:"Interpretation"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"p-value"}),(0,i.jsx)(t.th,{children:"Interpretation"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"> 0.10"}),(0,i.jsx)(t.td,{children:"Good fit"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0.05 - 0.10"}),(0,i.jsx)(t.td,{children:"Marginal fit"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"< 0.05"}),(0,i.jsx)(t.td,{children:"Poor fit - distribution may not apply"})]})]})]}),"\n",(0,i.jsx)(t.h4,{id:"fitting-a-tail-vs-fitting-a-generator",children:"Fitting a tail vs fitting a generator"}),"\n",(0,i.jsxs)(t.p,{children:["The x_min search answers ",(0,i.jsx)(t.em,{children:'"is some tail of this data a power law?"'})," \u2014 the right\nquestion for testing a hypothesis, and the reason each family is free to choose\nits own cutoff."]}),"\n",(0,i.jsxs)(t.p,{children:["It is the wrong question when the fit becomes a ",(0,i.jsx)(t.strong,{children:"generator's"})," size\ndistribution, because the model is then used across the whole range rather than\nabove a cutoff. Using the searched x_min as the generator's minimum size\ndiscards the body of the population, and shape parameters estimated on a tail\nextrapolate badly downwards."]}),"\n",(0,i.jsx)(t.p,{children:"So when a DFN is created from measurements, the families are re-fitted and\nre-selected over the full observed range, with the lower bound pinned to the\nsmallest measurement. The generated size population then spans, and matches,\nwhat was measured."}),"\n",(0,i.jsx)(t.h4,{id:"references",children:"References"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:'Clauset et al. (2009) "Power-Law Distributions in Empirical Data"'}),"\n",(0,i.jsx)(t.li,{children:'Newman (2006) "Power Laws, Pareto Distributions and Zipf\'s Law"'}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"fisher-concentration-from-pole-data",children:"Fisher Concentration from Pole Data"}),"\n",(0,i.jsx)(t.p,{children:"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:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"K \u2248 R(3 \u2212 R\xb2) / (1 \u2212 R\xb2)\n"})}),"\n",(0,i.jsx)(t.p,{children:"This is the spherical (3D) maximum-likelihood estimator \u2014 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]."}),"\n",(0,i.jsxs)(t.p,{children:["R is computed ",(0,i.jsx)(t.strong,{children:"axially"}),", via the orientation tensor ",(0,i.jsx)(t.code,{children:"T = (1/n) \u03a3 p p\u1d40"}),", whose\nprincipal eigenvector gives the mean axis; each pole is folded into that\nhemisphere before the resultant is summed. Averaging poles as plain vectors\nlets two descriptions of the same plane cancel \u2014 and because dip is reported in\n[0, 90], a subvertical set has exactly that problem: its two valid descriptions\nsit at opposite ends of one near-horizontal axis. Steep sets, which are the\ncommon case in outcrop, are the ones a vector average gets most wrong."]}),"\n",(0,i.jsx)(t.h3,{id:"circular-statistics",children:"Circular Statistics"}),"\n",(0,i.jsx)(t.p,{children:"For circular (2D angular) data such as strikes and paleocurrent directions:"}),"\n",(0,i.jsx)(t.h4,{id:"axial-vs-vectorial-data",children:"Axial vs Vectorial Data"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Type"}),(0,i.jsx)(t.th,{children:"Range"}),(0,i.jsx)(t.th,{children:"Examples"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Axial"})}),(0,i.jsx)(t.td,{children:"0-180\xb0 (headless)"}),(0,i.jsx)(t.td,{children:"Fracture strikes, lineation trends"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Vectorial"})}),(0,i.jsx)(t.td,{children:"0-360\xb0 (directed)"}),(0,i.jsx)(t.td,{children:"Dip directions, current azimuths"})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"For axial data, angles are doubled before analysis and results halved."}),"\n",(0,i.jsx)(t.h4,{id:"computed-statistics",children:"Computed Statistics"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Statistic"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Mean Direction"})}),(0,i.jsx)(t.td,{children:"Circular mean of angles"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Resultant Length (R)"})}),(0,i.jsx)(t.td,{children:"0-1, measures concentration (0 = uniform, 1 = identical)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Circular Variance"})}),(0,i.jsx)(t.td,{children:"1 - R"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Circular Std Dev"})}
1),(0,i.jsx)(t.td,{children:"\u221a(-2\xb7ln(R))"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Concentration (\u03ba)"})}),(0,i.jsx)(t.td,{children:"von Mises dispersion parameter (2D circular estimator)"})]})]})]}),"\n",(0,i.jsx)(t.h4,{id:"uniformity-tests",children:"Uniformity Tests"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Test"}),(0,i.jsx)(t.th,{children:"Output"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Rayleigh Test"})}),(0,i.jsx)(t.td,{children:"Tests for unimodal concentration (Z = nR\xb2 against a critical value)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Watson U\xb2 Test"})}),(0,i.jsx)(t.td,{children:"p-value for non-uniformity on the circle"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Kuiper Test"})}),(0,i.jsx)(t.td,{children:"Test statistic V_n (compare against published critical values)"})]})]})]}),"\n",(0,i.jsx)(t.h4,{id:"references-1",children:"References"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:'Fisher (1993) "Statistical Analysis of Circular Data"'}),"\n",(0,i.jsx)(t.li,{children:'Mardia & Jupp (2000) "Directional Statistics"'}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"fabric-tensor-analysis",children:"Fabric Tensor Analysis"}),"\n",(0,i.jsx)(t.p,{children:"Quantify fracture network anisotropy using Oda's 2nd-rank fabric tensor (crack tensor)."}),"\n",(0,i.jsx)(t.h4,{id:"fabric-tensor-f2",children:"Fabric Tensor (F2)"}),"\n",(0,i.jsx)(t.p,{children:"The tensor is computed as:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"F2_ij = (1/V) * \u03a3[A_p * n_i * n_j]\n"})}),"\n",(0,i.jsx)(t.p,{children:"Where:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"V = domain volume"}),"\n",(0,i.jsx)(t.li,{children:"A_p = fracture area"}),"\n",(0,i.jsx)(t.li,{children:"n = unit pole vector (normal to fracture)"}),"\n"]}),"\n",(0,i.jsx)(t.h4,{id:"output-properties",children:"Output Properties"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Property"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"F2 Matrix"})}),(0,i.jsx)(t.td,{children:"3x3 symmetric tensor"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Eigenvalues"})}),(0,i.jsx)(t.td,{children:"Principal anisotropy magnitudes (\u03bb1 \u2265 \u03bb2 \u2265 \u03bb3)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Eigenvectors"})}),(0,i.jsx)(t.td,{children:"Principal anisotropy directions"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Trace"})}),(0,i.jsx)(t.td,{children:"\u03bb1 + \u03bb2 + \u03bb3 (proxy for P32)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Anisotropy Ratio"})}),(0,i.jsx)(t.td,{children:"\u03bb1 / \u03bb3 (1 = isotropic, higher = anisotropic)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Shape Factor"})}),(0,i.jsx)(t.td,{children:"(\u03bb1 - \u03bb2) / (\u03bb1 - \u03bb3) (0 = prolate, 1 = oblate)"})]})]})]}),"\n",(0,i.jsx)(t.h4,{id:"interpretation-2",children:"Interpretation"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Anisotropy Ratio"}),(0,i.jsx)(t.th,{children:"Interpretation"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1.0 - 1.5"}),(0,i.jsx)(t.td,{children:"Nearly isotropic"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1.5 - 3.0"}),(0,i.jsx)(t.td,{children:"Moderately anisotropic"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3.0 - 10.0"}),(0,i.jsx)(t.td,{children:"Strongly anisotropic"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"> 10.0"}),(0,i.jsx)(t.td,{children:"Highly anisotropic (single dominant set)"})]})]})]}),"\n",(0,i.jsx)(t.h4,{id:"reference",children:"Reference"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:'Oda (1982) "Fabric tensor for discontinuous geological materials"'}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453(e,t,r){r.d(t,{R:()=>a,x:()=>l});var n=r(96540);const i={},s=n.createContext(i);function a(e){const t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.