Source code for gempy.API.examples_generator

import os

import numpy as np

import gempy as gp
from gempy_engine.core.data.stack_relation_type import StackRelationType
from gempy.core.data.enumerators import ExampleModel




[docs] def generate_example_model(example_model: ExampleModel, compute_model: bool = True) -> gp.data.GeoModel: match example_model: case ExampleModel.HORIZONTAL_STRAT: return _generate_horizontal_stratigraphic_model(compute_model) case ExampleModel.ANTICLINE: return _generate_anticline_model(compute_model) case ExampleModel.ONE_FAULT: return _generate_one_fault_model(compute_model) case ExampleModel.TWO_AND_A_HALF_D: return _generate_2_5d_model(compute_model) case ExampleModel.COMBINATION: return _generate_combination_model(compute_model) case ExampleModel.ONE_FAULT_GRAVITY: return _generate_one_fault_model_gravity(compute_model) case ExampleModel.GRABEN: return _generate_graben_model(compute_model) case _: raise NotImplementedError(f"Example model {example_model} not implemented.")
def _generate_2_5d_model(compute_model: bool) -> gp.data.GeoModel: geo_model: gp.data.GeoModel = gp.create_geomodel( project_name='Model1', extent=[0, 791, -200, 200, -582, 0], resolution=[50, 50, 50], refinement=1, structural_frame=gp.data.StructuralFrame.initialize_default_structure() ) gp.add_surface_points( geo_model=geo_model, x=[223, 458, 612], y=[0.01, 0, 0], z=[-94, -197, -14], elements_names='surface1' ) gp.add_orientations( geo_model=geo_model, x=[350], y=[1], z=[-300], elements_names=['surface1'], pole_vector=[[0, 0, 1]] ) geo_model.update_transform(gp.data.GlobalAnisotropy.NONE) # * Remove the auto anisotropy for this 2.5D model element2 = gp.data.StructuralElement( name='surface2', color=next(geo_model.structural_frame.color_generator), surface_points=gp.data.SurfacePointsTable.from_arrays( x=np.array([225, 459]), y=np.array([0, 0]), z=np.array([-269, -279]), names='surface2' ), orientations=gp.data.OrientationsTable.initialize_empty() ) geo_model.structural_frame.structural_groups[0].append_element(element2) element3 = gp.data.StructuralElement( name='surface3', color=next(geo_model.structural_frame.color_generator), surface_points=gp.data.SurfacePointsTable.from_arrays( x=np.array([225, 464, 619]), y=np.array([0, 0, 0]), z=np.array([-439, -456, -433]), names='surface3' ), orientations=gp.data.OrientationsTable.initialize_empty() ) geo_model.structural_frame.structural_groups[0].append_element(element3) element_fault = gp.data.StructuralElement( name='fault1', color=next(geo_model.structural_frame.color_generator), surface_points=gp.data.SurfacePointsTable.from_arrays( x=np.array([550, 650]), y=np.array([0, 0]), z=np.array([-30, -200]), names='fault1' ), orientations=gp.data.OrientationsTable.from_arrays( x=np.array([600]), y=np.array([0]), z=np.array([-100]), G_x=np.array([.3]), G_y=np.array([0]), G_z=np.array([.3]), names='fault1' ) ) group_fault = gp.data.StructuralGroup( name='Fault1', elements=[element_fault], structural_relation=gp.data.StackRelationType.FAULT, fault_relations=gp.data.FaultsRelationSpecialCase.OFFSET_ALL ) geo_model.structural_frame.insert_group(0, group_fault) # * We are placing it already in the right place so we do not need to map anything gp.set_topography_from_random( grid=geo_model.grid, fractal_dimension=1.9, d_z=np.array([-150, 0]), topography_resolution=np.array([50, 40]) ) if compute_model: gp.compute_model(geo_model) return geo_model def _generate_horizontal_stratigraphic_model(compute_model: bool) -> gp.data.GeoModel: """ Function to create a geological model of horizontally stacked layers, map the geological series to surfaces, and compute the geological model. """ # Define the path to data data_path = 'https://raw.githubusercontent.com/cgre-aachen/gempy_data/master/' # Create a GeoModel instance geo_data = gp.create_geomodel( project_name='horizontal', extent=[0, 1000, 0, 1000, 0, 1000], resolution=[50, 5, 50], refinement=3, importer_helper=gp.data.ImporterHelper( path_to_orientations=data_path + "/data/input_data/jan_models/model1_orientations.csv", path_to_surface_points=data_path + "/data/input_data/jan_models/model1_surface_points.csv" ) ) # Map geological series to surfaces gp.map_stack_to_surfaces( gempy_model=geo_data, mapping_object={"Strat_Series": ('rock2', 'rock1')} ) if compute_model: # Compute the geological model gp.compute_model(geo_data) return geo_data def _generate_anticline_model(compute_model: bool) -> gp.data.GeoModel: """ Function to create a geological model of an anticline structure, map the geological series to surfaces, and compute the geological model. """ # Define the path to data data_path = 'https://raw.githubusercontent.com/cgre-aachen/gempy_data/master/' path_to_data = data_path + "/data/input_data/jan_models/" # Create a GeoModel instance geo_data: gp.data.GeoModel = gp.create_geomodel( project_name='fold', extent=[0, 1000, 0, 1000, 0, 1000], refinement=5, importer_helper=gp.data.ImporterHelper( path_to_orientations=path_to_data + "model2_orientations.csv", path_to_surface_points=path_to_data + "model2_surface_points.csv" ) ) # Map geological series to surfaces gp.map_stack_to_surfaces( gempy_model=geo_data, mapping_object={"Strat_Series": ('rock2', 'rock1')} ) if compute_model: # Compute the geological model gp.compute_model(geo_data) return geo_data def _generate_one_fault_model(compute_model: bool) -> gp.data.GeoModel: """ Function to create a simple fault model, map the geological series to surfaces, and compute the geological model. """ # Define the path to data data_path = 'https://raw.githubusercontent.com/cgre-aachen/gempy_data/master/' path_to_data = data_path + "/data/input_data/jan_models/" # Create a GeoModel instance geo_data = gp.create_geomodel( project_name='fault', extent=[0, 1000, 0, 1000, 0, 1000], refinement=6, # resolution=[20, 20, 20], importer_helper=gp.data.ImporterHelper( path_to_orientations=path_to_data + "model5_orientations.csv", path_to_surface_points=path_to_data + "model5_surface_points.csv" ) ) # Map geological series to surfaces gp.map_stack_to_surfaces( gempy_model=geo_data, mapping_object={ "Fault_Series": 'fault', "Strat_Series": ('rock2', 'rock1') } ) # Define fault groups geo_data.structural_frame.structural_groups[0].structural_relation = StackRelationType.FAULT geo_data.structural_frame.fault_relations = np.array([[0, 1], [0, 0]]) gp.set_is_fault( frame=geo_data, fault_groups=['Fault_Series'] ) if compute_model: # Compute the geological model gp.compute_model(geo_data) return geo_data def _generate_combination_model(compute_model: bool) -> gp.data.GeoModel: """ Function to create a model with a folded domain featuring an unconformity and a fault, map the geological series to surfaces, and compute the geological model. """ # Define the path to data data_path = 'https://raw.githubusercontent.com/cgre-aachen/gempy_data/master/' path_to_data = data_path + "/data/input_data/jan_models/" # Create a GeoModel instance geo_data = gp.create_geomodel( project_name='combination', extent=[0, 2500, 0, 1000, 0, 1000], refinement=4, importer_helper=gp.data.ImporterHelper( path_to_orientations=path_to_data + "model7_orientations.csv", path_to_surface_points=path_to_data + "model7_surface_points.csv" ) ) geo_data.interpolation_options.evaluation_options.number_octree_levels_surface = 4 # Map geological series to surfaces gp.map_stack_to_surfaces( gempy_model=geo_data, mapping_object={ "Fault_Series" : ('fault'), "Strat_Series1": ('rock3'), "Strat_Series2": ('rock2', 'rock1'), } ) # Define the structural relation geo_data.structural_frame.structural_groups[0].structural_relation = StackRelationType.FAULT geo_data.structural_frame.fault_relations = np.array( [[0, 1, 1], [0, 0, 0], [0, 0, 0]] ) # Compute the geological model if compute_model: gp.compute_model( gempy_model=geo_data, engine_config=gp.data.GemPyEngineConfig( backend=gp.data.AvailableBackends.numpy ) ) return geo_data def _generate_one_fault_model_gravity(compute_model): from gempy_engine.core.backend_tensor import BackendTensor from gempy.optional_dependencies import require_pandas pd = require_pandas() resolution = [150, 10, 150] extent = [0, 200, -100, 100, -100, 0] # %% # Configure GemPy for geological modeling with PyTorch backend BackendTensor.change_backend_gempy(engine_backend=gp.data.AvailableBackends.PYTORCH, dtype="float64") geo_model: gp.data.GeoModel = gp.create_geomodel( project_name='Fault model', extent=extent, resolution=resolution, structural_frame=gp.data.StructuralFrame.initialize_default_structure() ) interpolation_options = geo_model.interpolation_options interpolation_options.mesh_extraction = False interpolation_options.kernel_options.range = .7 interpolation_options.kernel_options.c_o = 3 interpolation_options.kernel_options.compute_condition_number = True gp.add_surface_points( geo_model=geo_model, x=[40, 60, 120, 140], y=[0, 0, 0, 0], z=[-50, -50, -60, -60], elements_names=['surface1', 'surface1', 'surface1', 'surface1'] ) gp.add_orientations( geo_model=geo_model, x=[130], y=[0], z=[-50], elements_names=['surface1'], pole_vector=[[0, 0, 1.]] ) # Define second element element2 = gp.data.StructuralElement( name='surface2', color=next(geo_model.structural_frame.color_generator), surface_points=gp.data.SurfacePointsTable.from_arrays( x=np.array([120]), y=np.array([0]), z=np.array([-40]), names='surface2' ), orientations=gp.data.OrientationsTable.initialize_empty() ) # Add second element to structural frame geo_model.structural_frame.structural_groups[0].append_element(element2) # add fault # Calculate orientation from point values fault_point_1 = (80, -20) fault_point_2 = (110, -80) # calculate angle angle = np.arctan((fault_point_2[0] - fault_point_1[0]) / (fault_point_2[1] - fault_point_1[1])) x = np.cos(angle) z = - np.sin(angle) element_fault = gp.data.StructuralElement( name='fault1', color=next(geo_model.structural_frame.color_generator), surface_points=gp.data.SurfacePointsTable.from_arrays( x=np.array([fault_point_1[0], fault_point_2[0]]), y=np.array([0, 0]), z=np.array([fault_point_1[1], fault_point_2[1]]), names='fault1' ), orientations=gp.data.OrientationsTable.from_arrays( x=np.array([fault_point_1[0]]), y=np.array([0]), z=np.array([fault_point_1[1]]), G_x=np.array([x]), G_y=np.array([0]), G_z=np.array([z]), names='fault1' ) ) group_fault = gp.data.StructuralGroup( name='Fault1', elements=[element_fault], structural_relation=gp.data.StackRelationType.FAULT, fault_relations=gp.data.FaultsRelationSpecialCase.OFFSET_ALL ) # Insert the fault group into the structural frame: geo_model.structural_frame.insert_group(0, group_fault) # %% md ## Compute model # %% geo_model.update_transform(gp.data.GlobalAnisotropy.NONE) interesting_columns = pd.DataFrame() # x_vals = np.arange(20, 191, 10) x_vals = np.linspace(20, 191, 6) interesting_columns['X'] = x_vals interesting_columns['Y'] = np.zeros_like(x_vals) # Configuring the data correctly is key for accurate gravity calculations. device_location = interesting_columns[['X', 'Y']] device_location['Z'] = 0 # Add a Z-coordinate # Set up a centered grid for geophysical calculations # This grid will be used for gravity gradient calculations. gp.set_centered_grid( grid=geo_model.grid, centers=device_location, resolution=np.array([75/3, 5, 150/3]), radius=np.array([150, 10, 300]) ) # Calculate the gravity gradient using GemPy # Gravity gradient data is critical for geophysical modeling and inversion. gravity_gradient = gp.calculate_gravity_gradient(geo_model.grid.centered_grid) densities_tensor = BackendTensor.t.array([2., 2., 3., 2.]) densities_tensor.requires_grad = True # Set geophysics input for the GemPy model # Configuring this input is crucial for the forward gravity calculation. geo_model.geophysics_input = gp.data.GeophysicsInput( tz=BackendTensor.t.array(gravity_gradient), densities=densities_tensor ) # %% # Compute the geological model with geophysical data # This computation integrates the geological model with gravity data. if compute_model: sol = gp.compute_model( gempy_model=geo_model, engine_config=gp.data.GemPyEngineConfig( backend=gp.data.AvailableBackends.PYTORCH, dtype='float32', use_gpu=True ) ) grav = - sol.gravity grav[0].backward() return geo_model def _generate_graben_model(compute_model: bool) -> gp.data.GeoModel: # Data path is in root/examples/data # script_dir = os.path.dirname(os.path.abspath(__file__)) # data_path = os.path.join(script_dir, '.../examples/') # n_model = 7 # https: // github.com / gempy - project / gempy / blob / 279 # bbe904283e16320c54d868fe74be873177cca / examples / data / input_data / lisa_models / interfaces7.csv # csv_ = data_path + "/data/input_data/lisa_models/foliations" + n_model + ".csv" data_path = 'https://raw.githubusercontent.com/cgre-aachen/gempy_data/master/' path_to_data = data_path + "/data/input_data/lisa_models/" geo_data: gp.data.GeoModel = gp.create_geomodel( project_name="Graben", extent=[0, 2000, 0, 2000, 0, 1600], resolution=[50, 50, 50], refinement=6, # * For this model is better not to use octrees because we want to see what is happening in the scalar fields importer_helper=gp.data.ImporterHelper( path_to_orientations= path_to_data + "foliations7.csv", path_to_surface_points= path_to_data + "interfaces7.csv" ) ) gp.map_stack_to_surfaces( gempy_model=geo_data, mapping_object={ "Fault_1" : 'Fault_1', "Fault_2": 'Fault_2', "Strat_Series": ('Sandstone', 'Siltstone', 'Shale', 'Sandstone_2', 'Schist', 'Gneiss') }, ) gp.set_is_fault(geo_data, ['Fault_1', 'Fault_2']) if compute_model: sol = gp.compute_model(gempy_model=geo_data) return geo_data