def test_buffer(): model = GeologicalModel([0, 0, 0], [5, 5, 5]) interpolator = model.get_interpolator(interpolatortype='FDI', nelements=1e5, buffer=0.2) print(interpolator.support.origin) assert np.sum(interpolator.support.origin + .2) == 0
def test_remove_constraints_PLI(): data, bb = load_claudius() model = GeologicalModel(bb[0, :], bb[1, :]) model.set_model_data(data) s0 = model.create_and_add_foliation("s0", interpolatortype="FDI", nelements=1000, solver="cg", damp=False)
def test_create_stratigraphy_PLI_pyamg(): data, bb = load_claudius() model = GeologicalModel(bb[0, :], bb[1, :]) model.set_model_data(data) s0 = model.create_and_add_foliation("s0", interpolatortype="PLI", nelements=1000, solver="pyamg", damp=True)
def test_create_stratigraphy_PLI_lu(): data, bb = load_claudius() model = GeologicalModel(bb[0, :], bb[1, :]) model.set_model_data(data) s0 = model.create_and_add_foliation('s0', interpolatortype='PLI', nelements=1000, solver='lu', damp=True)
def test_access_feature_model(): data, bb = load_claudius() model = GeologicalModel(bb[0, :], bb[1, :]) model.set_model_data(data) s0 = model.create_and_add_foliation("s0", interpolatortype="FDI", nelements=1000, solver="fake", damp=False) assert s0 == model["s0"]
def test_element_number_FDI(): model = GeologicalModel([0, 0, 0], [5, 5, 5]) interpolator = model.get_interpolator(interpolatortype="FDI", nelements=1e5, buffer=0.2) assert np.log10(interpolator.support.n_nodes) - 5 < 1 interpolator = model.get_interpolator(interpolatortype="FDI", nelements=1e6, buffer=0.2) assert np.log10(interpolator.support.n_nodes) - 6 < 1 interpolator = model.get_interpolator(interpolatortype="FDI", nelements=3e4, buffer=0.2) assert np.log10(interpolator.support.n_nodes) - 4 < 1
def test_element_number_FDI(): model = GeologicalModel([0, 0, 0], [5, 5, 5]) interpolator = model.get_interpolator(interpolatortype='FDI', nelements=1e5, buffer=0.2) assert interpolator.support.n_elements - 1e5 < 1e3 interpolator = model.get_interpolator(interpolatortype='FDI', nelements=1e6, buffer=0.2) assert interpolator.support.n_elements - 1e6 < 1e3 interpolator = model.get_interpolator(interpolatortype='FDI', nelements=3e4, buffer=0.2) assert interpolator.support.n_elements - 3e4 < 1e3
def test_create_and_add_fault(): model = GeologicalModel([0, 0, 0], [1, 1, 1]) data = pd.DataFrame( [ [0.5, 0.5, 0.5, 0, 1, 0, 0, "fault", 0], # [0.5, 0.5, 0.5, 0, 1, 0, 0, "fault", 0], [0.5, 0.5, 0.5, 1, 0, 0, 1, "fault", 0], [0.5, 0.5, 0.5, 0, 0, 1, 2, "fault", 0], ], columns=["X", "Y", "Z", "nx", "ny", "nz", "coord", "feature_name", "val"], ) model.data = data model.create_and_add_fault( "fault", 1, nelements=1e4, # force_mesh_geometry=True ) assert isinstance(model["fault"], FaultSegment)
def set_model(): model = GeologicalModel(np.zeros(), np.ones()) coordinate_0 = GeologicalFeature('coord0', None) coordinate_1 = GeologicalFeature('coord1', None) coordinate_2 = GeologicalFeature('coord2', None) frame = StructuralFrame('structural_frame', [coordinate_0, coordinate_1, coordinate_2]) frame.set_model(model) assert frame.model == model assert frame[0].model == model assert frame[1].model == model assert frame[2].model == model
def set_model(): model = GeologicalModel(np.zeros(3), np.ones(3)) coordinate_0 = GeologicalFeature("coord0", None) coordinate_1 = GeologicalFeature("coord1", None) coordinate_2 = GeologicalFeature("coord2", None) frame = StructuralFrame( "structural_frame", [coordinate_0, coordinate_1, coordinate_2] ) frame.set_model(model) assert frame.model == model assert frame[0].model == model assert frame[1].model == model assert frame[2].model == model
def test_outside_box_normal(): for interpolator in ['PLI', 'FDI']: print(f'Running test for {interpolator} with normal constraints') model = GeologicalModel(np.zeros(3), np.ones(3)) data = pd.DataFrame( [[0.5, 0.5, 0.5, 0, 1., 0., 'strati'], [1.5, 0.5, 0.5, 0, 1., 0., 'strati'], [0.5, 1.5, 1.5, 0, 1., 0., 'strati']], columns=['X', 'Y', 'Z', 'nx', 'ny', 'nz', 'feature_name']) model.data = data model.create_and_add_foliation('strati', interpolatortype=interpolator) model.update()
def average_axis(): data, bb = load_laurent2016() model = GeologicalModel(bb[0, :], bb[1, :]) model.set_model_data(data) s2 = model.create_and_add_fold_frame("s2", nelements=10000) s1 = model.create_and_add_folded_fold_frame( "s1", limb_wl=0.4, av_fold_axis=True, nelements=50000 ) s0 = model.create_and_add_folded_fold_frame( "s0", limb_wl=1.0, av_fold_axis=True, nelements=50000 )
def test_no_fold_frame(): mdata = pd.concat([data[:100], data[data['feature_name'] == 's1']]) model = GeologicalModel(boundary_points[0, :], boundary_points[1, :]) model.set_model_data(mdata) fold_frame = model.create_and_add_fold_frame('s1', nelements=10000) stratigraphy = model.create_and_add_folded_foliation( 's0', # fold_frame, nelements=10000, # av_fold_axis=True fold_axis=[-6.51626577e-06, -5.00013645e-01, -8.66017526e-01], limb_wl=1)
def test_average_fold_axis(): mdata = pd.concat([data[:100], data[data["feature_name"] == "s1"]]) model = GeologicalModel(boundary_points[0, :], boundary_points[1, :]) model.set_model_data(mdata) fold_frame = model.create_and_add_fold_frame("s1", nelements=10000) stratigraphy = model.create_and_add_folded_foliation( "s0", fold_frame, nelements=10000, av_fold_axis=True # fold_axis=[-6.51626577e-06, -5.00013645e-01, -8.66017526e-01], # limb_wl=1 )
def test_intrusion_builder(): model = GeologicalModel(boundary_points[0, :], boundary_points[1, :]) model.data = data model.nsteps = [10, 10, 10] intrusion_data = data[data['feature_name'] == 'tabular_intrusion'] frame_data = model.data[model.data["feature_name"] == 'tabular_intrusion_frame'].copy() conformable_feature = model.create_and_add_foliation('stratigraphy') intrusion_network_parameters = {'type': 'interpolated', 'contact': 'roof'} interpolator = model.get_interpolator(interpolatortype='FDI') intrusion_frame_builder = IntrusionFrameBuilder( interpolator, name='tabular_intrusion_frame', model=model) # -- create intrusion network intrusion_frame_builder.set_intrusion_network_parameters( intrusion_data, intrusion_network_parameters) intrusion_network_geometry = intrusion_frame_builder.create_intrusion_network( ) # -- create intrusion frame using intrusion network points and flow/inflation measurements intrusion_frame_builder.set_intrusion_frame_data( frame_data, intrusion_network_geometry) ## -- create intrusion frame intrusion_frame_builder.setup() intrusion_frame = intrusion_frame_builder.frame # -- create intrusion builder to simulate distance thresholds along frame coordinates intrusion_builder = IntrusionBuilder(intrusion_frame, model=model, name="tabular intrusion") intrusion_builder.lateral_extent_model = rectangle_function #intrusion_lateral_extent_model intrusion_builder.vertical_extent_model = parallelepiped_function #intrusion_vertical_extent_model intrusion_builder.set_data_for_extent_simulation(intrusion_data) intrusion_builder.build_arguments = { "lateral_extent_sgs_parameters": {}, "vertical_extent_sgs_parameters": {} } intrusion_feature = intrusion_builder.feature intrusion_builder.update() assert len(intrusion_feature._lateral_simulated_thresholds) > 0 assert len(intrusion_feature._growth_simulated_thresholds) > 0
#'solver':'cg', 'cpw': 10, 'npw': 10 } foliation_params = { 'interpolatortype': 'PLI', # 'interpolatortype':'PLI', 'nelements': 1e5, # how many tetras/voxels 'buffer': 1.8, # how much to extend nterpolation around box #'solver':'cg', 'cpw': 10, 'npw': 10 } model = GeologicalModel.from_map2loop_directory( proj_path, # evaluate=False, fault_params=fault_params, rescale=False, foliation_params=foliation_params, ) #model.to_file(output_path + "/model.pickle") model.update() view = LavaVuModelViewer(model, vertical_exaggeration=1) view.nsteps = np.array([200, 200, 200]) view.nsteps = np.array([50, 50, 50]) for sg in model.feature_name_index: if ('super' in sg): view.add_data(model.features[model.feature_name_index[sg]]) view.nelements = 1e5 view.add_model_surfaces(function=function, filename=filename, faults=False) view.nelements = 1e6
def build_model(m2l_data, evaluate=True, skip_faults=False, unconformities=False, fault_params=None, foliation_params=None, rescale=True, skip_features=[], **kwargs): """[summary] [extended_summary] Parameters ---------- m2l_data : dict [description] skip_faults : bool, optional [description], by default False fault_params : dict, optional [description], by default None foliation_params : dict, optional [description], by default None Returns ------- [type] [description] """ from LoopStructural import GeologicalModel boundary_points = np.zeros((2, 3)) boundary_points[0, 0] = m2l_data["bounding_box"]["minx"] boundary_points[0, 1] = m2l_data["bounding_box"]["miny"] boundary_points[0, 2] = m2l_data["bounding_box"]["lower"] boundary_points[1, 0] = m2l_data["bounding_box"]["maxx"] boundary_points[1, 1] = m2l_data["bounding_box"]["maxy"] boundary_points[1, 2] = m2l_data["bounding_box"]["upper"] model = GeologicalModel(boundary_points[0, :], boundary_points[1, :], rescale=rescale) # m2l_data['data']['val'] /= model.scale_factor model.set_model_data(m2l_data["data"]) if not skip_faults: faults = [] for f in m2l_data["max_displacement"].keys(): if model.data[model.data["feature_name"] == f].shape[0] == 0: continue if f in skip_features: continue fault_id = f overprints = [] try: overprint_id = m2l_data["fault_fault"][ m2l_data["fault_fault"][fault_id] == 1]["fault_id"].to_numpy() for i in overprint_id: overprints.append(i) logger.info("Adding fault overprints {}".format(f)) except: logger.info("No entry for %s in fault_fault_relations" % f) # continue fault_center = m2l_data["stratigraphic_column"]["faults"][f][ "FaultCenter"] fault_influence = m2l_data["stratigraphic_column"]["faults"][f][ "InfluenceDistance"] fault_extent = m2l_data["stratigraphic_column"]["faults"][f][ "HorizontalRadius"] fault_vertical_radius = m2l_data["stratigraphic_column"]["faults"][ f]["VerticalRadius"] fault_slip_vector = m2l_data["stratigraphic_column"]["faults"][f][ "FaultSlip"] faults.append( model.create_and_add_fault( f, -m2l_data["max_displacement"][f], faultfunction="BaseFault", fault_slip_vector=fault_slip_vector, fault_center=fault_center, fault_extent=fault_extent, fault_influence=fault_influence, fault_vectical_radius=fault_vertical_radius, # overprints=overprints, **fault_params, )) # for f in m2l_data['fault_intersection_angles']: # if f in m2l_data['max_displacement'].keys(): # f1_norm = m2l_data['stratigraphic_column']['faults'][f]['FaultNorm'] # for intersection in m2l_data['fault_intersection_angles'][f]: # if intersection[0] in m2l_data['max_displacement'].keys(): # f2_norm = m2l_data['stratigraphic_column']['faults'][intersection[0]]['FaultNorm'] # if intersection[2] < 30 and np.dot(f1_norm,f2_norm)>0: # logger.info('Adding splay {} to {}'.format(intersection[0],f)) # if model[f] is None: # logger.error('Fault {} does not exist, cannot be added as splay') # elif model[intersection[0]] is None: # logger.error('Fault {} does not exist') # else: # model[intersection[0]].builder.add_splay(model[f]) # else: # logger.info('Adding abut {} to {}'.format(intersection[0],f)) # model[intersection[0]].add_abutting_fault(model[f]) faults = m2l_data.get("fault_graph", None) if faults: for f in faults.nodes: f1_norm = m2l_data["stratigraphic_column"]["faults"][f][ "FaultNorm"] for e in faults.edges(f): data = faults.get_edge_data(*e) f2_norm = m2l_data["stratigraphic_column"]["faults"][ e[1]]["FaultNorm"] if float(data["angle"]) < 30 and np.dot(f1_norm, f2_norm) > 0: if model[f] is None or model[e[1]] is None: logger.error( "Fault {} does not exist, cannot be added as splay" ) elif model[e[1]] is None: logger.error("Fault {} does not exist") else: region = model[e[1]].builder.add_splay(model[f]) model[e[1]].splay[model[f].name] = region else: if model[f] is None or model[e[1]] is None: continue logger.info("Adding abut {} to {}".format(e[1], f)) model[e[1]].add_abutting_fault(model[f]) ## loop through all of the groups and add them to the model in youngest to oldest. group_features = [] for i in np.sort(m2l_data["groups"]["group number"].unique()): g = (m2l_data["groups"].loc[m2l_data["groups"]["group number"] == i, "group"].unique()[0]) group_features.append( model.create_and_add_foliation(g, **foliation_params)) # if the group was successfully added (not null) then lets add the base (0 to be unconformity) if group_features[-1] and unconformities: model.add_unconformity(group_features[-1], 0) model.set_stratigraphic_column(m2l_data["stratigraphic_column"]) if evaluate: model.update(verbose=True) return model
from LoopStructural.datasets import load_claudius #demo data from LoopStructural import log_to_file import pandas as pd import numpy as np ################################################################################################## # Specify a log file # ~~~~~~~~~~~~~~~~~~~~ log_to_file('logging_demo_log.log') ################################################################################################## # Create model # ~~~~~~~~~~~~~~~~~~~~ data, bb = load_claudius() model = GeologicalModel(bb[0,:],bb[1,:]) model.set_model_data(data) vals = [0,60,250,330,600] strat_column = {'strati':{}} for i in range(len(vals)-1): strat_column['strati']['unit_{}'.format(i)] = {'min':vals[i],'max':vals[i+1],'id':i} model.set_stratigraphic_column(strat_column) strati = model.create_and_add_foliation("strati", interpolatortype="FDI", # try changing this to 'PLI' nelements=1e4, # try changing between 1e3 and 5e4 buffer=0.3, solver='pyamg', damp=True ) viewer = LavaVuModelViewer(model,background="white")
def loop2LoopStructural(thickness_file,orientation_file,contacts_file,bbox): from LoopStructural import GeologicalModel from LoopStructural.visualisation import LavaVuModelViewer import lavavu df = pd.read_csv(thickness_file) thickness = {} for f in df['formation'].unique(): thickness[f] = np.mean(df[df['formation']==f]['thickness']) #display(thickness) order = ['P__TKa_xs_k','P__TKo_stq','P__TKk_sf','P__TK_s', 'A_HAu_xsl_ci', 'A_HAd_kd', 'A_HAm_cib', 'A_FOj_xs_b', 'A_FO_xo_a', 'A_FO_od', 'A_FOu_bbo', 'A_FOp_bs', 'A_FOo_bbo', 'A_FOh_xs_f', 'A_FOr_b'] strat_val = {} val = 0 for o in order: if o in thickness: strat_val[o] = val val+=thickness[o] #display(strat_val) orientations = pd.read_csv(orientation_file) contacts = pd.read_csv(contacts_file) contacts['val'] = np.nan for o in strat_val: contacts.loc[contacts['formation']==o,'val'] = strat_val[o] data = pd.concat([orientations,contacts],sort=False) data['type'] = np.nan for o in order: data.loc[data['formation']==o,'type'] = 's0' data boundary_points = np.zeros((2,3)) boundary_points[0,0] = bbox[0] boundary_points[0,1] = bbox[1] boundary_points[0,2] = -20000 boundary_points[1,0] = bbox[2] boundary_points[1,1] = bbox[3] boundary_points[1,2] = 1200 model = GeologicalModel(boundary_points[0,:],boundary_points[1,:]) model.set_model_data(data) strati = model.create_and_add_foliation('s0', #identifier in data frame interpolatortype="FDI", #which interpolator to use nelements=400000, # how many tetras/voxels buffer=0.1, # how much to extend nterpolation around box solver='external', external=solve_pyamg ) #viewer = LavaVuModelViewer() viewer = LavaVuModelViewer(model) viewer.add_data(strati['feature']) viewer.add_isosurface(strati['feature'], # nslices=10, slices= strat_val.values(), # voxet={'bounding_box':boundary_points,'nsteps':(100,100,50)}, paint_with=strati['feature'], cmap='tab20' ) #viewer.add_scalar_field(model.bounding_box,(100,100,100), # 'scalar', ## norm=True, # paint_with=strati['feature'], # cmap='tab20') viewer.add_scalar_field(strati['feature']) viewer.set_viewer_rotation([-53.8190803527832, -17.1993350982666, -2.1576387882232666]) #viewer.save("fdi_surfaces.png") viewer.interactive()
from LoopStructural.visualisation import LavaVuModelViewer import pandas as pd import numpy as np data, bb = load_claudius() data = data.reset_index() data.loc[:, 'val'] *= -1 data.loc[:, ['nx', 'ny', 'nz']] *= -1 data.loc[792, 'feature_name'] = 'strati2' data.loc[792, ['nx', 'ny', 'nz']] = [0, 0, 1] data.loc[792, 'val'] = 0 model = GeologicalModel(bb[0, :], bb[1, :]) model.set_model_data(data) strati2 = model.create_and_add_foliation('strati2', interpolatortype='PLI', nelements=1e4, solver='pyamg') uc = model.add_unconformity(strati2, 1) strati = model.create_and_add_foliation('strati', interpolatortype='PLI', nelements=1e4, solver='pyamg') ######################################################################## # Stratigraphic columns
###################################################################### # Testing data density # ~~~~~~~~~~~~~~~~~~~~ # # - Use the toggle bar to change the amount of data used by the # interpolation algorithm. # - How does the shape of the fold change as we remove data points? # - Now what happens if we only consider data from the map view? # # **HINT** you can view the strike and dip data by unchecking the scalar # field box. # # **The black arrows are the normal vector to the folded surface** # npoints = 20 model = GeologicalModel(boundary_points[0,:],boundary_points[1,:]) model.set_model_data(data[:npoints]) stratigraphy = model.create_and_add_foliation("s0",interpolatortype="PLI",nelements=5000,buffer=0.3,cgw=0.1)#.2) viewer = LavaVuModelViewer(model,background="white") # viewer.add_scalar_field(model.bounding_box,(38,55,30), # 'box', # paint_with=stratigraphy, # cmap='prism') viewer.add_data(stratigraphy) viewer.add_isosurface(stratigraphy, ) viewer.rotate([-85.18760681152344, 42.93233871459961, 0.8641873002052307]) viewer.display() ######################################################################
data = pd.DataFrame(np.vstack([surface_1,surface_2]),columns=['X','Y','Z','val']) data['feature_name'] = 'conformable' data.head() ############################################################################################### # Creating a GeologicalModel # ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # The GeologicalModel is the main entry point into LoopStructural which manages the model domain, # setting up the interpolators, unconformities, faults etc. # To create a GeologicalModel we need to define the extent of the model with an origin vector and a maximum vector. # The pandas dataframe that contains the model data need to be linked to the geological model. # from LoopStructural import GeologicalModel model = GeologicalModel(extent[:,0],extent[:,1]) model.set_model_data(data) ############################################################################################### # Adding a conformable foliation # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # We can create a geological feature using the create_and_add_foliation method. # This returns a To build a scalar field representing the conformable_feature = model.create_and_add_foliation('conformable') ############################################################################################### # Visualising a 2-D section # ~~~~~~~~~~~~~~~~~~~~~~~~~ # Geological feature can be evaluated: # * for the scalar field value at a location
# A ProcessInputData onject can be built from these datasets using the argument names. A full list of possible arguments can be found in the documentation. processor = ProcessInputData( contacts=contacts, contact_orientations=stratigraphic_orientations.rename( {"formation": "name"}, axis=1), thicknesses=thicknesses, stratigraphic_order=order, origin=origin, maximum=maximum, ) ############################## # The process input data can be used to directly build a geological model model = GeologicalModel.from_processor(processor) model.update() ############################## # Or build directly from the dataframe and processor attributes. model2 = GeologicalModel(processor.origin, processor.maximum) model2.data = processor.data model2.create_and_add_foliation("supergroup_0") model2.update() ############################## # Visualising model # ~~~~~~~~~~~~~~~~~ view = LavaVuModelViewer(model)
def test_intrusion_freame_builder(): model = GeologicalModel(boundary_points[0, :], boundary_points[1, :]) model.data = data model.nsteps = [10, 10, 10] intrusion_data = data[data['feature_name'] == 'tabular_intrusion'] frame_data = model.data[model.data["feature_name"] == 'tabular_intrusion_frame'].copy() conformable_feature = model.create_and_add_foliation('stratigraphy') intrusion_network_parameters = { 'type': 'shortest path', 'contact': 'roof', 'delta_c': [2], 'contact_anisotropies': [conformable_feature], 'shortest_path_sequence': [conformable_feature], 'shortest_path_axis': 'X' } delta_c = intrusion_network_parameters.get('delta_c')[0] # -- get variables for intrusion frame interpolation interpolatortype = "FDI" nelements = 1e2 weights = [0, 0, 0] interpolator = model.get_interpolator(interpolatortype=interpolatortype) intrusion_frame_builder = IntrusionFrameBuilder( interpolator, name='tabular_intrusion_frame', model=model) # -- create intrusion network intrusion_frame_builder.set_intrusion_network_parameters( intrusion_data, intrusion_network_parameters) intrusion_network_geometry = intrusion_frame_builder.create_intrusion_network( ) keys = list(intrusion_frame_builder.anisotropies_series_parameters.keys()) # #test if points lie in the contact of interest mean = intrusion_frame_builder.anisotropies_series_parameters[keys[0]][1] # mean = -10 stdv = intrusion_frame_builder.anisotropies_series_parameters[keys[0]][2] evaluated_inet_points = conformable_feature.evaluate_value( model.scale(intrusion_network_geometry[:, :3])) assert np.all( np.logical_and((mean - stdv * delta_c) <= evaluated_inet_points, (mean + stdv * delta_c) >= evaluated_inet_points)) # -- create intrusion frame using intrusion network points and flow/inflation measurements intrusion_frame_builder.set_intrusion_frame_data( frame_data, intrusion_network_geometry) ## -- create intrusion frame intrusion_frame_builder.setup( nelements=nelements, w2=weights[0], w1=weights[1], gxygz=weights[2], ) intrusion_frame = intrusion_frame_builder.frame assert isinstance(intrusion_frame, StructuralFrame)
fault = np.zeros(xx.shape) fault[yy > 0] = 50 val = intrusion(xx, yy) + fault plt.contourf(val) ###################################################################### # LoopStructural applies structural frames to the fault geometry to # capture the geometry and kinematics of the fault. A fault frame # consisting of the fault surface, fault slip direction and fault extent # are built from observations. The geometry of the deformed surface is # then interpolated by first restoring the observations by combining the # fault frame and an expected displacement model. # model = GeologicalModel(bb[0, :], bb[1, :]) model.set_model_data(data) fault = model.create_and_add_fault('fault', 500, nelements=10000, steps=4, interpolatortype='PLI', buffer=0.3) viewer = LavaVuModelViewer(model) viewer.add_isosurface(fault, isovalue=0 # slices=[0,1]#nslices=10 ) xyz = model.data[model.data['feature_name'] == 'strati'][['X', 'Y', 'Z']].to_numpy()
def test_create_scale_factor_model(): model = GeologicalModel([0, 0, 0], [5, 5, 5], rescale=True) assert model.scale_factor == 5
def build_model(m2l_data, skip_faults=False, unconformities=False, fault_params=None, foliation_params=None, rescale=True, **kwargs): """[summary] [extended_summary] Parameters ---------- m2l_data : dict [description] skip_faults : bool, optional [description], by default False fault_params : dict, optional [description], by default None foliation_params : dict, optional [description], by default None Returns ------- [type] [description] """ from LoopStructural import GeologicalModel boundary_points = np.zeros((2, 3)) boundary_points[0, 0] = m2l_data['bounding_box']['minx'] boundary_points[0, 1] = m2l_data['bounding_box']['miny'] boundary_points[0, 2] = m2l_data['bounding_box']['lower'] boundary_points[1, 0] = m2l_data['bounding_box']['maxx'] boundary_points[1, 1] = m2l_data['bounding_box']['maxy'] boundary_points[1, 2] = m2l_data['bounding_box']['upper'] model = GeologicalModel(boundary_points[0, :], boundary_points[1, :], rescale=rescale) # m2l_data['data']['val'] /= model.scale_factor model.set_model_data(m2l_data['data']) if not skip_faults: faults = [] for f in m2l_data['max_displacement'].keys(): if model.data[model.data['feature_name'] == f].shape[0] == 0: continue fault_id = f overprints = [] try: overprint_id = m2l_data['fault_fault'][ m2l_data['fault_fault'][fault_id] == 1]['fault_id'].to_numpy() for i in overprint_id: overprints.append(i) logger.info('Adding fault overprints {}'.format(f)) except: logger.info('No entry for %s in fault_fault_relations' % f) # continue faults.append( model.create_and_add_fault( f, -m2l_data['max_displacement'][f], faultfunction='BaseFault', overprints=overprints, **fault_params, )) ## loop through all of the groups and add them to the model in youngest to oldest. group_features = [] for i in np.sort(m2l_data['groups']['group number'].unique()): g = m2l_data['groups'].loc[m2l_data['groups']['group number'] == i, 'group'].unique()[0] group_features.append( model.create_and_add_foliation(g, **foliation_params)) # if the group was successfully added (not null) then lets add the base (0 to be unconformity) if group_features[-1] and unconformities: model.add_unconformity(group_features[-1], 0) model.set_stratigraphic_column(m2l_data['stratigraphic_column']) return model
############################## # Modelling splay faults # ~~~~~~~~~~~~~~~~~~~~~~ # A splay fault relationship is defined for any fault where the angle between the faults is less than $30^\circ$. In this example we specify the angle between the faults as $10^\circ$. processor = ProcessInputData( fault_orientations=ori, fault_locations=df, origin=origin, maximum=maximum, fault_edges=[("fault_2", "fault_1")], fault_edge_properties=[{"angle": 10}], ) model = GeologicalModel.from_processor(processor) model.update() view = LavaVuModelViewer(model) for f in model.faults: view.add_isosurface(f, slices=[0]) # view.rotation = [-50.92916488647461, -30.319700241088867, -20.521053314208984] view.display() ############################## # Modelling abutting faults # ~~~~~~~~~~~~~~~~~~~~~~~~~ # In this exampe we will use the same faults but specify the angle between the faults as $40^\circ$ which will change the fault relationship to be abutting rather than splay. processor = ProcessInputData( fault_orientations=ori,
# images = {} for v in [1, 5, 1 / 5]: v_data = np.zeros((1, 4)) v_data[0, :3] += 0.1 data = pd.DataFrame(v_data, columns=["X", "Y", "Z", "val"]) data["feature_name"] = "test" data["feature_name"] = "test" data["nx"] = np.nan data["ny"] = np.nan data["nz"] = np.nan data.loc[3, :] = [0, 0, 0, np.nan, "test", v, 0, 0] # data.loc[3,['nx','ny','nz']]/=np.linalg.norm(data.loc[3,['nx','ny','nz']]) # data.loc[4,:] = [0,0,1,np.nan,'test',1,0,0] model = GeologicalModel(np.zeros(3), np.ones(3) * 10) model.data = data model.create_and_add_foliation("test", nelements=1e4, interpolatortype="FDI") view = LavaVuModelViewer(model) view.add_isosurface(model["test"], slices=[0, 1], name="test") view.add_data(model["test"]) view.rotate([-92.68915557861328, 2.879497528076172, 1.5840799808502197]) view.xmin = 0 view.ymin = 0 view.zmin = 0 view.xmax = 10 view.ymax = 10 view.zmax = 10 images[v] = view.image_array()
# bb[1,2] = 10000 data.head() newdata = pd.DataFrame([[5923.504395,4748.135254,3588.621094,'s2',1.0]],columns=['X','Y','Z','feature_name','val']) data = pd.concat([data,newdata],sort=False) rotation = [-69.11979675292969, 15.704944610595703, 6.00014591217041] ###################################################################### # Modelling S2 # ~~~~~~~~~~~~ # model = GeologicalModel(bb[0,:],bb[1,:]) model.set_model_data(data) s2 = model.create_and_add_fold_frame('s2', nelements=10000, buffer=0.5, solver='lu', damp=True) viewer = LavaVuModelViewer(model) viewer.add_scalar_field(s2[0], cmap='prism') viewer.add_isosurface(s2[0], slices=[0,1]) viewer.add_data(s2[0]) viewer.rotate(rotation) viewer.display()