def mesh(mesh_type): if mesh_type == "triangle": model["opts"]["dimension"] = 2 model["acquisition"]["receiver_locations"] = spyro.create_transect( (0.0, 1.0), (0.0, 0.9), 256 ) model["acquisition"]["source_pos"] = [(-0.05, 1.5)] elif mesh_type == "square": model["opts"]['quadrature']=='GLL' model["opts"]["dimension"] = 2 model["acquisition"]["receiver_locations"] = spyro.create_transect( (0.0, 1.0), (0.0, 0.9), 256 ) model["acquisition"]["source_pos"] = [(-0.05, 1.5)] elif mesh_type == "tetrahedral": model["opts"]["dimension"] = 3 model["acquisition"]["receiver_locations"] = spyro.create_transect( (0.0, 0.0, 0.0), (0.0, 0.0, 1.0), 256 ) model["acquisition"]["source_pos"] = [(-0.05, 1.5, 1.5)] return { "triangle": lambda n: UnitSquareMesh(2 ** n, 2 ** n), "tetrahedral": lambda n: UnitCubeMesh(2 ** n, 2 ** n, 2 ** n), "square": lambda n: UnitSquareMesh(2 ** n, 2 ** n, quadrilateral = True), }[mesh_type]
def test_correct_at_value2D(): comm = spyro.utils.mpi_init(model) model["opts"]["degree"] = 3 mesh, V = spyro.io.read_mesh(model, comm) pz = -0.1 px = 0.3 recvs = spyro.create_transect((pz, px), (pz, px), 3) # recvs = spyro.create_transect( # (-0.00935421, 3.25160664), (-0.00935421, 3.25160664), 3 # ) model["acquisition"]["receiver_locations"] = recvs model["acquisition"]["num_receivers"] = 3 receivers = spyro.Receivers(model, mesh, V, comm) V = receivers.space z, x = SpatialCoordinate(mesh) u1 = Function(V).interpolate(x + z) test1 = math.isclose((pz + px), receivers._Receivers__new_at(u1.dat.data[:], 0), rel_tol=1e-09) u1 = Function(V).interpolate(sin(x) * z * 2) test2 = math.isclose( sin(px) * pz * 2, receivers._Receivers__new_at(u1.dat.data[:], 0), rel_tol=1e-05, ) assert all([test1, test2])
def test_correct_at_value3D(): test_model2 = deepcopy(model3D) test_model2["acquisition"]["num_receivers"] = 3 test_model2["opts"]["degree"] = 3 comm = spyro.utils.mpi_init(test_model2) mesh, V = spyro.io.read_mesh(test_model2, comm) x_start = 0.09153949331982138 x_end = 0.09153949331982138 z_start = 0.0 z_end = 0.0 y_start = 0.47342699605572036 y_end = 0.47342699605572036 x_real, y_real, z_real = x_start, y_start, z_start recvs = spyro.create_transect((z_start, x_start, y_start), (z_end, x_end, y_end), 3) test_model2["acquisition"]["receiver_locations"] = recvs receivers = spyro.Receivers(test_model2, mesh, V, comm) V = receivers.space z, x, y = SpatialCoordinate(mesh) u1 = Function(V).interpolate(x + z + y) realvalue = x_real + y_real + z_real test1 = math.isclose(realvalue, receivers._Receivers__new_at(u1.dat.data[:], 0), rel_tol=1e-09) u1 = Function(V).interpolate(sin(x) * (z + 1)**2 * cos(y)) realvalue = sin(x_real) * (z_real + 1)**2 * cos(y_real) test2 = math.isclose(realvalue, receivers._Receivers__new_at(u1.dat.data[:], 0), rel_tol=1e-05) assert all([test1, test2])
def mesh(mesh_type): if mesh_type == "square": model["opts"]["element"] = "tria" model["opts"]["dimension"] = 2 model["acquisition"]["receiver_locations"] = spyro.create_transect( (0.0, 1.0), (0.0, 0.9), 256) model["acquisition"]["source_pos"] = [(-0.05, 1.5)] elif mesh_type == "cube": model["opts"]["element"] = "tetra" model["opts"]["dimension"] = 3 model["acquisition"]["receiver_locations"] = spyro.create_transect( (0.0, 0.0, 0.0), (0.0, 0.0, 1.0), 256) model["acquisition"]["source_pos"] = [(-0.05, 1.5, 1.5)] return { "square": lambda n: UnitSquareMesh(2**n, 2**n), "cube": lambda n: UnitCubeMesh(2**n, 2**n, 2**n), }[mesh_type]
def test_correct_receiver_to_cell_location2D(): """Tests if the receivers where located in the correct cell""" comm = spyro.utils.mpi_init(model) model["opts"]["degree"] = 3 mesh, V = spyro.io.read_mesh(model, comm) model["acquisition"]["num_receivers"] = 3 recvs = spyro.create_transect((-0.1, 0.3), (-0.1, 0.9), 3) recvs = model["acquisition"]["receiver_locations"] = recvs receivers = spyro.Receivers(model, mesh, V, comm) # test 1 cell_vertex1 = receivers.cellVertices[0][0] cell_vertex2 = receivers.cellVertices[0][1] cell_vertex3 = receivers.cellVertices[0][2] x = receivers.receiver_locations[0, 0] y = receivers.receiver_locations[0, 1] p = (x, y) areaT = triangle_area(cell_vertex1, cell_vertex2, cell_vertex3) area1 = triangle_area(p, cell_vertex2, cell_vertex3) area2 = triangle_area(cell_vertex1, p, cell_vertex3) area3 = triangle_area(cell_vertex1, cell_vertex2, p) test1 = math.isclose((area1 + area2 + area3), areaT, rel_tol=1e-09) # test 2 cell_vertex1 = receivers.cellVertices[1][0] cell_vertex2 = receivers.cellVertices[1][1] cell_vertex3 = receivers.cellVertices[1][2] x = receivers.receiver_locations[1, 0] y = receivers.receiver_locations[1, 1] p = (x, y) areaT = triangle_area(cell_vertex1, cell_vertex2, cell_vertex3) area1 = triangle_area(p, cell_vertex2, cell_vertex3) area2 = triangle_area(cell_vertex1, p, cell_vertex3) area3 = triangle_area(cell_vertex1, cell_vertex2, p) test2 = math.isclose((area1 + area2 + area3), areaT, rel_tol=1e-09) # test 3 cell_vertex1 = receivers.cellVertices[2][0] cell_vertex2 = receivers.cellVertices[2][1] cell_vertex3 = receivers.cellVertices[2][2] x = receivers.receiver_locations[2, 0] y = receivers.receiver_locations[2, 1] p = (x, y) areaT = triangle_area(cell_vertex1, cell_vertex2, cell_vertex3) area1 = triangle_area(p, cell_vertex2, cell_vertex3) area2 = triangle_area(cell_vertex1, p, cell_vertex3) area3 = triangle_area(cell_vertex1, cell_vertex2, p) test3 = math.isclose((area1 + area2 + area3), areaT, rel_tol=1e-09) assert all([test1, test2, test3])
def test_correct_receiver_location_generation2D(): """Tests if receiver locations where generated correctly""" comm = spyro.utils.mpi_init(model) mesh, V = spyro.io.read_mesh(model, comm) receivers = spyro.create_transect((-0.1, 0.3), (-0.1, 0.9), 3) answer = np.array([[-0.1, 0.3], [-0.1, 0.6], [-0.1, 0.9]]) assert np.allclose(receivers, answer)
def test_correct_receiver_location_generation3D(): """Tests if receiver locations where generated correctly""" test_model = deepcopy(model3D) comm = spyro.utils.mpi_init(test_model) mesh, V = spyro.io.read_mesh(test_model, comm) test_model["acquisition"]["num_receivers"] = 3 receivers = spyro.create_transect((-0.05, 0.3, 0.5), (-0.05, 0.9, 0.5), 3) test_model["acquisition"]["receiver_locations"] = receivers receivers = spyro.Receivers(test_model, mesh, V, comm) answer = np.array([[-0.05, 0.3, 0.5], [-0.05, 0.6, 0.5], [-0.05, 0.9, 0.5]]) assert np.allclose(receivers.receiver_locations, answer)
1.000, # thickness of the pml in the z-direction (km) - always positive "lx": 1.000, # thickness of the pml in the x-direction (km) - always positive "ly": 0.0, # thickness of the pml in the y-direction (km) - always positive } acquisition = { "source_type": "Ricker", "frequency": 5.0, "delay": 1.0, "num_sources": 1, "source_pos": [(1.5, -0.5)], "amplitude": 1.0, "num_receivers": 100, "receiver_locations": create_transect((0.1, -2.90), (2.9, -2.90), 100), } timeaxis = { "t0": 0.0, # Initial time for event "tf": 2.0, # Final time for event "dt": 0.001, # timestep size "nspool": 9999, # how frequently to output solution to pvds "fspool": 1, # how frequently to save solution to RAM } # how freq. to output to files and screen inversion = { "freq_bands": [None] } # cutoff frequencies (Hz) for Ricker source and to low-pass the observed shot record # Create your model with all the options
def test_forward_5shots(): model = {} model["opts"] = { "method": "KMV", # either CG or KMV "quadrature": "KMV", # Equi or KMV "degree": 4, # p order "dimension": 2, # dimension } model["parallelism"] = { "type": "automatic", } model["mesh"] = { "Lz": 3.5, # depth in km - always positive "Lx": 17.0, # width in km - always positive "Ly": 0.0, # thickness in km - always positive "meshfile": "meshes/marmousi_5Hz.msh", "initmodel": None, "truemodel": "velocity_models/vp_marmousi-ii.hdf5", } model["BCs"] = { "status": True, # True or false "outer_bc": "non-reflective", # None or non-reflective (outer boundary condition) "damping_type": "polynomial", # polynomial, hyperbolic, shifted_hyperbolic "exponent": 2, # damping layer has a exponent variation "cmax": 4.5, # maximum acoustic wave velocity in PML - km/s "R": 1e-6, # theoretical reflection coefficient "lz": 0.9, # thickness of the PML in the z-direction (km) - always positive "lx": 0.9, # thickness of the PML in the x-direction (km) - always positive "ly": 0.0, # thickness of the PML in the y-direction (km) - always positive } model["acquisition"] = { "source_type": "Ricker", "source_pos": spyro.create_transect((-0.1, 1.0), (-0.1, 15.0), 5), "frequency": 5.0, "delay": 1.0, "receiver_locations": spyro.create_transect((-0.1, 1.0), (-0.1, 15.0),13), } model["timeaxis"] = { "t0": 0.0, # Initial time for event "tf": 3.00, # Final time for event "dt": 0.001, "amplitude": 1, # the Ricker has an amplitude of 1. "nspool": 100, # how frequently to output solution to pvds "fspool": 99999, # how frequently to save solution to RAM } dt=model["timeaxis"]["dt"] final_time=model["timeaxis"]["tf"] comm = spyro.utils.mpi_init(model) mesh, V = spyro.io.read_mesh(model, comm) vp = spyro.io.interpolate(model, mesh, V, guess=False) if comm.ensemble_comm.rank == 0: File("true_velocity.pvd", comm=comm.comm).write(vp) sources = spyro.Sources(model, mesh, V, comm) receivers = spyro.Receivers(model, mesh, V, comm) wavelet = spyro.full_ricker_wavelet( dt=model["timeaxis"]["dt"], tf=model["timeaxis"]["tf"], freq=model["acquisition"]["frequency"], ) p, p_r = spyro.solvers.forward(model, mesh, comm, vp, sources, wavelet, receivers) pass_error_test = False for source_id in range(len(model["acquisition"]["source_pos"])): if comm.ensemble_comm.rank == (source_id % comm.ensemble_comm.size): receiver_in_source_index= get_receiver_in_source_location(source_id, model) if source_id != len(model["acquisition"]["source_pos"])-1 or source_id == 0: receiver_comparison_index = receiver_in_source_index + 1 else: receiver_comparison_index = receiver_in_source_index - 1 error_percent = compare_velocity(p_r, receiver_in_source_index, receiver_comparison_index, model,dt) if error_percent < 5: pass_error_test = True print(f"For source = {source_id}: test = {pass_error_test}", flush = True) spyro.plots.plot_shots(model, comm, p_r, vmin=-1e-3, vmax=1e-3) spyro.io.save_shots(model, comm, p_r) assert pass_error_test
"cmax": 1.0, # maximum acoustic wave velocity in PML - km/s "R": 1e-6, # theoretical reflection coefficient "lz": 1.0, # thickness of the PML in the z-direction (km) - always positive "lx": 1.0, # thickness of the PML in the x-direction (km) - always positive "ly": 1.0, # thickness of the PML in the y-direction (km) - always positive } model["acquisition"] = { "source_type": "Ricker", "num_sources": 1, "source_pos": [(-0.1, 1.0, 1.0)], "frequency": 5.0, "delay": 1.0, "num_receivers": 300, "receiver_locations": spyro.create_transect( (-0.10, 0.1, 1.9), (-0.10, 0.1, 1.9), 300 ), } # Simulate for 1.0 seconds. model["timeaxis"] = { "t0": 0.0, # Initial time for event "tf": 1.0, # Final time for event "dt": 0.0005, # timestep size "amplitude": 1, # the Ricker has an amplitude of 1. "nspool": 100, # how frequently to output solution to pvds "fspool": 99999, # how frequently to save solution to RAM } # Note: nz, nx, and ny are obtained by dividing the dimensions 3 x 4 x 4 km # by your desired element size.
def test_gradient_AD(): model = {} model["opts"] = { "method": "KMV", # either CG or KMV "quadratrue": "KMV", # Equi or KMV "degree": 1, # p order "dimension": 2, # dimension "regularization": False, # regularization is on? "gamma": 1e-5, # regularization parameter } model["parallelism"] = { "type": "spatial", # options: automatic (same number of cores for evey processor) or spatial } # Define the domain size without the ABL. model["mesh"] = { "Lz": 1.5, # depth in km - always positive "Lx": 1.5, # width in km - always positive "Ly": 0.0, # thickness in km - always positive "meshfile": "not_used.msh", "initmodel": "not_used.hdf5", "truemodel": "not_used.hdf5", } # Specify a 250-m Absorbing Boundary Layer (ABL) on the three sides of the domain to damp outgoing waves. model["BCs"] = { "status": False, # True or False, used to turn on any type of BC "outer_bc": "non-reflective", # none or non-reflective (outer boundary condition) "abl_bc": "none", # none, gaussian-taper, or alid "lz": 0.25, # thickness of the ABL in the z-direction (km) - always positive "lx": 0.25, # thickness of the ABL in the x-direction (km) - always positive "ly": 0.0, # thickness of the ABL in the y-direction (km) - always positive } model["acquisition"] = { "source_type": "Ricker", "num_sources": 1, "source_pos": [(0.75, 0.75)], "frequency": 10.0, "delay": 1.0, "num_receivers": 10, "receiver_locations": spyro.create_transect((0.9, 0.2), (0.9, 0.8), 10), } model["Aut_Dif"] = { "status": True, } model["timeaxis"] = { "t0": 0.0, # Initial time for event "tf": 0.8, # Final time for event (for test 7) "dt": 0.001, # timestep size (divided by 2 in the test 4. dt for test 3 is 0.00050) "amplitude": 1, # the Ricker has an amplitude of 1. "nspool": 20, # (20 for dt=0.00050) how frequently to output solution to pvds "fspool": 1, # how frequently to save solution to RAM } comm = spyro.utils.mpi_init(model) mesh = RectangleMesh(100, 100, 1.5, 1.5) # to test FWI, mesh aligned with interface element = spyro.domains.space.FE_method(mesh, model["opts"]["method"], model["opts"]["degree"]) V = FunctionSpace(mesh, element) z, x = SpatialCoordinate(mesh) vp_exact = Function(V).interpolate(1.0 + 0.0 * x) vp_guess = Function(V).interpolate(0.8 + 0.0 * x) spyro.tools.gradient_test_acoustic_ad(model, mesh, V, comm, vp_exact, vp_guess)
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
"lz": 0.286, # thickness of the PML in the z-direction (km) - always positive "lx": 0.286, # thickness of the PML in the x-direction (km) - always positive "ly": 0.0, # thickness of the PML in the y-direction (km) - always positive } model["acquisition"] = { "source_type": "Ricker", "num_sources": 1, "source_pos": [(-5.72, 4.29)], "frequency": 5.0, "delay": 1.0, "num_receivers": 15, "receiver_locations": spyro.create_transect((-5.72, 6.29), (-5.72, 14.29), 15), } # Simulate for 1.0 seconds. model["timeaxis"] = { "t0": 0.0, # Initial time for event "tf": 4.0, # Final time for event "dt": 0.0005, # timestep size "amplitude": 1, # the Ricker has an amplitude of 1. "nspool": 400, # how frequently to output solution to pvds "fspool": 99999, # how frequently to save solution to RAM } comm = spyro.utils.mpi_init(model) ## Starting meshing procedure with seismic mesh. This can be done seperately in order to not have to
"lz": 0.20, # thickness of the PML in the z-direction (km) - always positive "lx": 0.20, # thickness of the PML in the x-direction (km) - always positive "ly": 0.0, # thickness of the PML in the y-direction (km) - always positive } acquisition = { "source_type": "Ricker", "num_sources": 1, "source_pos": [(-0.1, 0.5)], "frequency": 5.0, "delay": 1.0, "num_receivers": 100, "receiver_locations": spyro.create_transect((-0.95, 0.1), (-0.95, 0.9), 100), } timeaxis = { "t0": 0.0, # Initial time for event "tf": 1.0, # Final time for event "dt": 0.001, # timestep size "amplitude": 1, # the Ricker has an amplitude of 1. "nspool": 99999, # how frequently to output solution to pvds "fspool": 1, # how frequently to save solution to RAM } model_pml = { "self": None, "opts": opts, "BCs": BCs, "parallelism": parallelism,
from firedrake import File import time import numpy as np import spyro line1 = spyro.create_transect((0.25, 0.25), (0.25, 7.25), 4) line2 = spyro.create_transect((2.0, 0.25), (2.0, 7.25), 4) line3 = spyro.create_transect((3.75, 0.25), (3.75, 7.25), 4) line4 = spyro.create_transect((5.5, 0.25), (5.25, 7.25), 4) line5 = spyro.create_transect((7.25, 0.25), (7.25, 7.25), 4) lines = np.concatenate((line1, line2, line3, line4, line5)) sources = spyro.insert_fixed_value(lines, -0.10, 0) receivers = spyro.create_2d_grid(0.25, 7.25, 0.25, 7.25, 30) receivers = spyro.insert_fixed_value(receivers, -0.15, 0) model = {} model["opts"] = { "method": "KMV", # either CG or KMV "quadratrue": "KMV", # Equi or KMV "degree": 3, # p order "dimension": 3, # dimension } model["parallelism"] = {"type": "spatial"} # automatic", model["mesh"] = { "Lz": 5.175, # depth in km - always positive "Lx": 7.50, # width in km - always positive "Ly": 7.50, # thickness in km - always positive "meshfile": "meshes/overthrust_3D_true_model.msh",
} model["BCs"] = { "status": True, # True or false "outer_bc": "non-reflective", # None or non-reflective (outer boundary condition) "damping_type": "polynomial", # polynomial, hyperbolic, shifted_hyperbolic "exponent": 2, # damping layer has a exponent variation "cmax": 4.5, # maximum acoustic wave velocity in PML - km/s "R": 1e-6, # theoretical reflection coefficient "lz": 0.9, # thickness of the PML in the z-direction (km) - always positive "lx": 0.9, # thickness of the PML in the x-direction (km) - always positive "ly": 0.0, # thickness of the PML in the y-direction (km) - always positive } model["acquisition"] = { "source_type": "Ricker", "num_sources": 40, "source_pos": spyro.create_transect((-0.01, 1.0), (-0.01, 15.0), 40), "frequency": 5.0, "delay": 1.0, "num_receivers": 500, "receiver_locations": spyro.create_transect((-0.10, 0.1), (-0.10, 17.0), 500), } model["timeaxis"] = { "t0": 0.0, # Initial time for event "tf": 5.00, # Final time for event "dt": 0.001, "amplitude": 1, # the Ricker has an amplitude of 1. "nspool": 1000, # how frequently to output solution to pvds "fspool": 10, # how frequently to save solution to RAM "skip": 4, } comm = spyro.utils.mpi_init(model)
def test_correct_receiver_to_cell_location3D(): """Tests if the receivers where located in the correct cell""" test_model1 = deepcopy(model3D) comm = spyro.utils.mpi_init(test_model1) mesh, V = spyro.io.read_mesh(test_model1, comm) rec = spyro.create_transect((-0.05, 0.1, 0.5), (-0.05, 0.9, 0.5), 3) test_model1["acquisition"]["receiver_locations"] = rec test_model1["acquisition"]["num_receivers"] = 3 receivers = spyro.Receivers(test_model1, mesh, V, comm) # test 1 cell_vertex1 = receivers.cellVertices[0][0] cell_vertex2 = receivers.cellVertices[0][1] cell_vertex3 = receivers.cellVertices[0][2] cell_vertex4 = receivers.cellVertices[0][3] x = receivers.receiver_locations[0, 0] y = receivers.receiver_locations[0, 1] z = receivers.receiver_locations[0, 2] p = (x, y, z) volumeT = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3, cell_vertex4) volume1 = tetrahedral_volume(p, cell_vertex2, cell_vertex3, cell_vertex4) volume2 = tetrahedral_volume(cell_vertex1, p, cell_vertex3, cell_vertex4) volume3 = tetrahedral_volume(cell_vertex1, cell_vertex2, p, cell_vertex4) volume4 = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3, p) test1 = math.isclose((volume1 + volume2 + volume3 + volume4), volumeT, rel_tol=1e-09) # test 2 cell_vertex1 = receivers.cellVertices[1][0] cell_vertex2 = receivers.cellVertices[1][1] cell_vertex3 = receivers.cellVertices[1][2] cell_vertex4 = receivers.cellVertices[1][3] x = receivers.receiver_locations[1, 0] y = receivers.receiver_locations[1, 1] z = receivers.receiver_locations[1, 2] p = (x, y, z) volumeT = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3, cell_vertex4) volume1 = tetrahedral_volume(p, cell_vertex2, cell_vertex3, cell_vertex4) volume2 = tetrahedral_volume(cell_vertex1, p, cell_vertex3, cell_vertex4) volume3 = tetrahedral_volume(cell_vertex1, cell_vertex2, p, cell_vertex4) volume4 = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3, p) test2 = math.isclose((volume1 + volume2 + volume3 + volume4), volumeT, rel_tol=1e-09) # test 3 cell_vertex1 = receivers.cellVertices[2][0] cell_vertex2 = receivers.cellVertices[2][1] cell_vertex3 = receivers.cellVertices[2][2] cell_vertex4 = receivers.cellVertices[2][3] x = receivers.receiver_locations[2, 0] y = receivers.receiver_locations[2, 1] z = receivers.receiver_locations[2, 2] p = (x, y, z) volumeT = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3, cell_vertex4) volume1 = tetrahedral_volume(p, cell_vertex2, cell_vertex3, cell_vertex4) volume2 = tetrahedral_volume(cell_vertex1, p, cell_vertex3, cell_vertex4) volume3 = tetrahedral_volume(cell_vertex1, cell_vertex2, p, cell_vertex4) volume4 = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3, p) test3 = math.isclose((volume1 + volume2 + volume3 + volume4), volumeT, rel_tol=1e-09) assert all([test1, test2, test3])