In this contribution we introduce LoopStructural, a new open-source 3D
geological modelling Python package (

Understanding and characterising the geometry and interaction between geological features in the subsurface is an important stage in resource identification and management. A surface or combination of surfaces can be used to represent the subsurface geometry of geological features or structural elements within 3D geological models (Caumon et al., 2009). There are two main approaches for representing surfaces in 3D geological models: (1) one in which the surface is represented by directly triangulating control points defining the surface geometry or (2) one in which the surface is extracted as an isovalue or level set of an implicit function (Wellmann and Caumon, 2018). Explicit surface representation in geological modelling refers to manually drawn surfaces and is usually time consuming and requires significant subjective user input because surfaces are usually sculpted to the modellers conceptual idea in a similar way to drawing polylines in geographical information systems or using computer-aided design software. Implicit surface representation involves approximating an unknown function that represents the distance to a geological surface. The implicit function can be queried anywhere throughout the model for the value or gradient of the function. The implicit function is fitted to observations that are used to infer the geometry of a geological surface, for example the distance to the geological surface (for stratigraphic horizons this may be the cumulative thickness) or the gradient of the function (on contact or off contact) observations. The topological relationships between different geological features, e.g. horizons, faults interactions, intrusions and unconformities, are incorporated using multiple implicit functions for different components of the model. Implicit surface representation removes the need to generate surfaces and allows for the geological features to be represented directly by the implicit function value.

All implicit surface modelling techniques involve finding a combination of
weighted basis functions that fit the geological observations. There are two
main approaches used for implicit surface modelling: (1) data-supported
approaches where the basis functions are estimated at the data points
(Calcagno et al.,
2008a; Cowan et al., 2003; Gonçalves et al., 2017; Hillier et al., 2014;
Lajaunie et al., 1997) and (2) discrete interpolation where the basis
functions are located on a predefined support
(Caumon et
al., 2013; Frank et al., 2007; Irakarama et al., 2018; Renaudeau et al.,
2019). The algorithms are often linked to commercial software, e.g. Leapfrog

In this contribution we introduce the open-source LoopStructural, a 3D geological
modelling Python library based on the incremental contributions of Laurent
et al. (2016) and Grose et al. (2017, 2018, 2019). LoopStructural is a new geological
modelling engine developed within the Loop

This paper begins with a background analysis of 3D modelling methods and the
algorithms used in implicit modelling, with an overview of the mathematical
and geological backgrounds used in our implementation. A detailed overview
of the specifics of the implementation can be found on
(

A 3D geological model can be represented by a collection of surfaces
representing geological features (e.g. fault surfaces, stratigraphic
horizons, axial surfaces of folds, unconformities)
(Wellmann and Caumon, 2018). There are two
main tasks for a 3D modelling software package:

the creation of the surfaces from geological observations and knowledge,
this is known as

the incorporation of geological concepts into the surface description, e.g. faulted surfaces should show displacement and unconformities should be a boundary between units.

Implicit surface modelling involves the representation of the geometry of a
geological feature using a function

These implicit functions have no known analytical solution, which means that
they need to be approximated from the observations that are provided. The
implicit function is represented by a weighted combination of basis
functions:

Geological observations that are directly incorporated into 3D modelling can generally be divided into two categories: observations that describe the orientation of a geological feature (on contact and off contact) and observations that describe the location within a geological feature (cumulative thickness for conformable stratigraphic horizons, or location of fault surface). In the context of a geological map, location observations may be the trace of a geological surface on the geological map, or a single point observation at an outcrop or from a borehole. Orientation observations generally record a geometrical property of the surface – e.g. a vector that is tangential to the plane or the vector that is normal to the plane (black and dashed arrows in Fig. 1).

Schematic showing different types of interpolation constraints that can be applied to an implicit interpolation scheme in 2-D. There are two interfaces: the reference horizon with a value of 0 and the next interface with a value of 1. Here we show three types of constraints: (1) scalar field norm constraints constrain the orientation of the scalar field and the norm of the implicit function at that location; (2) scalar field value constraints control the value of the scalar field; and (3) tangent constraints constrain only the orientation of the implicit function not the norm. Figure adapted from Hillier et al. (2014).

When modelling using the potential field approach, the value of the scalar field is inferred through the magnitude of the normal control points. Using the signed distance approach, the value of the scalar field is defined by the value of the observations and effectively controls the thickness of the layers. Orientation constraints either control a component of the orientation, e.g. specifying that the gradient of the function should be orthogonal to the observation or constrain the magnitude and direction of the norm of the gradient of the implicit function.

All geological observations constrain a component of the implicit function
at a location in the model:

Observations for the location of the geological feature will constrain the
value of the scalar field

Observations for the orientation of the contact can either

constrain the partial derivatives of the function

constrain a vector which is parallel to the contact

The volumetric scalar field is defined by a piece-wise linear function on a
volumetric tetrahedral mesh. In LoopStructural the volumetric tetrahedral mesh creation is
simplified by subdividing a regular Cartesian grid into a tetrahedral mesh
where one cubic element is divided into five tetrahedra (see Appendix A). The
linear tetrahedron is the basis of the piecewise linear interpolation
algorithm, where the property within the tetrahedron is interpolated using a
linear function; see Appendix A for a detailed description of the linear
basis function. We use constant gradient regularisation
(Caumon et al., 2013; Frank
et al., 2007; Mallet, 1992), where the change in gradient of the implicit
function is minimised between tetrahedra with a shared face. The constant
gradient regularisation is as follows:

The second discrete interpolation approach approximates the interpolant
using a combination of tri-linear basis functions on a Cartesian grid. The
basis functions describe the interpolation as a function of the corners of
the cell within which the point where the function is to be estimated falls;
see Appendix B for the trilinear basis functions. For example, to evaluate
the value of the implicit function at a point

Using either the piecewise linear interpolator or the finite-difference
interpolator the scalar field is defined by the node values of the support.
These can be found by solving a system of equations with

The interpolation problem is over-constrained, i.e.

Another approach for implicit surface modelling is to use basis functions that are located at the same location as data points.

This can be done using radial basis interpolation where the
interpolation problem is attempting to approximate the signed distance
field:

LoopStructural uses SurfE, a C++ implementation of the generalised radial basis interpolation (Hillier et al., 2014) for all data-supported interpolations. SurfE has three approaches for implicit surface reconstruction (1) signed distance interpolation using radial basis functions, (2) potential field interpolation using dual co-kriging (Lajaunie et al., 1997) and (3) signed distance interpolation using a separate scalar field for each surface. The interface between LoopStructural and SurfE allows the user to access all of the interpolation parameters used by SurfE. These include access to more sophisticated solvers, as well as the addition of a smoothing parameter into the interpolation.

There are three ways that the geometry of rock packages can structurally
interact in a geological model:

stratigraphic contacts – the contact between sedimentary layers;

fault contacts;

intrusive contacts.

In an implicit geological model, the distribution of stratigraphic packages is defined by the values of a volumetric scalar field. The scalar field is defined by an implicit function that is fitted to observations (location and orientation) defining the geometry of the top or base of a geological unit. A single geological interface can be modelled using a single scalar field, or multiple conformable interfaces can be modelled using a single scalar field where different isovalues are used to represent the different contacts. A stratigraphic group can be considered as a collection of stratigraphic surfaces that are conformable. When modelling a stratigraphic group, the value of the scalar field represents the distance away from the base of a group of conformable layers.

Unconformities interfaces (red lines) and geological interfaces
(black lines) represent a break in depositional history. There are different
possible geometries that an unconformity can have:

An unconformity is a geological interface where the rock units on either side are of significantly different ages, usually representing a period of erosion. In Fig. 3 the three conventional types of unconformity are shown. In Fig. 3a. the unconformity between the units is a disconformity and the geometry of the disconformity is not associated with either stratigraphic package. The disconformity is usually identified by the significant gap between the ages of the rocks. In this type of contact the layers actually share a similar geometry and for the purpose of 3D modelling the units could be represented by a single stratigraphic group. Angular unconformities (Fig. 3b) are observed when erosion occurs after some deformation (the older beds are not horizontal anymore) and before the next deposition of sedimentary layers. As the name suggests the angular unconformity represents a boundary between two differently oriented stratigraphic sequences. In a 3D model an angular unconformity can be introduced by setting the boundary between the two sequences to be the base of the younger package. In practice, this means that the two groups are modelled with two separate scalar fields. In Fig. 3c a nonconformity is shown; in this type of unconformity the geometry of the older unit defines the base of the younger unit. This could occur when a stratigraphic package is deposited on top of a crystalline basement.

A structural frame (Fig. 4) is a local coordinate
system that is built around the major structural elements of a geological
event. In LoopStructural structural frames are used for characterising the geometry of
folds where the major structural element is the fold axial foliation
(Fig. 4b) and the structural direction is roughly
the fold axis. A fault frame is a structural frame where the major
structural feature is the fault surface, the structural direction is the fault slip
and the intermediate direction is the fault extent
(Fig. 4). In LoopStructural, structural frames are built by
first building the major structural feature which will typically have more
observations, e.g. fault surface location or axial foliations. The structural
direction is then built using any available observations of the structural
direction, e.g. local observations of the fault slip or the fold axis,
combined with an additional constraint which sets the gradient of the scalar
field to be orthogonal to the major structural feature. The third
coordinate can be built with an arbitrary value constraint, or value
constraints to specify the extent of the field in this direction (e.g. for
faults

“A fault is a tabular volume of rock consisting of a central slip surface or core, formed by an intense shearing, and a surrounding volume of rock that has been affected by more gentle brittle deformation spatially and genetically related to the fault” (Fossen, 2010).

When adding faults there are two aspects to modelling the fault: (1) building the fault surface geometry and (2) integrating the fault displacement into older surfaces. Where possible, measurements of faults include the movement direction and the magnitude of displacement. There are three broad approaches for integrating faults into the implicit modelling framework: (1) add the fault into the implicit description of the surface (Calcagno et al., 2008a; de la Varga et al., 2019); (2) apply the fault after interpolating a continuous surface (Godefroy et al., 2018a; Laurent et al., 2013) and (3) represent the foot wall and hanging wall by separate implicit functions. Regardless of the approach used, the geometry of the fault surface is defined before defining the geometry of the surfaces displaced by the fault. The fault surface can be interpolated by building a scalar field where the fault surface is represented by an isovalue.

Fault displacement profiles:

In LoopStructural there are two ways of representing faults: (1) the fault kinematics are
added into the implicit description of the scalar field of the faults and
applied to the affected scalar field(s) (Grose et al., 2021a) and (2) faults are treated as domain boundaries and separate scalar
fields are used to model the hanging wall and footwall of the fault. The
kinematics of the fault are added into the implicit description of the
faulted surface. To do this a fault frame is built
(Fig. 4c) where three coordinates are interpolated:
(1) a scalar field representing the distance to the fault surface, (2) a
scalar field representing the distance along the slip direction of the fault
and (3) a scalar field representing the extent of the fault. These
coordinates can then be used to define the fault ellipsoid, which is a
volumetric representation of the area deformed by the fault. The
displacement of the fault can be defined relative to this coordinate system,
e.g. the displacement of the fault should decay away from the fault centre
along the fault extent and along the direction of displacement using the
bell-shaped curve (Fig. 5d). The displacement may
decrease with distance away from the fault centre perpendicular to the fault
surface; this can be defined using the profile in
Fig. 5c. If the displacement is constant within
the model area the curves in Fig. 5a and b can be
substituted for Fig. 5c and d respectively. The displacement curves shown in
Fig. 5 can be substituted for any function of the
fault frame coordinates. The same approach for combining the fault profiles
(Fig. 5) within the fault frame has been used to
define a volumetric fault displacement field
(Jessell and Valenta, 1996; Godefroy et
al., 2018b), the latter of which was adapted from the following
Laurent et al. (2013):

The fault frame can be built using a discrete implicit modelling approach as
additional constraints can be added into the interpolation to enforce the
orthogonality of the three coordinate systems. This is added into the
interpolation matrix by adding a constraint for every element in the mesh
where

Folds are challenging to model using classical implicit interpolation algorithms, because by definition a folded surface has a symmetry only defined by their axial surface. The symmetry is hard to reproduce by only interpolating orientations of the folded foliation as this would require orientations to be sampled in a symmetrical way across the axial surface (Laurent et al., 2016; Lisle et al., 2007; Mynatt et al., 2007). The regularisation of implicit algorithms are usually defined to minimise some sort of curvature between observations such as constant gradient regularisation, minimising second derivatives using finite differences or the weighted combination of infinite basis functions (Calcagno et al., 2008a; Cowan et al., 2003; Frank et al., 2007; Jessell et al., 2014; Lajaunie et al., 1997; Laurent, 2016; Mallet, 2014). As a result, to model folded geometries the geologist is required to add interpretive constraints such as synthetic bore holes, cross sections or simply synthetic constraints to produce model geometries that fit the geologist's conceptual idea of the fold (Caumon et al., 2003; Jessell et al., 2014, 2010).

There have been a number of different approaches to incorporating folds into implicit modelling including incorporating the fold axial surfaces (Laurent et al., 2016; Maxelon et al., 2009), the fold axis (Hillier et al., 2014; Laurent et al., 2016; Massiot and Caumon, 2010), both these structural elements and fold overprinting relationships (Laurent et al., 2016).

LoopStructural implements the following fold constraints: the fold axis, fold axial surface and overprinting relationships (Laurent et al., 2016) by adding additional constraints into a discrete interpolation approach. A fold frame (Figs. 4b and 6) is built where the principal axes of the fold frame correspond with the direction of the finite-strain ellipsoid. The fold frame allows for the geometry of the folded surface to be defined.

Schematic diagram of a fold adapted from Laurent et al. (2016) showing

The orientation of the fold axis (

The folded surface should contain the orientation of
the fold axis:

The folded surface will contain the fold direction (solid red arrow in
Fig. 6b3) vector:

The regularisation should only occur within the intermediate structural
direction (

A similar fold constraint is as follows:

The fold limb rotation angle

In LoopStructural the default approach for fitting the fold rotation angle is to fit a
Fourier series. The fold axis rotation angle is calculated first; the
wavelength is first estimated automatically using the gradient descent
method on the experimental variogram of the fold axis. The fold rotation
angle is optimised using the scipy.optimize.curve_fit method using non-linear least squares to fit
wavelength and Fourier coefficients. The fold axis can then be defined
throughout the model by applying the rotation of

The fold limb rotation angle is calculated by finding the complementary
angle between the normal to the folded foliation and

Grose et al. (2018, 2019) use inverse problem theory to fit a forward model of the fold geometry to the observed fold rotation angles. The joint posterior distribution of the fold parameters (Fourier series coefficients, fold wavelength and a misfit parameter) are sampled using Bayesian inference. This allows multiple fold geometries to be explored without perturbing the datasets. LoopStructural does not provide a direct probabilistic interface; however, it is possible to define a probabilistic representation of the fold geometry curves and add this into the modelling workflow. An example using the Python library emcee (Foreman-Mackey et al., 2013) is provided in the LoopStructural documentation.

LoopStructural is written using Python 3.6+, using numpy data structures and operations. The
design of LoopStructural follows an object-oriented architecture with multiple levels of
inheritance. Object-oriented design allows for LoopStructural to be used as
a development platform for 3D geological modelling, where new features can
be added without needing to implement boiler plate code. There are five
submodules that can be imported into a Python environment:

Comparison of interpolation methods for synthetic surfaces where
two isosurfaces are shown coloured by the local

Within LoopStructural geological objects such as stratigraphy, faults, folding event and unconformities are all represented by a GeologicalFeature. A GeologicalFeature can be evaluated for the value of the scalar field and/or the gradient of the scalar field at a location.

The GeologicalModel contains an ordered collection of geological features and determines how the features interact. For example, unconformity geological features act as a mask to determine where the interface between packages should be. The ordering of the GeologicalFeatures inside the model reflects the timing of the geological events being modelled. The most recent features are added first as their geometry is used to constrain the older features.

There are different ways a GeologicalFeature can be added to a GeologicalModel depending on the type of geological object that is being modelled. The LoopStructural GeologicalModel class provides an interface for creating geological objects, where different types of geological features can be added using different functions. All geological objects are represented by one or multiple volumetric scalar field. These scalar fields can be built using an implicit interpolation algorithm where the implicit function is approximated from observations of the scalar field. Alternatively, a GeologicalFeature can be represented by an analytical function (or a combination of existing GeologicalFeatures). LoopStructural allows for different interpolation algorithms to be specified for different GeologicalFeatures within the same model. The interpolation algorithm and any parameter definitions are specified by adding additional keyword arguments to the function. Table 1 outlines the possible arguments that can be specified for the interpolator.

Interpolation keyword arguments. Default values are highlighted by bold text.

LoopStructural includes a number of helper functions for evaluating the
GeologicalModel on an array of coordinates within the model. The
following functions can be called from a GeologicalModel as shown
in the code below.

To evaluate the lithology value at a location the function evaluate_model(xyz) returns a numpy array containing the integer ID of the stratigraphy that was specified in the stratigraphic column.

To evaluate the value of a GeologicalFeature at a location within the model the function evaluate_feature_value(feature_name,xyz) returns the value of the scalar field that represents the geological feature.

To evaluate the gradient of a GeologicalFeature the evaluate_feature_gradient(feature_name,xyz) can be called.

LoopStructural has three different visualisation tools that can be accessed from the
LoopStructural.visualisation module:

Implicit surfaces calculated for regularisation constraints (0.1,0.5,1,1.5) using piecewise linear interpolator (PLI), finite-difference interpolator (FDI) and radial basis function (SurfE).

In the first example we will demonstrate modelling two synthetic surfaces
using the same scalar field within a model volume of (

In Fig. 7a the data points are shown, and in Fig. 7b, c and d the same surfaces are interpolated using the three default interpolation algorithms in LoopStructural (PLI – piecewise linear interpolator, FDI – finite-difference interpolator and SurfE – radial basis interpolation). The results for the interpolation using PLI and FDI are very similar, as both interpolation algorithms use least squares to fit observations whilst minimising a global regularisation term that effectively minimises the second derivative of the implicit function. This means that the interpolant balances fitting the observations with minimising the roughness of the resulting surfaces. The radial basis interpolation used by SurfE is a direct interpolation approach, which means that the interpolant must fit all of the observations (although a smoothing constraint can be used). In this example, because the surfaces are over-constrained to a highly variable point set the resulting surface is non-manifold (cannot be unfolded into a flat plane). While this does not necessarily mean the surface is incorrect it is geologically unlikely.

The weighting of the regularisation constraint generally has the biggest impact on the resulting geometry when using the discrete interpolation approaches. In Fig. 8 the regularisation constraint is varied from 0.1 (rougher surface) to 1.5 (smoother surface). Lower regularisation constraints result in surfaces that more closely fit the observations at the cost of a more irregular surface. However, even for the lowest regularisation constraints the surfaces still do not fit every observation. There is no explicit rule for choosing the relative weighting of the regularisation, as it is often dependent on the surfaces being modelled. For example, when modelling a surface where the underlying process causing the variation in the data points is non-stationary, a higher regularisation constraint is appealing as the goal of the modelling is to reproduce the effect of this process. However, if the perturbations are the result of a process we are trying to model (probably a stationary process) then a lower regularisation constraint would be appealing. A smoothing constraint can be added into the radial basis interpolation which aims to increase the smoothness of the resulting surface. The smoothing constraint for data-supported methods adds a buffer to how closely the function must fit the observations. In Fig. 8 increasing regularisation results in smoother surfaces; however, with this approach the fit to both surfaces is impacted, which can be seen by the change in colour of the surface, which represents the local height of the surface.

Structural data for refolded fold:

F2 S plot showing the fold rotation angle between observations of S1 and the fold frame S2.

F1 S plot showing the fold rotation angle between observations of S0 and the fold frame S1.

Scalar fields:

To demonstrate the time-aware approach for modelling folds we reuse the case
study from Laurent et al. (2016). The
reference model was generated using Noddy (Jessell and Valenta,
1996) with two folding events forming a type 3 interference pattern:

F1 involves large-scale recumbent folding (wavelength: 608 m, amplitude: 435 m, fold
axis: N000E/45

F2 involves upright open folding (wavelength: 400 m, amplitude: 30 m).

In the final examples we use map2loop (Jessell et al., 2021) as a pre-processor to generate an input dataset from regional geological survey maps, the national stratigraphic database and a global digital elevation model. map2loop creates a set of augmented data files that can be used to build a geological model in LoopStructural. The class method (GeologicalModel.from_map2loop_directory(m2l_directory, **kwargs)) creates an instance of a GeologicalModel from a root map2loop output directory. We will demonstrate the interface between map2loop and LoopStructural with two case studies (1) from the Flinders Ranges in South Australia and (2) from the Hamersley region in Western Australia. The first case study demonstrates the interface between map2loop and LoopStructural for a large regional model. The second case study shows how the conceptual model used to generate the input dataset can be varied.

The first example uses a small study area from South Australia using the Geological Survey of South Australia's open-access datasets (GSSA, 2020). The model area covers approximately 85 km by 53 km within the Finders Ranges in South Australia. The stratigraphic units within this area are shown in Fig. 13a, and the outcropping geology is shown in the geological map (Fig. 13b); the patches of the map without any geological units represent shallow Tertiary and Quaternary cover. map2loop extracts basal contacts from the outcropping geological units and estimates the layer thicknesses shown in the stratigraphic column. Within this map area all of the stratigraphic groups share a similar deformation history and area modelled as a single super-group. The cumulative thickness is estimated for all of the stratigraphic horizons relative to the Pound Subgroup and is used to constrain the value of the implicit function. There are 15 faults within the model area with limited geometrical information constraining only the map trace of the faults. As a result, the faults are assumed to be vertical with a vertical slip direction, and the displacements are estimated from the geometry on the geological map using map2loop. The geometry of the fault can be changed within LoopStructural and map2loop to explore the uncertainty space. The overprinting relationships of the faults are estimated from the geological map using map2loop by analysing the intersection between faults on the geological map. The estimated overprinting relationships are used to constrain the order of the faults in the geological model. The scalar field representing the supergroup is interpolated after the observations of the stratigraphic horizon (contacts and orientation measurements) are un-faulted using the calculated fault displacements. The modelling workflow is all encapsulated in the (GeologicalModel.from_map2loop_directory(m2l_directory, **kwargs)) class method, meaning the geological model can be produced without any user input.

The resulting geological model surfaces are shown in
Fig. 14 where the surface represents the base of a
stratigraphic group and are coloured using the stratigraphic column
(Fig. 13a). The faults in the model are interpolated
using a Cartesian grid with 50 000 elements and are interpolated using the
finite-difference interpolator, and the interpolation matrix is solved using
the pyamg algorithmic multigrid solver (Olson and Schroder, 2018).
Stratigraphy is interpolated using a finer mesh with 500 000 elements using
the finite-difference interpolator and also using pyamg. Using a workstation laptop
with an i7 processor and 32gb of RAM the data processing using map2loop takes
approximately 1 min, building the implicit model takes approximately 8 min and the rendering of the surfaces on a (

Geological model from South Australia using map2loop processed data stratigraphic surfaces using colours from Fig. 12a and fault surfaces.

In the second example we use map2loop to process a small area of the Turner Syncline in
the Hamersley region in Western Australia using data provided by the Geological
Survey of Western Australia (GSWA) (2016). The model area
is 12 km

The 12 model iterations where initial fault slip vector has been rotated around the normal to the fault surface. Stereonets show the resulting fault slip vectors (poles) and the fault plane (great circles).

LoopStructural is the 3D geological modelling module for Loop, a new open-source 3D probabilistic geological and geophysical modelling platform. LoopStructural integrates the relative timing of geological features into the description of the model elements using a time-aware modelling approach where the model is built by adding geological features in the reverse order from which they occur. This is necessary for capturing the complexities of complex structural geometries, for this approach is used for modelling refolded folds (Fig. 12). In a similar way faults are added backwards in time; this means that the displacements of the faults are applied to the model prior to interpolating the faulted surface. As a result, the fault displacements and overprinting relationships are internally consistent. In comparison, where faults are represented using step functions (Calcagno et al., 2008b; de la Varga and Wellmann, 2016) the fault displacements are added into the interpolation of the faulted surfaces using the polynomial trend in the dual co-kriging system, meaning the cumulative displacement is determined as the best global fit, rather than incorporating the displacements of individual faults.

LoopStructural provides a flexible open-source implementation of implicit geological modelling algorithms workflows. The motivation behind developing LoopStructural was to create a framework for being able to develop new implicit geological modelling algorithms and tools. LoopStructural has native implementation of piecewise linear interpolation (Caumon et al., 2013; Frank et al., 2007; Mallet, 1992, 2004), including the fold constraints (Grose et al., 2017; Laurent et al., 2016) and a finite-difference interpolator, minimising the second derivative as a regularisation constraint (Irakarama et al., 2018). In Fig. 8 we showed that choosing the regularisation weight is somewhat dependent on the quality of the input dataset. For this reason, varying the regularisation weight and interpolation approach should be a common step in implicit modelling workflows. The current implementation of the piecewise linear interpolation uses a tetrahedral mesh that is derived from a Cartesian grid. A more sophisticated mesh generated from an external mesh generation code could be integrated into LoopStructural by overwriting the tetrahedral mesh class with a custom class. Within the LoopStructural architecture alternative regularisation constraints could easily be incorporated. For example, it is possible to define custom constraints for implementation within the finite-difference scheme; the user simply has to provide a dictionary containing 3D numpy arrays, where each pixel in the array represents the 3D finite-difference mask and a relative weighting. New interpolation schemes can be easily implemented using various levels of inheritance to avoid re-writing boiler plate code. For example, the interface with SurfE capitalises on the object-oriented design of LoopStructural, where the interface between LoopStructural and SurfE was achieved by creating a new class which inherits the components for the base geological interpolation class. Both the piecewise linear interpolator and finite-difference interpolator inherit from a base discrete interpolation class which manages the assembly of the least squares system and the solving of the least squares problem. This object-oriented design allows for the interpolation algorithms to be interchanged and re-implemented without modifying the other aspects of the geological modelling.

A recent focus of 3D modelling research has been to simulate uncertainties by framing the problem as an inverse problem, where the data points are the parameters of the forward model (de la Varga et al., 2019). This allows for additional geological knowledge to be integrated into the model definition such as fault displacement, fault type and fold geometry. Within LoopStructural, we have directly integrated many aspects of the geological knowledge into the interpolation schemes and model definition. The fundamental reasoning behind our approach is that the subjective constraints that are required to capture the geological features with standard implicit algorithms will be one of the greatest sources of uncertainty in the model. By incorporating the geological concepts into the geological modelling algorithms, these conceptual uncertainties can be integrated into a probabilistic definition of the geological model. Currently, LoopStructural does not have a probabilistic interface; however, all parameters relating to geological structures (topological ordering, fold geometries, fault displacement and geometries) are accessible from the GeologicalModel class functions.

In Fig. 14, map2loop (Jessell et al.,
2021) generates an augmented dataset from the open-access geological
survey databases (stratigraphic database, DTM, geology shapefiles,
structural lines and structural observations). In this example, the total
time from data processing to model rendering was approximately 10 min.
Using discrete implicit modelling means that the complexity of the model is
defined by the resolution of the support, rather than the number of
observations. Discrete interpolation involves solving the linear equation

The fault displacement profiles (Fig. 5) define the fault displacement within the fault volume; however, these conceptual profiles are not fitted to the observations. Godefroy et al. (2018b) interpolate a continuous surface without observations within the fault domain and then use particle swarm optimisation to fit the displacement profiles to the unused observations. LoopStructural cannot apply this same approach because all data points are restored (with respect to the fault displacement) prior to interpolating the faulted surfaces. The displacement estimates calculated by map2loop could be used to estimate the displacement profile along the fault trace. The fault displacements could then be optimised using a probabilistic representation of the model geometry parameters. Within the same framework it would be necessary to include the parameterisation of the fault slip vector and fault dip if these are defined by a conceptual model rather than observations. However, defining a specific likelihood function for constraining the fault displacement is challenging and may be specific to the geology in question – e.g. where observations are abundant it would be possible to adopt the technique from Godefroy et al. (2018b) and separate some data from the interpolation; however, when dealing with typical regional scale map sheets most of the observations occur on the surface with limited constraints on the 3D geometry.

In this contribution we have introduced LoopStructural, a new open-source Python library for
implicit 3D geological modelling. The key features of LoopStructural are as follows:

implicit 3D geological modelling algorithms using discrete interpolation,

implementation of structural geology of folds and faults using structural frames,

a direct link to map2loop for automated 3D geological modelling,

an object-oriented software design allowing for easy development and extension of the 3D modelling algorithms.

A cube is defined by eight vertices and can be referenced inside a Cartesian
grid by the indices

Odd and even masks for extracting tetrahedrons from a Cartesian grid.

Schematic diagram showing transformation from tetrahedron in Cartesian space to reference tetrahedron in natural coordinates. This transformation allows for the shape functions and derivatives to be simplified.

The property is interpolated linearly within the element,

Solving this set of linear equations for

Since

The implicit function can be described relative to the eight vertices of the
cell using the shape functions (

LoopStructural is a free open-source Python library licensed under the Massachusetts Institute of Technology (MIT) license. It is currently
hosted on

Documentation is available within the package and is hosted on

Jupyter notebooks used for the examples in this paper are available on

LG, GL and LA contributed to the conceptual design of the project. GL wrote an initial version of the fold interpolation code. LG wrote and maintained the code. MJ was involved with the integration with map2loop and ongoing testing of the code. LG prepared the paper with contributions from all authors for reviewing and editing.

The authors declare that they have no conflict of interest.

This research has performed as part of the Loop project, a OneGeology initiative funded by the Australian Research Council and supported by Monash University; the University of Western Australia; Geoscience Australia; the Geological Surveys of Western Australia, Northern Territory, South Australia and New South Wales; the Research for Integrative Numerical Geology; Universite de Lorraine; RWTH Aachen; Geological Survey of Canada; British Geological Survey; and Bureau de Recherches Géòlogiques et Minières and Auscope. The work has also been supported by the Mineral Exploration Cooperative Research Centre, whose activities are funded by the Australian Government's Cooperative Research Centre Programme. This is MinEx CRC Document 2021/41. The source data used in the final example were provided by Geological Survey of South Australia, Geological Survey of Western Australia and Geoscience Australia.

This research has been supported by the Australian Research Council (grant no. LP170100985).

This paper was edited by Andrew Wickert and reviewed by Italo Goncalves and one anonymous referee.