def cylinder(h): cylinder = SeismicMesh.Cylinder(h=1.0, r=1.0) points, cells = SeismicMesh.generate_mesh(domain=cylinder, edge_length=h, verbose=0) points, cells = SeismicMesh.sliver_removal( points=points, domain=cylinder, edge_length=h, verbose=0 ) return points, cells
def test_3dmesher(): fname = os.path.join(os.path.dirname(__file__), "test3D.bin") wl = 10 hmin = 50 freq = 2 grade = 0.005 nz, nx, ny = 20, 10, 10 ef = SeismicMesh.MeshSizeFunction( bbox=(-2e3, 0, 0, 1e3, 0, 1e3), nx=nx, ny=ny, nz=nz, endianness="big", grade=grade, freq=freq, wl=wl, model=fname, hmin=hmin, ) ef = ef.build() mshgen = SeismicMesh.MeshGenerator(ef, method="qhull") points, cells = mshgen.build(nscreen=1, max_iter=20, seed=0) # 16459 vertices and 102868 cells assert len(points) == 16459 assert np.abs(len(cells) - 102868) < 150
def ball(h): ball = SeismicMesh.Ball([0.0, 0.0, 0.0], 1.0) points, cells = SeismicMesh.generate_mesh( domain=ball, h0=h, edge_length=h, verbose=0 ) points, cells = SeismicMesh.sliver_removal( domain=ball, points=points, h0=h, edge_length=h, verbose=0 ) return points, cells
def test_verbose(): square = SeismicMesh.Rectangle((0.0, 1.0, 0.0, 1.0)) for verbosity, correct_size in zip([0, 1, 2], [0, 191, 6013]): sys.stdout = open("output.txt", "w") points, cells = SeismicMesh.generate_mesh(domain=square, edge_length=0.1, verbose=verbosity) sys.stdout.close() sys.stdout = sys.__stdout__ output_size = os.path.getsize("output.txt") assert output_size == correct_size
def run_SeismicMesh(HMIN=0.025): bbox = (-1.0, 1.0, -1.0, 1.0, -1.0, 1.0) def dsphere(p, xc, yc, zc, r): """Signed distance function for a sphere centered at xc,yc,zc with radius r.""" return ( numpy.sqrt((p[:, 0] - xc) ** 2 + (p[:, 1] - yc) ** 2 + (p[:, 2] - zc) ** 2) - r ) def sphere(x): return dsphere(x, 0, 0, 0, 1) def fh(x): return numpy.abs(numpy.sqrt(numpy.einsum("ij, ij->i", x, x)) - 0.5) / 5 + HMIN t1 = time.time() points, cells = SeismicMesh.generate_mesh( bbox=bbox, h0=HMIN, domain=sphere, edge_length=fh, max_iter=25, delta_t=0.3, ) points, cells = SeismicMesh.sliver_removal( points=points, bbox=bbox, h0=HMIN, domain=sphere, edge_length=fh, min_dh_angle_bound=10, max_iter=50, ) elapsed = time.time() - t1 # meshio.write_points_cells( # "SeismicMesh_sphere.vtk", # points, # [("tetra", cells)], # ) plex = meshplex.MeshTetra(points, cells) angles = plex.q_min_sin_dihedral_angles quality = plex.q_radius_ratio num_cells = len(cells) num_vertices = len(points) return angles, quality, elapsed, num_vertices, num_cells
def example_2D(): # Name of SEG-Y file containg velocity model. fname = "velocity_models/vel_z6.25m_x12.5m_exact.segy" bbox = (-12e3, 0, 0, 67e3) # Construct mesh sizing object from velocity model ef = SeismicMesh.MeshSizeFunction( bbox=bbox, model=fname, domain_ext=500, dt=0.001, freq=5, wl=5, hmax=1e3, hmin=50.0, grade=0.05, ) # Build mesh size function ef = ef.build() ef.WriteVelocityModel("BP2004") # Save your mesh size function options. ef.SaveMeshSizeFunctionOptions("BP2004_SizingFunction") # Visualize mesh size function # ef.plot() # Construct mesh generator mshgen = SeismicMesh.MeshGenerator( ef, method="qhull" ) # if you have cgal installed, you can use method="cgal" # Build the mesh (note the seed makes the result deterministic) points, facets = mshgen.build(max_iter=2, nscreen=1, seed=0) import numpy as np np.savetxt("points.out", points, delimiter=",") # Write to disk (see meshio for more details) meshio.write_points_cells( "BP2004.msh", points / 1000, [("triangle", facets)], file_format="gmsh22", binary=False, )
def test_smooth_diff(): cube1 = sm.Cube((-0.5, 0.5, -0.5, 0.5, -0.5, 0.5)) ball1 = sm.Ball((0.0, 0.0, 0.5), 0.85) domain = sm.Difference([ball1, cube1], smoothness=0.20) points, cells = sm.generate_mesh( domain=domain, edge_length=0.10, ) points, cells = sm.sliver_removal( points=points, domain=domain, edge_length=0.10, ) assert np.abs(cells.shape[0] - 9004) < 100
def disk(h): domain = SeismicMesh.geometry.Disk([0.0, 0.0], 1.0) points, cells = SeismicMesh.generate_mesh( h0=h, domain=domain, edge_length=h, verbose=0 ) return points, cells
def example_write(): # Name of SEG-Y file containg velocity model. fname = "velocity_models/vel_z6.25m_x12.5m_exact.segy" bbox = (-12e3, 0, 0, 67e3) # Construct mesh sizing object from velocity model ef = SeismicMesh.MeshSizeFunction( bbox=bbox, model=fname, domain_ext=2e3, dt=0.001, freq=5, wl=5, hmax=1e3, hmin=50.0, grade=0.05, ) ef = ef.build() # Write it to an hdf5 file for later use. ef.WriteVelocityModel("BP2004") # Save your mesh size function options. ef.SaveMeshSizeFunctionOptions("BP2004_SizingFunction")
def run_SeismicMesh(HMIN=0.01): bbox = (-1.0, 1.0, -1.0, 1.0) disk = SeismicMesh.geometry.Disk([0, 0], 1) def fh(x): return numpy.array([HMIN] * len(x)) t1 = time.time() points, cells = SeismicMesh.generate_mesh( bbox=bbox, h0=HMIN, domain=disk, edge_length=fh, max_iter=25, delta_t=0.3, ) elapsed = time.time() - t1 # meshio.write_points_cells( # "SeismicMesh_circle.vtk", # points, # [("triangle", cells)], # ) plex = meshplex.MeshTri(points, cells) quality = numpy.abs(plex.cell_quality) num_cells = len(cells) num_vertices = len(points) return quality, elapsed, num_vertices, num_cells
def box_with_refinement(h): cube = SeismicMesh.geometry.Cube((-1.0, 1.0, -1.0, 1.0, -1.0, 1.0)) def edge_length(x): return h + 0.1 * numpy.sqrt(x[:, 0] ** 2 + x[:, 1] ** 2 + x[:, 2] ** 2) points, cells = SeismicMesh.generate_mesh( domain=cube, h0=h, edge_length=edge_length, verbose=0 ) points, cells = SeismicMesh.sliver_removal( domain=cube, points=points, h0=h, edge_length=edge_length, verbose=0, ) return points, cells
def test_2dmesher(): fname = os.path.join(os.path.dirname(__file__), "testing.segy") wl = 5 hmin = 100 grade = 0.005 ef = SeismicMesh.MeshSizeFunction(bbox=(-10e3, 0, 0, 10e3), grade=grade, wl=wl, model=fname, hmin=hmin) ef = ef.build() mshgen = SeismicMesh.MeshGenerator(ef) points, facets = mshgen.build(max_iter=100, seed=0) # should have: 7690 vertices and 15045 cells assert np.abs((len(points) == 7690)) assert len(facets) == 15045
def ball(h): bbox = (-1.0, 1.0, -1.0, 1.0, -1.0, 1.0) def ball(x): return numpy.sqrt(x[:, 0]**2 + x[:, 1]**2 + x[:, 2]**2) - 1.0 points, cells = SeismicMesh.generate_mesh(bbox=bbox, h0=h, domain=ball, edge_length=h, verbose=False) points, cells = SeismicMesh.sliver_removal(points=points, bbox=bbox, h0=h, domain=ball, edge_length=h, verbose=False) return points, cells
def rect_with_refinement(h): domain = SeismicMesh.geometry.Rectangle((-1.0, +1.0, -1.0, +1.0)) def f(x): return h + 0.1 * numpy.sqrt(x[:, 0] ** 2 + x[:, 1] ** 2) points, cells = SeismicMesh.generate_mesh( domain=domain, h0=h, edge_length=f, verbose=0 ) return points, cells
def rect_with_refinement(h): bbox = (-1.0, 1.0, -1.0, 1.0) domain = SeismicMesh.geometry.Rectangle([-1.0, +1.0, -1.0, +1.0]) points, cells = SeismicMesh.generate_mesh( bbox=bbox, h0=h, domain=domain, edge_length=lambda x: h + 0.1 * numpy.sqrt(x[:, 0]**2 + x[:, 1]**2), ) return points, cells
def box_with_refinement(h): bbox = (-1.0, 1.0, -1.0, 1.0, -1.0, 1.0) cube = SeismicMesh.geometry.Cube([-1.0, 1.0, -1.0, 1.0, -1.0, 1.0]) def edge_length(x): return h + 0.1 * numpy.sqrt(x[:, 0]**2 + x[:, 1]**2 + x[:, 2]**2) points, cells = SeismicMesh.generate_mesh(bbox=bbox, h0=h, domain=cube, edge_length=edge_length, verbose=False) points, cells = SeismicMesh.sliver_removal( points=points, bbox=bbox, h0=h, domain=cube, edge_length=edge_length, verbose=False, ) return points, cells
def test_immersion(): for radius in radii: box0 = SeismicMesh.Rectangle((0.0, 1.0, 0.0, 1.0)) disk0 = SeismicMesh.Disk([0.5, 0.5], radius) def fh(p): return 0.05 * np.abs(disk0.eval(p)) + hmin points, cells = SeismicMesh.generate_mesh( domain=box0, edge_length=fh, h0=hmin, subdomains=[disk0], ) pmid = points[cells].sum(1) / 3 # Compute centroids sd = disk0.eval(pmid) # measure the subdomain volume subdomain_vol = np.sum(SeismicMesh.geometry.simp_vol(points, cells[sd < 0])) assert np.isclose(subdomain_vol, np.pi * radius ** 2, rtol=1e-2)
def example_3D(): # Name of SEG-Y file containg velocity model. fname = "velocity_models/EGAGE_Salt.bin" bbox = (-4200, 0, 0, 13520, 0, 13520) # Construct mesh sizing object from velocity model ef = SeismicMesh.MeshSizeFunction( bbox=bbox, model=fname, nx=676, ny=676, nz=210, dt=0.001, freq=2, wl=10, hmin=25, grade=0.35, domain_ext=1000, ) # Build mesh size function ef = ef.build() # Save your options so you have a record ef.SaveMeshSizeFunctionOptions("EGAGE_Salt") # Construct mesh generator mshgen = SeismicMesh.MeshGenerator(ef, method="cgal") # Build the mesh points, cells = mshgen.build(nscreen=1, max_iter=30, seed=0) # Write to disk (see meshio for more details) meshio.write_points_cells( "foo3D_V3.vtk", points, [("tetra", cells)], )
def test_pfix(): hmin = 0.05 bbox = (0.0, 1.0, 0.0, 1.0, 0.0, 1.0) pfix = np.linspace((0.0, 0.0, 0.0), (1.0, 0.0, 1.0), int(np.sqrt(2) / hmin)) pfix = np.vstack((pfix, SeismicMesh.geometry.corners(bbox))) cube = SeismicMesh.Cube(bbox) points, cells = SeismicMesh.generate_mesh(domain=cube, edge_length=hmin, pfix=pfix) def _closest_node(node, nodes): nodes = np.asarray(nodes) deltas = nodes - node dist_2 = np.einsum("ij,ij->i", deltas, deltas) return dist_2 for p in pfix: d = _closest_node(p, points) assert np.isclose(np.min(d), 0.0)
def test_hmin(): fname = os.path.join(os.path.dirname(__file__), "testing.segy") hmin = 100 ef = SeismicMesh.MeshSizeFunction(bbox=(-1e3, 0, 0, 1e3), wl=5, model=fname, hmin=hmin) ef = ef.build() fh = ef.fh zg, xg = ef.GetDomainMatrices() sz1z, sz1x = zg.shape sz2 = sz1z * sz1x _zg = np.reshape(zg, (sz2, 1)) _xg = np.reshape(xg, (sz2, 1)) hh = fh((_zg, _xg)) hh = np.reshape(hh, (sz1z, sz1x)) assert np.amin(hh) == hmin
def l_shape_3d(h): tol = h / 10 cube0 = SeismicMesh.Cube((-1.0, 1.0, -1.0, 1.0, -1.0, tol)) cube1 = SeismicMesh.Cube((-1.0, 1.0, 0.0, 1.0, -tol, 1.0)) cube2 = SeismicMesh.Cube((-tol, 1.0, -1.0, 1.0, -tol, 1.0)) domain = SeismicMesh.Union([cube0, cube1, cube2]) points, cells = SeismicMesh.generate_mesh(domain=domain, edge_length=h, verbose=0) points, cells = SeismicMesh.sliver_removal( domain=domain, points=points, edge_length=h, verbose=0 ) return points, cells
def quarter_annulus(h): rect = SeismicMesh.Rectangle((0.0, 1.0, 0.0, 1.0)) disk0 = SeismicMesh.Disk([0.0, 0.0], 0.25) diff0 = SeismicMesh.Difference([rect, disk0]) disk1 = SeismicMesh.Disk([0.0, 0.0], 1.0) quarter = SeismicMesh.Intersection([diff0, disk1]) points, cells = SeismicMesh.generate_mesh( domain=quarter, edge_length=lambda x: h + 0.1 * numpy.abs(disk0.eval(x)), h0=h, verbose=0, ) return points, cells
def test_grade(): fname = os.path.join(os.path.dirname(__file__), "testing.segy") wl = 5 hmin = 10 grade = 0.005 elen = 1e3 ef = SeismicMesh.MeshSizeFunction(bbox=(-10e3, 0, 0, 10e3), grade=grade, wl=wl, model=fname, hmin=hmin) ef = ef.build() fh = ef.fh zg, xg = ef.GetDomainMatrices() nz, nx = zg.shape _zg = np.reshape(zg, (nz * nx, 1)) _xg = np.reshape(xg, (nz * nx, 1)) hh = fh((_zg, _xg)) hh = np.reshape(hh, (nz, nx)) max_grade = CheckGrade(hh, nz, nx, elen=elen) assert max_grade <= grade
def generate_mesh3D(model, G, comm): print('Entering mesh generation', flush=True) M = grid_point_to_mesh_point_converter_for_seismicmesh(model, G) method = model["opts"]["method"] Lz = model["mesh"]['Lz'] lz = model['BCs']['lz'] Lx = model["mesh"]['Lx'] lx = model['BCs']['lx'] Ly = model["mesh"]['Ly'] ly = model['BCs']['ly'] Real_Lz = Lz + lz Real_Lx = Lx + 2 * lx Real_Ly = Ly + 2 * ly minimum_mesh_velocity = model['testing_parameters'][ 'minimum_mesh_velocity'] frequency = model["acquisition"]['frequency'] lbda = minimum_mesh_velocity / frequency edge_length = lbda / M #print(Real_Lz) bbox = (-Real_Lz, 0.0, -lx, Real_Lx - lx, -ly, Real_Ly - ly) cube = SeismicMesh.Cube(bbox) if comm.comm.rank == 0: # Creating rectangular mesh points, cells = SeismicMesh.generate_mesh(domain=cube, edge_length=edge_length, mesh_improvement=False, max_iter=75, comm=comm.ensemble_comm, verbose=0) points, cells = SeismicMesh.sliver_removal(points=points, bbox=bbox, domain=cube, edge_length=edge_length, preserve=True, max_iter=200) print('entering spatial rank 0 after mesh generation') meshio.write_points_cells("meshes/3Dhomogeneous" + str(G) + ".msh", points, [("tetra", cells)], file_format="gmsh22", binary=False) meshio.write_points_cells("meshes/3Dhomogeneous" + str(G) + ".vtk", points, [("tetra", cells)], file_format="vtk") comm.comm.barrier() if method == "CG" or method == "KMV": mesh = fire.Mesh( "meshes/3Dhomogeneous" + str(G) + ".msh", distribution_parameters={ "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0) }, ) print('Finishing mesh generation', flush=True) return mesh
def generate_mesh2D(model, G, comm): print('Entering mesh generation', flush=True) M = grid_point_to_mesh_point_converter_for_seismicmesh(model, G) method = model["opts"]["method"] Lz = model["mesh"]['Lz'] lz = model['BCs']['lz'] Lx = model["mesh"]['Lx'] lx = model['BCs']['lx'] Real_Lz = Lz + lz Real_Lx = Lx + 2 * lx if model['testing_parameters']['experiment_type'] == 'homogeneous': minimum_mesh_velocity = model['testing_parameters'][ 'minimum_mesh_velocity'] frequency = model["acquisition"]['frequency'] lbda = minimum_mesh_velocity / frequency Real_Lz = Lz + lz Real_Lx = Lx + 2 * lx edge_length = lbda / M bbox = (-Real_Lz, 0.0, -lx, Real_Lx - lx) rec = SeismicMesh.Rectangle(bbox) if comm.comm.rank == 0: # Creating rectangular mesh points, cells = SeismicMesh.generate_mesh(domain=rec, edge_length=edge_length, mesh_improvement=False, comm=comm.ensemble_comm, verbose=0) print('entering spatial rank 0 after mesh generation') points, cells = SeismicMesh.geometry.delete_boundary_entities( points, cells, min_qual=0.6) a = np.amin(SeismicMesh.geometry.simp_qual(points, cells)) meshio.write_points_cells("meshes/2Dhomogeneous" + str(G) + ".msh", points, [("triangle", cells)], file_format="gmsh22", binary=False) meshio.write_points_cells("meshes/2Dhomogeneous" + str(G) + ".vtk", points, [("triangle", cells)], file_format="vtk") comm.comm.barrier() if method == "CG" or method == "KMV": mesh = fire.Mesh( "meshes/2Dhomogeneous" + str(G) + ".msh", distribution_parameters={ "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0) }, ) elif model['testing_parameters']['experiment_type'] == 'heterogeneous': # Name of SEG-Y file containg velocity model. fname = "vel_z6.25m_x12.5m_exact.segy" # Bounding box describing domain extents (corner coordinates) bbox = (-12000.0, 0.0, 0.0, 67000.0) rectangle = SeismicMesh.Rectangle(bbox) # Desired minimum mesh size in domain frequency = model["acquisition"]['frequency'] hmin = 1429.0 / (M * frequency) # Construct mesh sizing object from velocity model ef = SeismicMesh.get_sizing_function_from_segy( fname, bbox, hmin=hmin, wl=M, freq=5.0, grade=0.15, domain_pad=model["BCs"]["lz"], pad_style="edge", ) points, cells = SeismicMesh.generate_mesh(domain=rectangle, edge_length=ef, verbose=0, mesh_improvement=False) meshio.write_points_cells("meshes/2Dheterogeneous" + str(G) + ".msh", points / 1000, [("triangle", cells)], file_format="gmsh22", binary=False) meshio.write_points_cells("meshes/2Dheterogeneous" + str(G) + ".vtk", points / 1000, [("triangle", cells)], file_format="vtk") comm.comm.barrier() if method == "CG" or method == "KMV": mesh = fire.Mesh( "meshes/2Dheterogeneous" + str(G) + ".msh", distribution_parameters={ "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0) }, ) print('Finishing mesh generation', flush=True) return mesh
# when testing multiple cores. print('Entering mesh generation', flush=True) if model['opts']['degree'] == 2: M = 5.1 elif model['opts']['degree'] == 3: M = 3.1 edge_length = 0.286 / M Real_Lz = model["mesh"]["Lz"] + model["BCs"]["lz"] Lx = model["mesh"]["Lx"] Ly = model["mesh"]["Ly"] pad = model["BCs"]["lz"] bbox = (-Real_Lz, 0.0, -pad, Lx + pad, -pad, Ly + pad) cube = SeismicMesh.Cube(bbox) points, cells = SeismicMesh.generate_mesh(domain=cube, edge_length=edge_length, max_iter=80, comm=comm.ensemble_comm, verbose=2) points, cells = SeismicMesh.sliver_removal(points=points, bbox=bbox, max_iter=100, domain=cube, edge_length=edge_length, preserve=True) meshio.write_points_cells("meshes/benchmark_3d.msh", points, [("tetra", cells)],
def test_2d_domain_ext(): fname = os.path.join(os.path.dirname(__file__), "testing.segy") wl = 5 freq = 10 hmin = 100 hmax = 1000 grade = 0.005 domain_ext = 1e3 ef = SeismicMesh.MeshSizeFunction( bbox=(-10e3, 0, 0, 10e3), grade=grade, domain_ext=domain_ext, wl=wl, freq=freq, model=fname, hmin=hmin, hmax=hmax, ) ef = ef.build() mshgen = SeismicMesh.MeshGenerator(ef) points, facets = mshgen.build(max_iter=100, seed=0, nscreen=1) # 12284 vertices and 24144 cells assert len(points) == 12284 assert len(facets) == 24144 ef = SeismicMesh.MeshSizeFunction( bbox=(-10e3, 0, 0, 10e3), grade=grade, domain_ext=500, padstyle="constant", wl=wl, freq=freq, model=fname, hmin=hmin, hmax=hmax, ) ef = ef.build() mshgen = SeismicMesh.MeshGenerator(ef) points, facets = mshgen.build(max_iter=100, seed=0, nscreen=1) # 10992 vertices and 21580 cells assert len(points) == 10992 assert len(facets) == 21580 ef = SeismicMesh.MeshSizeFunction( bbox=(-10e3, 0, 0, 10e3), grade=grade, domain_ext=2000, padstyle="linear_ramp", wl=wl, freq=freq, model=fname, hmin=hmin, hmax=hmax, ) ef = ef.build() mshgen = SeismicMesh.MeshGenerator(ef) points, facets = mshgen.build(max_iter=100, seed=0, nscreen=1) # 14773 vertices and 29102 cells assert len(points) == 14773 assert len(facets) == 29102
if model['opts']['degree'] == 2: M = 5.85 elif model['opts']['degree'] == 3: M = 3.08 elif model['opts']['degree'] == 4: M = 2.22 elif model['opts']['degree'] == 5: M = 1.69 edge_length = 0.286 / M Real_Lz = model["mesh"]["Lz"] + model["BCs"]["lz"] Lx = model["mesh"]["Lx"] pad = model["BCs"]["lz"] bbox = (-Real_Lz, 0.0, -pad, Lx + pad) rec = SeismicMesh.Rectangle(bbox) if comm.comm.rank == 0: points, cells = SeismicMesh.generate_mesh(domain=rec, edge_length=edge_length, comm=comm.ensemble_comm, verbose=0) points, cells = SeismicMesh.geometry.delete_boundary_entities(points, cells, min_qual=0.6) meshio.write_points_cells("meshes/benchmark_2d.msh", points, [("triangle", cells)], file_format="gmsh22", binary=False)
def create_model_2D_heterogeneous(grid_point_calculator_parameters, degree): ''' Creates models with the correct parameters for for grid point calculation experiments. Parameters ---------- frequency: `float` Source frequency to use in calculation degree: `int` Polynomial degree of finite element space method: `string` The finite element method choosen minimum_mesh_velocity: `float` Minimum velocity presented in the medium experiment_type: `string` Only options are `homogenous` or `heterogenous` receiver_type: `string` Options: `near`, `far` or `near_and_far`. Specifies receiver grid locations for experiment Returns ------- model: Python `dictionary` Contains model options and parameters for use in Spyro ''' minimum_mesh_velocity = grid_point_calculator_parameters['minimum_velocity_in_the_domain'] frequency = grid_point_calculator_parameters['source_frequency'] dimension = grid_point_calculator_parameters['dimension'] receiver_type = grid_point_calculator_parameters['receiver_setup'] method = grid_point_calculator_parameters['FEM_method_to_evaluate'] velocity_model = grid_point_calculator_parameters['velocity_model_file_name'] model = {} if minimum_mesh_velocity > 500: print("Warning: minimum mesh velocity seems to be in m/s, input should be in km/s", flush = True) # domain calculations pady = 0.0 Ly = 0.0 #using the BP2004 velocity model Lz = 12000.0/1000. Lx = 67000.0/1000. pad = 1000./1000. Real_Lz = Lz+ pad Real_Lx = Lx+ 2*pad source_z = -1.0 source_x = Real_Lx/2. source_coordinates = [(source_z,source_x)] if velocity_model != None: if velocity_model[-4:] == "segy": SeismicMesh.write_velocity_model(velocity_model, ofname = 'velocity_models/gridsweepcalc') elif velocity_model[-4:] == "hdf5": shutil.copy(velocity_model,'velocity_models/gridsweepcalc.hdf5' ) else: raise ValueError("Velocity model filetype not recognized.") else: print("Warning: running without a velocity model is suitable for testing purposes only.", flush = True) padz = pad padx = pad if receiver_type == 'bins': # time calculations tmin = 1./frequency final_time = 25*tmin #should be 35 # receiver calculations receiver_bin_center1 = 2.5*750.0/1000 receiver_bin_width = 500.0/1000 receiver_quantity_in_bin = 100#2500 # 50 squared bin1_startZ = source_z - receiver_bin_width/2. bin1_endZ = source_z + receiver_bin_width/2. bin1_startX = source_x + receiver_bin_center1 - receiver_bin_width/2. bin1_endX = source_x + receiver_bin_center1 + receiver_bin_width/2. receiver_coordinates = spyro.create_2d_grid(bin1_startZ, bin1_endZ, bin1_startX, bin1_endX, int(np.sqrt(receiver_quantity_in_bin))) receiver_bin_center2 = 6500.0/1000 receiver_bin_width = 500.0/1000 bin2_startZ = source_z - receiver_bin_width/2. bin2_endZ = source_z + receiver_bin_width/2. bin2_startX = source_x + receiver_bin_center2 - receiver_bin_width/2. bin2_endX = source_x + receiver_bin_center2 + receiver_bin_width/2. receiver_coordinates= receiver_coordinates + spyro.create_2d_grid(bin2_startZ, bin2_endZ, bin2_startX, bin2_endX, int(np.sqrt(receiver_quantity_in_bin))) receiver_quantity = 2*receiver_quantity_in_bin if receiver_type == 'line': # time calculations tmin = 1./frequency final_time = 2*10*tmin + 5.0 #should be 35 # receiver calculations receiver_bin_center1 = 2000.0/1000 receiver_bin_center2 = 10000.0/1000 receiver_quantity = 500 bin1_startZ = source_z bin1_endZ = source_z bin1_startX = source_x + receiver_bin_center1 bin1_endX = source_x + receiver_bin_center2 receiver_coordinates = spyro.create_transect( (bin1_startZ, bin1_startX), (bin1_endZ, bin1_endX), receiver_quantity) # Choose method and parameters model["opts"] = { "method": method, "variant": None, "element": "tria", # tria or tetra "degree": degree, # p order "dimension": dimension, # dimension } model["BCs"] = { "status": True, # True or false "outer_bc": "non-reflective", # neumann, non-reflective (outer boundary condition) "damping_type": "polynomial", # polynomial. hyperbolic, shifted_hyperbolic "exponent": 1, "cmax": 4.7, # maximum acoustic wave velocity in PML - km/s "R": 0.001, # theoretical reflection coefficient "lz": padz, # thickness of the pml in the z-direction (km) - always positive "lx": padx, # thickness of the pml in the x-direction (km) - always positive "ly": pady, # thickness of the pml in the y-direction (km) - always positive } model["mesh"] = { "Lz": Lz, # depth in km - always positive "Lx": Lx, # width in km - always positive "Ly": Ly, # thickness in km - always positive "meshfile": "demos/mm_exact.msh", "initmodel": "velocity_models/gridsweepcalc.hdf5", "truemodel": "velocity_models/gridsweepcalc.hdf5", } model["acquisition"] = { "source_type": "Ricker", "num_sources": 1, "source_pos": source_coordinates, "source_mesh_point": False, "source_point_dof": False, "frequency": frequency, "delay": 1.0, "num_receivers": receiver_quantity, "receiver_locations": receiver_coordinates, } model["timeaxis"] = { "t0": 0.0, # Initial time for event "tf": final_time, # Final time for event "dt": 0.001, # timestep size "nspool": 200, # how frequently to output solution to pvds "fspool": 100, # how frequently to save solution to RAM } model["parallelism"] = { "type": "off", # options: automatic (same number of cores for evey processor), custom, off. "custom_cores_per_shot": [], # only if the user wants a different number of cores for every shot. # input is a list of integers with the length of the number of shots. } model['testing_parameters'] = { 'minimum_mesh_velocity': minimum_mesh_velocity, 'pml_fraction': padz/Lz, 'receiver_type': receiver_type } # print(source_coordinates) # print(receiver_coordinates) return model
def l_shape(h): rect0 = SeismicMesh.Rectangle([-1.0, 1.0, -1.0, 0.0]) rect1 = SeismicMesh.Rectangle([-1.0, 0.0, -1.0, 1.0]) domain = SeismicMesh.Union([rect0, rect1]) points, cells = SeismicMesh.generate_mesh(domain=domain, edge_length=h, verbose=0) return points, cells