Skip to content

Commit 49b4f25

Browse files
committed
fix: correct IDs and positions for fault and rock1 in multiple series faults tutorial
1 parent 9b78ac2 commit 49b4f25

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
"""
2+
Tutorial: Loading a Model with Multiple Series and Faults using JSON I/O
3+
=====================================================================
4+
5+
This tutorial demonstrates how to load a geological model with multiple series and faults using GemPy's JSON I/O functionality.
6+
The model consists of two layers (rock1, rock2) and a fault that offsets them.
7+
"""
8+
9+
# %%
10+
# Import necessary libraries
11+
import matplotlib
12+
matplotlib.use('Agg') # Use non-interactive backend
13+
import gempy as gp
14+
import gempy_viewer as gpv
15+
import numpy as np
16+
import json
17+
from pathlib import Path
18+
import matplotlib.pyplot as plt
19+
from gempy_engine.core.data.stack_relation_type import StackRelationType
20+
from gempy.modules.json_io.json_operations import JsonIO # Updated import path
21+
22+
# %%
23+
# Define the model data
24+
model_data = {
25+
"metadata": {
26+
"name": "multiple_series_faults",
27+
"creation_date": "2024-03-19",
28+
"last_modification_date": "2024-03-19",
29+
"owner": "tutorial"
30+
},
31+
"surface_points": [
32+
# fault surface points (previously rock1 points)
33+
{"x": 0.0, "y": 200.0, "z": 600.0, "id": 2, "nugget": 0.00002},
34+
{"x": 0.0, "y": 500.0, "z": 600.0, "id": 2, "nugget": 0.00002},
35+
{"x": 0.0, "y": 800.0, "z": 600.0, "id": 2, "nugget": 0.00002},
36+
{"x": 200.0, "y": 200.0, "z": 600.0, "id": 2, "nugget": 0.00002},
37+
{"x": 200.0, "y": 500.0, "z": 600.0, "id": 2, "nugget": 0.00002},
38+
{"x": 200.0, "y": 800.0, "z": 600.0, "id": 2, "nugget": 0.00002},
39+
{"x": 800.0, "y": 200.0, "z": 200.0, "id": 2, "nugget": 0.00002},
40+
{"x": 800.0, "y": 500.0, "z": 200.0, "id": 2, "nugget": 0.00002},
41+
{"x": 800.0, "y": 800.0, "z": 200.0, "id": 2, "nugget": 0.00002},
42+
{"x": 1000.0, "y": 200.0, "z": 200.0, "id": 2, "nugget": 0.00002},
43+
{"x": 1000.0, "y": 500.0, "z": 200.0, "id": 2, "nugget": 0.00002},
44+
{"x": 1000.0, "y": 800.0, "z": 200.0, "id": 2, "nugget": 0.00002},
45+
# rock2 surface points
46+
{"x": 0.0, "y": 200.0, "z": 800.0, "id": 1, "nugget": 0.00002},
47+
{"x": 0.0, "y": 800.0, "z": 800.0, "id": 1, "nugget": 0.00002},
48+
{"x": 200.0, "y": 200.0, "z": 800.0, "id": 1, "nugget": 0.00002},
49+
{"x": 200.0, "y": 800.0, "z": 800.0, "id": 1, "nugget": 0.00002},
50+
{"x": 800.0, "y": 200.0, "z": 400.0, "id": 1, "nugget": 0.00002},
51+
{"x": 800.0, "y": 800.0, "z": 400.0, "id": 1, "nugget": 0.00002},
52+
{"x": 1000.0, "y": 200.0, "z": 400.0, "id": 1, "nugget": 0.00002},
53+
{"x": 1000.0, "y": 800.0, "z": 400.0, "id": 1, "nugget": 0.00002},
54+
# rock1 surface points (previously fault points)
55+
{"x": 500.0, "y": 500.0, "z": 500.0, "id": 0, "nugget": 0.00002},
56+
{"x": 450.0, "y": 500.0, "z": 600.0, "id": 0, "nugget": 0.00002},
57+
{"x": 500.0, "y": 200.0, "z": 500.0, "id": 0, "nugget": 0.00002},
58+
{"x": 450.0, "y": 200.0, "z": 600.0, "id": 0, "nugget": 0.00002},
59+
{"x": 500.0, "y": 800.0, "z": 500.0, "id": 0, "nugget": 0.00002},
60+
{"x": 450.0, "y": 800.0, "z": 600.0, "id": 0, "nugget": 0.00002},
61+
],
62+
"orientations": [
63+
# rock2 orientation (upper layer at x=100)
64+
{"x": 100.0, "y": 500.0, "z": 800.0, "G_x": 0.0, "G_y": 0.0, "G_z": 1.0, "id": 1, "nugget": 0.01, "polarity": 1},
65+
# rock1 orientation (lower layer at x=100)
66+
{"x": 100.0, "y": 500.0, "z": 600.0, "G_x": 0.0, "G_y": 0.0, "G_z": 1.0, "id": 2, "nugget": 0.01, "polarity": 1},
67+
# fault orientation (at x=500)
68+
{"x": 500.0, "y": 500.0, "z": 500.0, "G_x": 0.8, "G_y": 0.0, "G_z": 0.6, "id": 0, "nugget": 0.01, "polarity": 1},
69+
# rock2 orientation (upper layer at x=900)
70+
{"x": 900.0, "y": 500.0, "z": 400.0, "G_x": 0.0, "G_y": 0.0, "G_z": 1.0, "id": 1, "nugget": 0.01, "polarity": 1},
71+
# rock1 orientation (lower layer at x=900)
72+
{"x": 900.0, "y": 500.0, "z": 200.0, "G_x": 0.0, "G_y": 0.0, "G_z": 1.0, "id": 2, "nugget": 0.01, "polarity": 1},
73+
],
74+
"series": [
75+
{
76+
"name": "Fault_Series",
77+
"surfaces": ["fault"],
78+
"structural_relation": "FAULT",
79+
"color": "#015482" # Blue color for fault
80+
},
81+
{
82+
"name": "Strat_Series",
83+
"surfaces": ["rock2", "rock1"],
84+
"structural_relation": "ERODE",
85+
"colors": ["#ffbe00", "#9f0052"] # Yellow for rock2, Pink for rock1
86+
}
87+
],
88+
"grid_settings": {
89+
"regular_grid_resolution": [90, 30, 30], # Increased resolution for better visualization
90+
"regular_grid_extent": [0, 1000, 0, 1000, 0, 1000],
91+
"octree_levels": None
92+
},
93+
"interpolation_options": {}
94+
}
95+
96+
# %%
97+
# Save the model data to a JSON file
98+
tutorial_dir = Path(__file__).parent
99+
json_file = tutorial_dir / "multiple_series_faults.json"
100+
with open(json_file, "w") as f:
101+
json.dump(model_data, f, indent=4)
102+
103+
# %%
104+
# Load the model from JSON
105+
model = JsonIO.load_model_from_json(str(json_file))
106+
107+
# Print structural groups
108+
print("\nStructural Groups:")
109+
print(model.structural_frame.structural_groups)
110+
111+
# %%
112+
# Set fault relations
113+
# Create a 2x2 matrix for fault relations (2 series: Fault_Series, Strat_Series)
114+
# 1 means the fault affects the series, 0 means it doesn't
115+
model.structural_frame.fault_relations = np.array([
116+
[0, 1], # Fault_Series affects Strat_Series
117+
[0, 0] # Strat_Series doesn't affect any series
118+
])
119+
120+
# Explicitly set the structural relation for the fault series
121+
model.structural_frame.structural_groups[0].structural_relation = StackRelationType.FAULT
122+
123+
# Set the fault series as a fault
124+
gp.set_is_fault(
125+
frame=model,
126+
fault_groups=['Fault_Series']
127+
)
128+
129+
# %%
130+
# Compute the geological model
131+
gp.compute_model(model)
132+
133+
# %%
134+
# Plot the model
135+
# Plot the initial geological model in the y direction without results
136+
fig, ax = plt.subplots(figsize=(10, 6))
137+
gpv.plot_2d(model, direction=['y'], show_results=False, ax=ax)
138+
plt.title("Initial Geological Model (y direction)")
139+
plt.savefig('initial_model_y.png')
140+
plt.close()
141+
142+
# Plot the result of the model in the x and y direction with data and without boundaries
143+
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
144+
gpv.plot_2d(model, direction=['x'], show_data=True, show_boundaries=False, ax=ax1)
145+
ax1.set_title("Model with Data (x direction)")
146+
gpv.plot_2d(model, direction=['y'], show_data=True, show_boundaries=False, ax=ax2)
147+
ax2.set_title("Model with Data (y direction)")
148+
plt.tight_layout()
149+
plt.savefig('model_with_data.png')
150+
plt.close()
151+
152+
# Plot the scalar field of the fault
153+
fig, ax = plt.subplots(figsize=(10, 6))
154+
gpv.plot_2d(model, show_scalar=True, show_lith=False, series_n=0, ax=ax)
155+
plt.title("Fault Scalar Field")
156+
plt.savefig('fault_scalar_field.png')
157+
plt.close()

0 commit comments

Comments
 (0)