Skip to content

Commit 76d3fd1

Browse files
committed
[DOC] Second pass to Getting started
1 parent 5d73f8b commit 76d3fd1

File tree

1 file changed

+31
-25
lines changed

1 file changed

+31
-25
lines changed

examples/tutorials/a_getting_started/get_started.py

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# geomodeling and demonstrating how you can leverage these to create your own geological models. We will guide you through building a
99
# model from scratch, based on a conceptual 2D cross-section with boreholes. This simple example will highlight key workflow steps
1010
# and structural features that GemPy can model.
11+
1112
# Installation
1213
# """"""""""""
1314
#
@@ -78,18 +79,19 @@
7879
# relevant data in a representative space. For this example, we align the extent with the cross-section we imported:
7980
# - **X** is parallel to the section.
8081
# - **Y** is perpendicular. Since we have no data along y, a narrow extent makes sense. We choose an extent of 400, defining it as
81-
# -200 to 200, placing the cross-section at y=0 (in the middle).
82+
# -200 to 200, placing the cross-section at y=0 (in the middle).
8283
# - **Z**, representing depth, takes a negative value since we are modeling the subsurface.
8384
# 3. **Initialize Structural Framework**: Set up a default structural framework.
8485
# 4. **Define either resolution or refinement**: In GemPy 3, you can use either regular grids or octrees.
8586
# - **Regular grids**: Define a resolution (and refinement=None). A medium resolution of 50x50x50, for example, results in 125,000 voxels.
8687
# Model voxels are prisms, not cubes, so resolution can differ from extent. Avoid exceeding 100 cells in each direction (1,000,000 voxels)
8788
# to prevent high computational costs.
8889
# - **Octrees**: Define a level of refinement (and resolution=None). Higher refinement levels increase computational costs.
89-
#
90-
# > **Note on choice of modeling grids:** Which type of grid is used depends on the use case. Note that as of the current version of GemPy 3,
91-
# the rendering of surfaces uses dual-contouring, which is based on octrees. So even if you choose regular grids, octree-based computing will
92-
# be executed additionally in order to render the surfaces in 3D.
90+
91+
# .. admonition:: Note on choice of modeling grids
92+
# Which type of grid is used depends on the use case. Note that as of the current version of GemPy 3,
93+
# the rendering of surfaces uses dual-contouring, which is based on octrees. So even if you choose regular grids, octree-based computing will
94+
# be executed additionally in order to render the surfaces in 3D.
9395

9496
# %%
9597
geo_model = gp.create_geomodel(
@@ -106,8 +108,10 @@
106108
# such as the parameters defined above,
107109
# and the input data we will introduce further below. You can access different types of information by accessing the attributes. For instance, you
108110
# can retrieve the coordinates of our modeling grid as follows:
111+
109112
# %%
110113
geo_model.grid
114+
111115
# %% md
112116
# The `geo_model` object also contains the structural frame of our model, i.e., information about our main structural groups (also referred to as
113117
# series or stacks in our model), and their sequential and geological relationships with one another. Each group can contain several elements,
@@ -230,8 +234,9 @@
230234
# """"""""""""""""""""""""""""""""""
231235
# Ok, good! Now we have added the position of the bottom of this top layer for each borehole. But is this enough to compute our first layer?
232236
# Well, no. GemPy's approach is based on an implicit interpolation method that requires the following minimum data:
233-
# - **Two surface points** for at least one surface in a structural group/series
234-
# - **One orientation** per structural group/series
237+
#
238+
# - **Two surface points** for at least one surface in a structural group/series
239+
# - **One orientation** per structural group/series
235240
#
236241
# Thanks to GemPy's global interpolation approach, once you have one surface defined by two surface points and an orientation in a structural
237242
# group, you can add more surfaces (in the same group) with the minimum of one surface point, as it will now take its orientation information
@@ -336,8 +341,8 @@
336341
plt.show()
337342

338343
# %% md
339-
# ## Adding a Second Lithological Unit
340-
#
344+
# Adding a Second Lithological Unit
345+
# """""""""""""""""""""""""""""""""
341346
# To add another unit to our model, we can define it as another structural element and then append it to our `geo_model` object. We do this
342347
# for the second unit in the following steps. See how we can already give it a name (let's assume this is a siltstone now), a color corresponding
343348
# to the dot colors in the cross-section, as well as define surface points and orientations. By appending it to `structural_groups[0]`, we are
@@ -527,6 +532,7 @@
527532
# defines how a younger (upper) structural group will relate to the older (lower) structural groups and possibly affect their scalar field.
528533
#
529534
# The parameter `StackRelationType` can take the following values:
535+
#
530536
# - `BASEMENT`: Treats all lower groups as the basement.
531537
# - `ERODE`: Defines erosive contact/unconformity.
532538
# - `ONLAP`: Defines the younger group to be onlapping onto the older groups.
@@ -535,8 +541,8 @@
535541
# We will now take a look at each of these relation types except for the basement type.
536542

537543
# %% md
538-
# ### Erosive Contact
539-
#
544+
# Erosive Contact
545+
# """""""""""""""
540546
# For this, we don't have to change anything now, as we already set the `StackRelationType` to be `ERODE`. If we now plot it, we will see
541547
# how this younger structural group erodes all older elements and basically "cuts them out" in our model.
542548

@@ -562,8 +568,8 @@
562568
# We can see how all units of the depositional series stop at the contact with the new discontinuity group. However, this doesn't look
563569
# quite right, and it in particular doesn't fit the surface point that was observed in the third borehole. So let's try another relation type.
564570
#
565-
# ## Onlapping
566-
#
571+
# Onlapping
572+
# """""""""
567573
# Let's change the relation type from `ERODE` to `ONLAP` to achieve a different type of discontinuity and then plot it.
568574

569575
# %%
@@ -594,8 +600,8 @@
594600
# Now the unit defined as part of the discontinuity group is onlapping onto the uppermost surface of the default group and ends there.
595601
# This also doesn't really make sense considering the data given, so let's try the last relation type.
596602
#
597-
# ## Faults
598-
#
603+
# Faults
604+
# """"""
599605
# Let's change the relation type to `FAULT` and plot the results. For a fault, we also need to make use of the function `set_is_fault`.
600606

601607
# %%
@@ -652,8 +658,8 @@
652658
plt.show()
653659

654660
# %% md
655-
# ## Topography and Geological Maps
656-
#
661+
# Topography and Geological Maps
662+
# """"""""""""""""""""""""""""""
657663
# In GemPy, we can add more grid types for different purposes, such as to add topography to our model. In this following section,
658664
# we will exemplify this by creating a random topography grid which allows us to intersect the surfaces as well as compute a high-resolution
659665
# geological map. GemPy has a built-in function to generate random topography. After executing it, a topography grid will be added to the
@@ -697,17 +703,17 @@
697703
# `set_topography_from_file` and `set_topography_from_arrays`.
698704

699705
# %% md
700-
# ## Extracting Model Solutions
701-
#
706+
# Extracting Model Solutions
707+
# """"""""""""""""""""""""""
702708
# Once you have built a model, you might not only want to visualize it, but also further analyze it or export it for further utilization.
703709
# For this, it is good to know that the solutions from modeling are stored in `geo_model.solutions` and can be returned from there. This
704710
# includes the following outputs in particular:
705711
# - `geo_model.solutions.dc_meshes`: A list of the surface meshes in the model with the location of vertices and edges for each.
706712
# - `geo_model.solutions.raw_arrays`: An object containing numerous arrays that define various parts of the model. Of particular importance
707713
# are the lithology block (`lith_block`), the fault block (`fault_block`), and the scalar field matrix (`scalar_field_matrix`).
708714
#
709-
# ### Mesh Solutions
710-
#
715+
# Mesh Solutions
716+
# """"""""""""""
711717
# Let's take a quick look at how we can return some key information from `geo_model.solutions`. Starting with meshes, we can see that the list
712718
# `dc_meshes` can be indexed to return specific meshes and their respective vertices or edges. Please note that the order will be the same as
713719
# in our `structural_frame`, i.e., the index `[0]` will return the first and top surface, in our case, the discontinuity surface.
@@ -726,8 +732,8 @@
726732
geo_model.input_transform.apply_inverse(vertices_0)
727733

728734
# %% md
729-
# ### Lithology Block
730-
#
735+
# Lithology Block
736+
# """""""""""""""
731737
# The lithology block is an array that, for a given model realization/solution, returns the ID of the lithology for each voxel. Note below
732738
# that the `lith_block` first returns all values in the shape of one row. You might need to reshape it as shown below. For a regular grid,
733739
# you can reshape it using the resolution used in `geo_model`.
@@ -742,8 +748,8 @@
742748
print(lith_block.shape, lith_block)
743749

744750
# %% md
745-
# ### Grid Values
746-
#
751+
# Grid Values
752+
# """""""""""
747753
# Apart from these solutions, you might also need to return grid values. You can access the values for each grid in your `geo_model`
748754
# object via `geo_model.grid` as shown below.
749755
# %%

0 commit comments

Comments
 (0)