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") viewer.add_model_surfaces() viewer.rotate([-85.18760681152344, 42.93233871459961, 0.8641873002052307]) viewer.display() ################################################################################################# # Looking at the log file # ~~~~~~~~~~~~~~~~~~~~~~~ # Here are the first 10 lines of the log file. # Most operations in loopstructural are recorded and this will allow you to identify whether # an operation is not occuring as you would expect. from itertools import islice # with open('logging_demo_log.log') as inf: # for line in islice(inf, 0, 11): # print(line)
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() fig, ax = plt.subplots(1, 3, figsize=(30, 10)) ax[0].imshow(images[1]) ax[1].imshow(images[5]) ax[2].imshow(images[1 / 5]) ax[0].axis("off")
######################################################################## # Stratigraphic columns # ~~~~~~~~~~~~~~~~~~~~~~~ # We define the stratigraphic column using a nested dictionary stratigraphic_column = {} stratigraphic_column['strati2'] = {} stratigraphic_column['strati2']['unit1'] = {'min': 1, 'max': 10, 'id': 0} stratigraphic_column['strati'] = {} stratigraphic_column['strati']['unit2'] = {'min': -60, 'max': 0, 'id': 1} stratigraphic_column['strati']['unit3'] = {'min': -250, 'max': -60, 'id': 2} stratigraphic_column['strati']['unit4'] = {'min': -330, 'max': -250, 'id': 3} stratigraphic_column['strati']['unit5'] = { 'min': -np.inf, 'max': -330, 'id': 4 } ######################################################## # Adding stratigraphic column to the model # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # The stratigraphic column can be added to the geological model. Allowing # for the `model.evaluate_model(xyz)` function to be called. model.set_stratigraphic_column(stratigraphic_column) viewer = LavaVuModelViewer(model) viewer.add_model(cmap='tab20') viewer.rotate([-85.18760681152344, 42.93233871459961, 0.8641873002052307]) viewer.display()
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()
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) view.add_model_surfaces() view.rotation = [-37.965614318847656, 13.706363677978516, 3.110347032546997] view.display() ############################## # Adding faults # ~~~~~~~~~~~~~ fault_orientations fault_edges fault_properties processor = ProcessInputData(
# # - 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() ###################################################################### # Modelling folds using structural geology # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
# 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() xyz = xyz[fault.evaluate(xyz).astype(bool), :] viewer.add_vector_field(fault, locations=xyz) viewer.add_points( model.data[model.data['feature_name'] == 'strati'][['X', 'Y', 'Z']], name='prefault') viewer.rotation = [-73.24819946289062, -86.82220458984375, -13.912878036499023] viewer.display() displacement = 400 #INSERT YOUR DISPLACEMENT NUMBER HERE BEFORE #
# distance from a reference horizon. It is comparable # to the relative thickness # # * ``nx`` is the x component of the normal vector to the surface gradient # * ``ny`` is the y component of the normal vector to the surface gradient # * ``nz`` is the z component of the normal vector to the surface gradeint # * ``strike`` is the strike angle # * ``dip`` is the dip angle # # Having a look at the data for this example by looking at the top of the # dataframe and then using a 3D plot # data['feature_name'].unique() viewer = LavaVuModelViewer(background='white') viewer.add_value_data(data[~np.isnan(data['val'])][['X', 'Y', 'Z']], data[~np.isnan(data['val'])]['val'], name='value points') viewer.add_vector_data(data[~np.isnan(data['nx'])][['X', 'Y', 'Z']], data[~np.isnan(data['nx'])][['nx', 'ny', 'nz']], name='orientation points') viewer.rotate([-85.18760681152344, 42.93233871459961, 0.8641873002052307]) viewer.display() ###################################################################### # The pandas dataframe can be linked to the ``GeologicalModel`` using # ``.set_model_data(dataframe`` # model.set_model_data(data)
'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 view.add_model_surfaces(function=function, filename=filename, strati=False, displacement_cmap='rainbow') view.lv.webgl(vtk_path + model_name) view.nsteps = np.array([200, 200, 200])
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() ###################################################################### # Modelling S1 # ~~~~~~~~~~~~ #
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') viewer = LavaVuModelViewer(model) viewer.add_isosurface( strati2, # nslices=5 slices=[2, 1.5, 1], ) viewer.add_isosurface(strati, slices=[0, -60, -250, -330], paint_with=strati) viewer.rotate([-85.18760681152344, 42.93233871459961, 0.8641873002052307]) viewer.display()
# ~~~~~~~~~~~~~~~~~~~~~~ # 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, fault_locations=df, origin=origin, maximum=maximum,
# # - plot a vector field using the gradient of a geological feature # # .. code:: python # # viewer.add_vector_field(feature, **kwargs) # # Where ``locations`` can be specified to control specific evaluation locations # It is recommended to visualise # the vectorfield at a lower resolution than the mesh otherwise it can be # difficult to see the vectors. You can use numpy stepping along the # array: ``locations = mesh.barycentre[::20,:]`` which will sample every # 20th sample in the numpy array. # viewer = LavaVuModelViewer(model,background="white") # determine the number of unique surfaces in the model from # the input data and then calculate isosurfaces for this unique = np.unique(strati.interpolator.get_value_constraints()[:,3]) viewer.add_isosurface(strati, slices=unique, cmap='prism', paint_with=strati) viewer.add_section(strati, axis='x', value=0., boundary_points=model.bounding_box, nsteps=np.array([30,30,30]), cmap='prism')
bb[1,0]+=200 bb[0,0]-=200 bb[1,1]+=200 bb[0,1]-=200 bb[1,2]+=200 bb[0,2]-=200 model = GeologicalModel(bb[0,:],bb[1,:]) data['random'] = np.random.random(data.shape[0]) model.set_model_data(data[data['random'] < 0.01])#[np.isnan(data['val'])]) strati = model.create_and_add_foliation("strati", interpolatortype="surfe", method='single_surface' ) print(strati.evaluate_value(model.regular_grid((10,10,10)))) viewer = LavaVuModelViewer(model,background="white") # determine the number of unique surfaces in the model from # the input data and then calculate isosurfaces for this unique = np.unique(strati.interpolator.get_value_constraints()[:,3]) viewer.add_isosurface(model.features[0], slices=unique, cmap='prism', paint_with=model.features[0]) # # # viewer.add_section(model.features[0], # # axis='x', # # value=0, # # boundary_points=model.bounding_box, # # nsteps=np.array([30,30,30]), # # voxet=model.voxet(),
# 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, voxet=model.voxet(), isovalue=0 # slices=[0,1]#nslices=10 ) xyz = model.data[model.data['feature_name'] == 'strati'][['X', 'Y', 'Z']].to_numpy() xyz = xyz[fault.evaluate(xyz), :] viewer.add_vector_field(fault, locations=xyz) viewer.add_points( model.data[model.data['feature_name'] == 'strati'][['X', 'Y', 'Z']], name='prefault') viewer.display() displacement = 400 #INSERT YOUR DISPLACEMENT NUMBER HERE BEFORE #