def test_pile_geomodel_2():
    ve = 3
    extent = [451e3, 456e3, 6.7820e6, 6.7840e6, -2309 * ve, -1651 * ve]

    geo_model = gp.create_model('Topology-Gullfaks')

    gp.init_data(geo_model,
                 extent, [30, 30, 30],
                 path_o=input_path + "/filtered_orientations.csv",
                 path_i=input_path + "/filtered_surface_points.csv",
                 default_values=True)

    series_distribution = {
        "fault3": "fault3",
        "fault4": "fault4",
        "unconformity": "BCU",
        "sediments": ("tarbert", "ness", "etive"),
    }

    gp.map_series_to_surfaces(geo_model,
                              series_distribution,
                              remove_unused_series=True)

    geo_model.reorder_series(
        ["unconformity", "fault3", "fault4", "sediments", "Basement"])

    geo_model.set_is_fault(["fault3"])
    geo_model.set_is_fault(["fault4"])

    rel_matrix = np.array([[0, 0, 0, 0, 0], [0, 0, 0, 1, 1], [0, 0, 0, 1, 1],
                           [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]])

    geo_model.set_fault_relation(rel_matrix)

    surf_groups = pd.read_csv(input_path +
                              "/filtered_surface_points.csv").group
    geo_model.surface_points.df["group"] = surf_groups
    orient_groups = pd.read_csv(input_path +
                                "/filtered_orientations.csv").group
    geo_model.orientations.df["group"] = orient_groups

    geo_model.surface_points.df.reset_index(inplace=True, drop=True)
    geo_model.orientations.df.reset_index(inplace=True, drop=True)

    gp.set_interpolator(geo_model,
                        verbose=['mask_matrix_loop', 'mask_e', 'nsle'])
    gp.compute_model(geo_model)

    gp.plot.plot_section(geo_model,
                         cell_number=25,
                         direction='y',
                         show_data=True)

    from gempy.plot.plot_api import plot_2d

    p = plot_2d(geo_model, cell_number=[25])

    plt.savefig(os.path.dirname(__file__) + '/../figs/test_pile_lith_block')

    return geo_model
Example #2
0
def interpolator_islith_isfault():

    geo_model = gp.create_model('interpolator_islith_isfault')

    # Importing the data from CSV-files and setting extent and resolution
    gp.init_data(geo_model,
                 path_o=input_path + "/simple_fault_model_orientations.csv",
                 path_i=input_path + "/simple_fault_model_points.csv",
                 default_values=True)

    gp.map_series_to_surfaces(geo_model, {
        "Fault_Series":
        'Main_Fault',
        "Strat_Series":
        ('Sandstone_2', 'Siltstone', 'Shale', 'Sandstone_1', 'basement')
    },
                              remove_unused_series=True)

    geo_model.set_is_fault(['Fault_Series'])

    gp.set_interpolation_data(geo_model,
                              compile_theano=True,
                              theano_optimizer='fast_compile',
                              verbose=[])

    return geo_model.interpolator
Example #3
0
def map_sequential_pile(load_model):
    geo_model = load_model

    # TODO decide what I do with the layer order

    gp.map_series_to_surfaces(geo_model, {"Fault_Series": 'Main_Fault',
                                          "Strat_Series": ('Sandstone_2', 'Siltstone',
                                                           'Shale', 'Sandstone_1', 'basement')},
                                            remove_unused_series=True)

    geo_model.set_is_fault(['Fault_Series'])
    return geo_model
Example #4
0
def test_add_point():
    extend = [0.0, 1.0, 0.0, 1.0, 0.0, 1.1]
    discretization = [5, 20, 20]

    x, y, z, f = 0.0, 0.0, 0.5, 'surface2'

    # %%
    geo_model = gp.create_model('test')
    gp.init_data(geo_model, extend, discretization)

    geo_model.set_default_surfaces()
    geo_model.set_default_orientation()

    strats = ['surface1', 'surface2', 'basement']

    gp.map_series_to_surfaces(geo_model, {'Strat_Series': strats})

    geo_model.add_surface_points(x, y, z, f)
    geo_model.add_orientations(x, y, z, f, pole_vector=(1, 0, 0))
Example #5
0
def geo_model():
    geo_model = gp.create_model('Test_uncomformities')

    # Importing the data from CSV-files and setting extent and resolution
    gp.init_data(
        geo_model, [0, 10., 0, 2., 0, 5.], [100, 3, 100],
        path_o=input_path + '/05_toy_fold_unconformity_orientations.csv',
        path_i=input_path + '/05_toy_fold_unconformity_interfaces.csv',
        default_values=True)

    gp.map_series_to_surfaces(
        geo_model, {
            "Flat_Series": 'Flat',
            "Inclined_Series": 'Inclined',
            "Fold_Series": ('Basefold', 'Topfold', 'basement')
        })

    # Create the theano model
    gp.set_interpolator(geo_model, theano_optimizer='fast_compile')

    return geo_model
Example #6
0
def topology_jan_unconf():
    geo_model = gp.create_data(
        [0, 1000, 0, 1000, 0, 1000],
        resolution=[50, 50, 50],
        path_o=data_path / "jan_models/model6_orientations.csv",
        path_i=data_path / "jan_models/model6_surface_points.csv")

    gp.map_series_to_surfaces(
        geo_model, {
            "Strat_Series1": ('rock3'),
            "Strat_Series2": ('rock2', 'rock1'),
            "Basement_Series": ('basement')
        })

    # with open("input_data/geomodel_jan_sol.p", "rb") as f:
    # geo_model.solutions = load(f)
    gp.set_interpolator(geo_model)
    gp.compute_model(geo_model)

    edges, centroids = tp.compute_topology(geo_model, voxel_threshold=1)
    return edges, centroids
Example #7
0
data_path= '../..'
# Importing the data from CSV-files and setting extent and resolution
gp.init_data(
    geo_model, [0, 2000., 0, 2000., 0, 2000.], [50, 50, 50],
    path_o = data_path+"/data/input_data/tut_chapter1/simple_fault_model_orientations.csv",
    path_i = data_path+"/data/input_data/tut_chapter1/simple_fault_model_points.csv",
    default_values=True
)
geo_model.surfaces


# gp.get_data(geo_model, 'surface_points').head()
# gp.get_data(geo_model, 'orientations').head()
gp.map_series_to_surfaces(
    geo_model,
    {
        "Fault_Series":'Main_Fault',
        "Strat_Series": ('Sandstone_2','Siltstone', 'Shale', 'Sandstone_1', 'basement')
    }, remove_unused_series=True)

# geo_model.series

geo_model.set_is_fault(['Fault_Series'])
geo_model.faults.faults_relations_df
# gp.plot.plot_data(geo_model, direction='y')
# gp.plot.plot_3D(geo_model)

gp.set_interpolation_data(geo_model,
                          compile_theano=True,
                          theano_optimizer='fast_compile',
                          verbose=[])
Example #8
0
def create_example(name_model,
                   interpolator=None,
                   save_pickle=False,
                   plot_section=True):
    """
    Create an inter_data from one of the examples data_set
    
    Attr:
        name_model (str): name of the model that you want to generate. It has to be in ['Model 1' ,'Model 2', 'Model 3', 'Model 4','Model 5' 'Model 6','Model 7',
                          'Model 8', 'Model 9']
        save_pickle (bool, str): Save to a pickle the interp_data object. You can pass the path as a string otherwse
                                the default name will be given
        plot_section (bool)
    
    """
    name_list = np.array([
        'Model 1', 'Model 2', 'Model 3', 'Model 4', 'Model 5', 'Model 6',
        'Model 7', 'Model 8', 'Model 9'
    ])
    assert name_model in name_list, 'Name model must be in the following list: ' + str(
        name_list)
    # Extract number of the model
    n_model = name_model[-1]

    # Load right gempy geodata
    geo_data = gp.create_data(
        name_model,
        extent=[0, 2000, 0, 2000, 0, 1600],
        resolution=[50, 50, 50],
        path_o=data_path + "/data/input_data/lisa_models/foliations" +
        n_model + ".csv",
        path_i=data_path + "/data/input_data/lisa_models/interfaces" +
        n_model + ".csv")

    # Set the right sequential pile
    subset_list_1 = np.array(['Model 1'])
    subset_list_2 = np.array(['Model 5', 'Model 8'])
    subset_list_3 = np.array(['Model 2', 'Model 3', 'Model 9', 'Model 6'])
    subset_list_4 = np.array(['Model 7'])
    ### Model 1 - Discordant layering ###
    if name_model in subset_list_1:
        gp.map_series_to_surfaces(
            geo_data,
            {
                "Strat_Series_1": ('Sandstone', 'Siltstone', 'Shale'),
                "Strat_Series_2": ('Sandstone2', 'Siltstone2', 'Shale2')
            },
        )
    ### Model 5 - One normal Fault ###
    ### Model 8 - ###
    elif name_model in subset_list_2:
        gp.map_series_to_surfaces(
            geo_data,
            {
                "Fault_Series":
                'Main_Fault',
                "Strat_Series": ('Sandstone', 'Siltstone', 'Shale',
                                 'Sandstone_2', 'Schist', 'Gneiss')
            },
        )
        geo_data.set_is_fault(['Fault_Series'])
    elif name_model in subset_list_3:
        ### Model 2 - Aufwölbung (durch Salzstock?) ###
        ### Model 3+9 - Parallele NNE Schichtung ohne Verwerfung ###
        ### Model 6 - Mulde ###
        gp.map_series_to_surfaces(
            geo_data,
            {
                "Strat_Series": ('Sandstone', 'Siltstone', 'Shale',
                                 'Sandstone_2', 'Schist', 'Gneiss')
            },
        )

    elif name_model in subset_list_4:
        ### Model 7 - Graben ###
        gp.map_series_to_surfaces(
            geo_data,
            {
                "Fault_1":
                'Fault_1',
                "Fault_2":
                'Fault_2',
                "Strat_Series": ('Sandstone', 'Siltstone', 'Shale',
                                 'Sandstone_2', 'Schist', 'Gneiss')
            },
        )
        geo_data.set_is_fault(['Fault_1', 'Fault_2'])

    else:
        print('You would never reach this point. Look for the bug')

    # Interpolation and Computation
    if interpolator is None:
        interp_data = gp.set_interpolator(geo_data,
                                          theano_optimizer='fast_run')
    else:
        interp_data = interpolator
        geo_data.set_theano_function(interpolator)
    sol = gp.compute_model(geo_data)

    if plot_section is True:
        # 2D Plot
        gp.plot_2d(geo_data, cell_number=25, direction='y', show_data=True)
        gp.plot_3d(geo_data)

    if save_pickle is not False:
        if type(save_pickle) is str:
            gp.save_model_to_pickle(geo_data, save_pickle)
        else:
            gp.save_model_to_pickle(geo_data, 'lisa-' + str(n_model))

    return interp_data
Example #9
0
def loop2gempy(test_data_name: str, tmp_path: str, vtk_path: str, orientations_file: str,
               contacts_file: str, groups_file:str,
               bbox: tuple, model_base: float, model_top: float, vtk: bool, dtm_reproj_file:str = None,
               va=None,
               verbose: bool = False, compute: bool = True):
    """

    :param test_data_name:
    :param tmp_path:
    :param vtk_path:
    :param orientations_file:
    :param contacts_file:
    :param groups_file:
    :param bbox:
    :param model_base:
    :param model_top:
    :param vtk:
    :param dtm_reproj_file:
    :param va: vertical anisotropy. Factor by which all Z coordinates are multiplied by
    :param verbose:
    :param compute:
    :return:
    """
    import gempy as gp
    from gempy import plot

    geo_model = gp.create_model(test_data_name)

    # If depth coordinates are much smaller than XY the whole system of equations becomes very unstable. Until
    # I fix it properly in gempy this is a handcrafted hack
    if va is None:
        va = (float(bbox[0]) - float(bbox[2])) / (model_base - model_top)/2

        if va < 3:
            va = 0
        else:
            print('The vertical exageration is: ', va)

    gp.init_data(geo_model, extent=[bbox[0], bbox[2], bbox[1], bbox[3], model_base * va, model_top * va],
                 resolution=(50, 50, 50),
                 path_o=orientations_file,
                 path_i=contacts_file)

    geo_model.modify_surface_points(geo_model.surface_points.df.index, Z=geo_model.surface_points.df['Z'] * va)

    if dtm_reproj_file is not None:
        # Load reprojected topography to model

        fp = dtm_reproj_file
        geo_model.set_topography(source='gdal', filepath=fp)

        # Rescaling topography:
        geo_model.grid.topography.values[:, 2] *= va
        geo_model.grid.update_grid_values()
        geo_model.update_from_grid()

    # Pile processing:
    contents = np.genfromtxt(groups_file,
                             delimiter=',', dtype='U100')

    # Init dictionary Series:Surfaces
    map_series_to_surfaces = {}
    choice = 0
    for group in contents:
        # Reading surfaces groups
        surfaces_g = np.atleast_2d(np.genfromtxt(tmp_path + group + '.csv', delimiter=',', dtype='U100'))

        # Check if there are several choices
        if surfaces_g.shape[1] > 1:
            surfaces_g = surfaces_g[choice]
        # Deleting the first element since it is not a surface
        surfaces_g = surfaces_g[1:]
        # Creating the mapping dictionary
        map_series_to_surfaces[group] = surfaces_g.tolist()

    if verbose is True:
        print(map_series_to_surfaces)

    # Setting pile to model
    gp.map_series_to_surfaces(geo_model, map_series_to_surfaces, remove_unused_series=False)

    #    Removing related data
    del_surfaces = geo_model.surfaces.df.groupby('series').get_group('Default series')['surface']
    geo_model.delete_surfaces(del_surfaces, remove_data=True)

    # Removing series that have not been mapped to any surface
    geo_model.delete_series('Default series')

    if compute is True:
        gp.set_interpolator(geo_model, theano_optimizer='fast_run', dtype='float64')
        gp.compute_model(geo_model)

    # Visualise Model
    gp.plot.plot_3D(geo_model, render_data=False)

    # Save model as vtk
    if vtk:
        gp.plot.export_to_vtk(geo_model, path=vtk_path, name=test_data_name + '.vtk', voxels=False, block=None,
                              surfaces=True)

    return geo_model
Example #10
0
# %%
# Initiate the stratigraphies and faults, and add resistivities to lithology
# --------------------------------------------------------------------------
#

# %%
# Add an air-layer: Horizontal layer at z=0m
geo_model.add_surfaces('air')
geo_model.add_surface_points(0, 0, 0, 'air')
geo_model.add_surface_points(0, 0, 0, 'air')
geo_model.add_orientations(0, 0, 0, 'air', [0, 0, 1])

# Add a Series for the air layer; this series will not be cut by the fault
geo_model.add_series('Air_Series')
geo_model.modify_order_series(2, 'Air_Series')
gempy.map_series_to_surfaces(geo_model, {'Air_Series': 'air'})

# Map the different series
gempy.map_series_to_surfaces(geo_model, {
    "Fault_Series":
    'fault',
    "Air_Series": ('air'),
    "Strat_Series":
    ('seawater', 'overburden', 'target', 'underburden', 'basement')
},
                             remove_unused_series=True)

# %%
geo_model.rename_series({'Main_Fault': 'Fault_Series'})

# %%
Example #11
0
# Assign formations to series
gp.map_series_to_surfaces(
    geo_model,
    {
        "Thrust_Mandach":
        'Mandach',
        "Thrust_Jura":
        'Jurathrust5',
        #"Thrust_Jura6": 'Jurathrust6', #('Jurathrust4', 'Jurathrust5', 'Jurathrust6'),
        "Fault_north_series":
        'Fault_Basement_A',
        "Fault_south_series":
        'Fault-south',
        "Vorwald_series":
        'Vorwald_Basement',
        "BIH_series":
        'BIH-Basement-N',
        "Fault_north_series":
        'Fault_Basement_A',
        "Fault_south_series":
        'Fault-south',
        "Post_graben_series":
        ('OMM', 'USM', 'Malm', 'Effinger-Schichten', 'Dogger', 'Opalinuston',
         'Keuper', 'Oberer-Muschelkalk'),
        "Detachement":
        'Mittlerer-Muschelkalk',
        "Graben_series":
        'graben-fill'
    },
    remove_unused_series=True)
geo_model.surfaces
#%%
# Show data

gp.get_data(geo_model, 'surface_points').head()

gp.plot.plot_data(geo_model, direction='y')

#%%
# Assign formations to series

gp.map_series_to_surfaces(geo_model,
                         {"Fault7_series": 'Fault7',
                          "Fault1_series": 'Fault1',
                          "Fault6_series": 'Fault6',
                          "Fault2_series": 'Fault2',
                          "Fault5_series": 'Fault5',
                         "Fault3_series": 'Fault3',
                         "Fault4_series": 'Fault4',
                         "Post_tectonic_series": ('Quaternary', 'Tertiary', 'Mesozoic'),
                         "Syn_tectonic_series": 'Upper-filling',
                         "Pre_tectonic_series": ('Lower-filling','Middle-filling')},
                         remove_unused_series=True)
geo_model.surfaces

geo_model.set_is_fault(['Fault7_series', 'Fault1_series', 'Fault6_series', 'Fault2_series', 
                        'Fault5_series', 'Fault3_series', 'Fault4_series'])
#geo_model.set_is_finite_fault(series_fault=['Fault6_series', 'Fault5_series', 'Fault3_series', 'Fault4_series'],
#                              toggle=True)

geo_model.faults.faults_relations_df

Example #13
0
geo_model.surfaces.colors.change_colors(col_dict)
geo_model.surfaces

#%%
# Model Characteristics  
# ---------------------
# Main features of the model is the asymetric graben system, with the major fault (denoted with **A**), and the graben fill, which is not present beyond the graben shoulders. This, as well as the stop of major faults beneath the mesozoic units (blue units) are important considerations for the modelling process.  
# These could be caught, for instance, in likelihood functions if we model the PCT as a Bayesian inference problem.

# Assign formations to series
gp.map_series_to_surfaces(geo_model,
                         {"Thrust1_series": 'Thrust1_south',
                          "Thrust2_series": 'Thrust2_south',
                          "Fault2_series": 'Fault2',
                          "Fault5_series": 'Fault5',
                          "Fault6_series": 'Fault6',
                         "Post_tectonic_series": ('Tertiary', 'Pink', 'Orange'),
                          "Detachement": 'Unconformity',
                         "Syn_tectonic_series2": 'Upper-filling',
                         #"Syn_tectonic_series1": 'Middle-filling',
                         "Pre_tectonic_series": 'Lower-filling'},
                         remove_unused_series=True)
geo_model.surfaces

#%%
# After assigning units to stacks or series, we have so define which of those series is a fault. Here, we see that it is usually important to assign each fault its own series, as faults may have very different 
# scalar fields (in which the fault surfaces are interpolated).

geo_model.set_is_fault(['Thrust1_series', 'Thrust2_series',
                        'Fault2_series', 'Fault5_series', 'Fault6_series'],
                      change_color=False)
Example #14
0
def test_complete_model(tmpdir, interpolator):
    # ### Initializing the model:
    compute = True

    geo_model = gp.create_model('Geological_Model1')
    geo_model = gp.init_data(geo_model,
                             extent=[0, 4000, 0, 2775, 200, 1200],
                             resolution=[100, 10, 100])

    if compute is True:
        geo_model.set_theano_function(interpolator)

    from gempy.plot import visualization_2d_pro as vv

    # In this case perpendicular to the z axes
    p2d = vv.Plot2D(geo_model)
    p2d.create_figure((15, 8))
    ax = p2d.add_section(direction='z', ax_pos=121)

    ax2 = p2d.add_section(direction='y', ax_pos=122)
    ax2.set_xlim(geo_model.grid.regular_grid.extent[0],
                 geo_model.grid.regular_grid.extent[1])
    ax2.set_ylim(geo_model.grid.regular_grid.extent[4],
                 geo_model.grid.regular_grid.extent[5])

    geo_model.add_surfaces(['D', 'C', 'B', 'A'])

    # surface B
    geo_model.add_surface_points(X=584, Y=285, Z=500, surface='B')
    geo_model.add_surface_points(X=494, Y=696, Z=500, surface='B')
    geo_model.add_surface_points(X=197, Y=1898, Z=500, surface='B')
    geo_model.add_surface_points(X=473, Y=2180, Z=400, surface='B')
    geo_model.add_surface_points(X=435, Y=2453, Z=400, surface='B')
    # surface C
    geo_model.add_surface_points(X=946, Y=188, Z=600, surface='C')
    geo_model.add_surface_points(X=853, Y=661, Z=600, surface='C')
    geo_model.add_surface_points(X=570, Y=1845, Z=600, surface='C')
    geo_model.add_surface_points(X=832, Y=2132, Z=500, surface='C')
    geo_model.add_surface_points(X=767, Y=2495, Z=500, surface='C')
    # Surface D
    geo_model.add_surface_points(X=967, Y=1638, Z=800, surface='D')
    geo_model.add_surface_points(X=1095, Y=996, Z=800, surface='D')

    geo_model.add_orientations(X=832,
                               Y=2132,
                               Z=500,
                               surface='C',
                               orientation=[98, 17.88, 1])

    p2d.plot_data(ax, direction='z')
    p2d.plot_data(ax2, direction='y')

    gp.compute_model(geo_model) if compute else None
    p2d.plot_contacts(ax, direction='z', cell_number=-10)
    p2d.plot_lith(ax, direction='z', cell_number=-10)

    p2d.plot_contacts(ax2, direction='y', cell_number=5)
    p2d.plot_lith(ax2, direction='y', cell_number=5)

    plt.savefig(os.path.dirname(__file__) + '/../figs/test_pile_complete')

    # -----------
    # Adding a fault
    geo_model.rename_series(['Cycle1'])

    geo_model.add_series(['Fault1'])
    geo_model.set_is_fault(['Fault1'])

    geo_model.modify_order_series(1, 'Fault1')
    geo_model.add_surfaces(['F1'])
    gp.map_series_to_surfaces(geo_model, {'Fault1': 'F1'})

    # Add input data of the fault
    geo_model.add_surface_points(X=1203, Y=138, Z=600, surface='F1')
    geo_model.add_surface_points(X=1250, Y=1653, Z=800, surface='F1')
    # Add orientation
    geo_model.add_orientations(X=1280,
                               Y=2525,
                               Z=500,
                               surface='F1',
                               orientation=[272, 90, -1])

    gp.compute_model(geo_model)

    p2d.remove(ax)
    p2d.plot_data(ax, direction='z', cell_number=-10)
    p2d.plot_contacts(ax, direction='z', cell_number=-10)
    p2d.plot_lith(ax, direction='z', cell_number=-10)

    p2d.remove(ax2)
    # Plot
    p2d.plot_data(ax2, cell_number=5)
    p2d.plot_lith(ax2, cell_number=5)
    p2d.plot_contacts(ax2, cell_number=5)

    # surface B
    geo_model.add_surface_points(X=1447, Y=2554, Z=500, surface='B')
    geo_model.add_surface_points(X=1511, Y=2200, Z=500, surface='B')
    geo_model.add_surface_points(X=1549, Y=629, Z=600, surface='B')
    geo_model.add_surface_points(X=1630, Y=287, Z=600, surface='B')
    # surface C
    geo_model.add_surface_points(X=1891, Y=2063, Z=600, surface='C')
    geo_model.add_surface_points(X=1605, Y=1846, Z=700, surface='C')
    geo_model.add_surface_points(X=1306, Y=1641, Z=800, surface='C')
    geo_model.add_surface_points(X=1476, Y=979, Z=800, surface='C')
    geo_model.add_surface_points(X=1839, Y=962, Z=700, surface='C')
    geo_model.add_surface_points(X=2185, Y=893, Z=600, surface='C')
    geo_model.add_surface_points(X=2245, Y=547, Z=600, surface='C')
    # Surface D
    geo_model.add_surface_points(X=2809, Y=2567, Z=600, surface='D')
    geo_model.add_surface_points(X=2843, Y=2448, Z=600, surface='D')
    geo_model.add_surface_points(X=2873, Y=876, Z=700, surface='D')

    # Compute
    gp.compute_model(geo_model)

    # Plot
    p2d.remove(ax)
    p2d.plot_data(ax, direction='z', cell_number=-10)
    p2d.plot_contacts(ax, direction='z', cell_number=-10)
    p2d.plot_lith(ax, direction='z', cell_number=-10)

    p2d.remove(ax2)
    p2d.plot_lith(ax2, cell_number=5)
    p2d.plot_data(ax2, cell_number=5)

    plt.savefig(os.path.dirname(__file__) + '/../figs/test_pile_complete')

    # ----------------
    # Second cycle
    geo_model.add_series(['Cycle2'])
    geo_model.add_surfaces(['G', 'H'])
    gp.map_series_to_surfaces(geo_model, {'Cycle2': ['G', 'H']})
    geo_model.reorder_series(['Cycle2', 'Fault1', 'Cycle1'])

    # Surface G
    geo_model.add_surface_points(X=1012, Y=1493, Z=900, surface='G')
    geo_model.add_surface_points(X=1002, Y=1224, Z=900, surface='G')
    geo_model.add_surface_points(X=1996, Y=47, Z=800, surface='G')
    geo_model.add_surface_points(X=300, Y=907, Z=700, surface='G')
    # Surface H
    geo_model.add_surface_points(X=3053, Y=727, Z=800, surface='G')
    # Orientation
    geo_model.add_orientations(X=1996,
                               Y=47,
                               Z=800,
                               surface='G',
                               orientation=[272, 5.54, 1])

    # Compute
    gp.compute_model(geo_model)

    # Plot
    p2d.remove(ax)
    p2d.plot_data(ax, direction='z', cell_number=-10)
    p2d.plot_contacts(ax, direction='z', cell_number=-10)
    p2d.plot_lith(ax, direction='z', cell_number=-10)

    p2d.remove(ax2)
    p2d.plot_lith(ax2, cell_number=5)
    p2d.plot_data(ax2, cell_number=5)
    p2d.plot_contacts(ax2, cell_number=5)

    plt.savefig(os.path.dirname(__file__) + '/../figs/test_pile_complete')

    # ----------------
    # Second Fault
    geo_model.add_series('Fault2')
    geo_model.set_is_fault('Fault2')
    geo_model.add_surfaces('F2')

    geo_model.reorder_series(['Cycle2', 'Fault1', 'Fault2', 'Cycle1'])
    gp.map_series_to_surfaces(geo_model, {'Fault2': 'F2'})

    geo_model.add_surface_points(X=3232, Y=178, Z=1000, surface='F2')
    geo_model.add_surface_points(X=3132, Y=951, Z=700, surface='F2')
    # geo_model.add_surface_points(X=2962, Y=2184, Z=700, surface='F2')

    geo_model.add_orientations(X=3132,
                               Y=951,
                               Z=700,
                               surface='F2',
                               orientation=[95, 90, 1])

    # Compute
    gp.compute_model(geo_model)

    # Plot
    p2d.remove(ax)
    p2d.plot_data(ax, direction='z', cell_number=5, legend='force')
    p2d.plot_lith(ax, direction='z', cell_number=5)
    p2d.plot_contacts(ax, direction='z', cell_number=5)

    p2d.remove(ax2)
    p2d.plot_lith(ax2, cell_number=5)
    p2d.plot_data(ax2, cell_number=5)
    p2d.plot_contacts(ax2, cell_number=5)

    plt.savefig(os.path.dirname(__file__) + '/../figs/test_pile_complete')

    geo_model.add_surface_points(X=3135, Y=1300, Z=700, surface='D')
    geo_model.add_surface_points(X=3190, Y=969, Z=700, surface='D')

    geo_model.add_surface_points(X=3031, Y=2725, Z=800, surface='G')
    geo_model.add_surface_points(X=3018, Y=1990, Z=800, surface='G')
    geo_model.add_surface_points(X=3194, Y=965, Z=700, surface='G')

    geo_model.add_surface_points(X=3218, Y=1818, Z=890, surface='H')
    geo_model.add_surface_points(X=3934, Y=1207, Z=810, surface='H')

    # Compute
    gp.compute_model(geo_model)

    # Plot
    p2d.remove(ax)
    p2d.plot_data(ax, direction='z', cell_number=5, legend='force')
    p2d.plot_lith(ax, direction='z', cell_number=5)
    p2d.plot_contacts(ax, direction='z', cell_number=5)

    p2d.remove(ax2)
    p2d.plot_lith(ax2, cell_number=5)
    p2d.plot_data(ax2, cell_number=5)
    p2d.plot_contacts(ax2, cell_number=5)

    plt.savefig(os.path.dirname(__file__) + '/../figs/test_pile_complete')