def test_current_lr_dir(): hx = np.ones(4) grid = emg3d.TensorMesh([hx, hx, hx], (0, 0, 0)) # Big enough # Big enough, no change. for lr_dir in range(8): assert lr_dir == solver._current_lr_dir(lr_dir, grid) # Small in all directions => always 0 grid = emg3d.TensorMesh([[2, 2], [2, 2], [2, 2]], (0, 0, 0)) for lr_dir in range(8): assert 0 == solver._current_lr_dir(lr_dir, grid) # Small in y, z grid = emg3d.TensorMesh([hx, [2, 2], [2, 2]], (0, 0, 0)) for lr_dir in [0, 1]: assert lr_dir == solver._current_lr_dir(lr_dir, grid) for lr_dir in [2, 3, 4]: assert 0 == solver._current_lr_dir(lr_dir, grid) for lr_dir in [5, 6, 7]: assert 1 == solver._current_lr_dir(lr_dir, grid) # Small in z grid = emg3d.TensorMesh([hx, hx, [2, 2]], (0, 0, 0)) for lr_dir in [0, 1, 2, 6]: assert lr_dir == solver._current_lr_dir(lr_dir, grid) assert 0 == solver._current_lr_dir(3, grid) assert 2 == solver._current_lr_dir(4, grid) assert 1 == solver._current_lr_dir(5, grid) assert 6 == solver._current_lr_dir(7, grid)
def test_runs_warnings(self): # The interpolation happens in maps.interp_spline_3d. # Here we just check the 'other' things: warning and errors, and that # it is composed correctly. # Check cubic spline runs fine (NOT CHECKING ACTUAL VALUES!. grid = emg3d.TensorMesh( [np.ones(4), np.array([1, 2, 3, 1]), np.array([2, 1, 1, 1])], [0, 0, 0]) field = fields.Field(grid) field.field = np.ones( field.field.size) + 1j * np.ones(field.field.size) grid = emg3d.TensorMesh( [np.ones(6), np.array([1, 1, 2, 3, 1]), np.array([1, 2, 1, 1, 1])], [-1, -1, -1]) efield = fields.Field(grid, frequency=1) n = efield.field.size efield.field = np.ones(n) + 1j * np.ones(n) # Provide wrong rec_loc input: with pytest.raises(ValueError, match='`receiver` needs to be in the'): fields.get_receiver(efield, (1, 1, 1))
def test_nearest(self): # Assert it is 'nearest' or extrapolate if points are outside. tgrid = emg3d.TensorMesh( [np.array([1, 1, 1, 1]), np.array([1, 1, 1, 1]), np.array([1, 1, 1, 1])], origin=np.array([0., 0, 0])) tmodel = np.ones(tgrid.n_cells).reshape(tgrid.shape_cells, order='F') tmodel[:, 0, :] = 2 t2grid = emg3d.TensorMesh( [np.array([1]), np.array([1]), np.array([1])], origin=np.array([2, -1, 2])) # Nearest with cubic. out = maps.interpolate(tgrid, tmodel, t2grid, 'cubic') assert_allclose(out, 2.) # Same, but with log. vlog = maps.interpolate(tgrid, tmodel, t2grid, 'cubic', log=True) vlin = maps.interpolate(tgrid, np.log10(tmodel), t2grid, 'cubic') assert_allclose(vlog, 10**vlin) # Extrapolate with linear. out = maps.interpolate(tgrid, tmodel, t2grid, 'linear') assert_allclose(out, 3.) # Same, but with log. vlog = maps.interpolate(tgrid, tmodel, t2grid, 'linear', log=True) vlin = maps.interpolate(tgrid, np.log10(tmodel), t2grid, 'linear') assert_allclose(vlog, 10**vlin) # Assert it is 0 if points are outside. out = maps.interpolate(tgrid, tmodel, t2grid, 'cubic', False) assert_allclose(out, 0.) out = maps.interpolate(tgrid, tmodel, t2grid, 'linear', False) assert_allclose(out, 0.)
def test_interp_volume_average(njit): if njit: interp_volume_average = maps.interp_volume_average else: interp_volume_average = maps.interp_volume_average.py_func # Comparison to alt_version. grid_in = emg3d.TensorMesh( [np.ones(30), np.ones(20)*5, np.ones(10)*10], origin=np.array([0, 0, 0])) grid_out = emg3d.TensorMesh( [np.arange(7)+1, np.arange(13)+1, np.arange(13)+1], origin=np.array([0.5, 3.33, 5])) values = np.arange(grid_in.n_cells, dtype=np.float64).reshape( grid_in.shape_cells, order='F') points = (grid_in.nodes_x, grid_in.nodes_y, grid_in.nodes_z) new_points = (grid_out.nodes_x, grid_out.nodes_y, grid_out.nodes_z) # Compute volume. vol = np.outer(np.outer( grid_out.h[0], grid_out.h[1]).ravel('F'), grid_out.h[2]) vol = vol.ravel('F').reshape(grid_out.shape_cells, order='F') # New solution. new_values = np.zeros(grid_out.shape_cells, dtype=values.dtype) interp_volume_average(*points, values, *new_points, new_values, vol) # Old solution. new_values_alt = np.zeros(grid_out.shape_cells, dtype=values.dtype) alternatives.alt_volume_average( *points, values, *new_points, new_values_alt) assert_allclose(new_values, new_values_alt)
def test_current_sc_dir(): hx = np.ones(4) grid = emg3d.TensorMesh([hx, hx, hx], (0, 0, 0)) # Big enough # Big enough, no change. for sc_dir in range(4): assert sc_dir == solver._current_sc_dir(sc_dir, grid) # Small in all directions => always 0 grid = emg3d.TensorMesh([[2, 2], [2, 2], [2, 2]], (0, 0, 0)) for sc_dir in range(4): assert 6 == solver._current_sc_dir(sc_dir, grid) # Small in y, z grid = emg3d.TensorMesh([hx, [2, 2], [2, 2]], (0, 0, 0)) assert 4 == solver._current_sc_dir(0, grid) assert 6 == solver._current_sc_dir(1, grid) assert 4 == solver._current_sc_dir(2, grid) assert 4 == solver._current_sc_dir(3, grid) # Small in x, z grid = emg3d.TensorMesh([[2, 2], hx, [2, 2]], (0, 0, 0)) assert 5 == solver._current_sc_dir(0, grid) assert 5 == solver._current_sc_dir(1, grid) assert 6 == solver._current_sc_dir(2, grid) assert 5 == solver._current_sc_dir(3, grid)
def test_volume_average_weights(njit): if njit: volume_avg_weights = maps._volume_average_weights else: volume_avg_weights = maps._volume_average_weights.py_func grid_in = emg3d.TensorMesh( [np.ones(11), np.ones(10)*2, np.ones(3)*10], origin=np.array([0, 0, 0])) grid_out = emg3d.TensorMesh( [np.arange(4)+1, np.arange(5)+1, np.arange(6)+1], origin=np.array([0.5, 3.33, 5])) wx, ix_in, ix_out = volume_avg_weights(grid_in.nodes_x, grid_out.nodes_x) assert_allclose(wx, [0.5, 0.5, 0.5, 1, 0.5, 0.5, 1, 1, 0.5, 0.5, 1, 1, 1, 0.5]) assert_allclose(ix_in, [0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10]) assert_allclose(ix_out, [0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3]) wy, iy_in, iy_out = volume_avg_weights(grid_in.nodes_y, grid_out.nodes_y) assert_allclose(wy, [0.67, 0.33, 1.67, 0.33, 1.67, 1.33, 0.67, 2., 1.33, 0.67, 2, 2, 0.33]) assert_allclose(iy_in, [1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9]) assert_allclose(iy_out, [0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]) wz, iz_in, iz_out = volume_avg_weights(grid_in.nodes_z, grid_out.nodes_z) assert_allclose(wz, [1, 2, 2, 1, 4, 5, 6]) assert_allclose(iz_in, [0, 0, 0, 1, 1, 1, 2]) assert_allclose(iz_out, [0, 1, 2, 2, 3, 4, 5]) w, inp, out = volume_avg_weights(x_i=np.array([0., 5, 7, 10]), x_o=np.array([-1., 1, 4, 6, 7, 11])) assert_allclose(w, [1, 1, 3, 1, 1, 1, 3, 1]) assert_allclose(inp, [0, 0, 0, 0, 1, 1, 2, 2]) assert_allclose(out, [0, 0, 1, 2, 2, 3, 4, 4])
def test_restrict_weights(njit): if njit: restrict_weights = core.restrict_weights else: restrict_weights = core.restrict_weights.py_func # 1. Simple example following equation 9, [Muld06]_. edges = np.array([0., 500, 1200, 2000, 3000]) width = (edges[1:] - edges[:-1]) centr = edges[:-1] + width / 2 c_edges = edges[::2] c_width = (c_edges[1:] - c_edges[:-1]) c_centr = c_edges[:-1] + c_width / 2 # Result wtl = np.array([350 / 250, 250 / 600, 400 / 900]) wt0 = np.array([1., 1., 1.]) wtr = np.array([350 / 600, 500 / 900, 400 / 500]) # Result from implemented function wl, w0, wr = restrict_weights(edges, centr, width, c_edges, c_centr, c_width) assert_allclose(wtl, wl) assert_allclose(wt0, w0) assert_allclose(wtr, wr) # 2. Test with stretched grid and compare with alternative formulation # Create a highly stretched, non-centered grid hx = helpers.widths(2, 2, 200, 1.8) hy = helpers.widths(0, 8, 800, 1.2) hz = helpers.widths(0, 4, 400, 1.4) grid = emg3d.TensorMesh([hx, hy, hz], np.array([-100000, 3000, 100])) # Create coarse grid thereof ch = [ np.diff(grid.nodes_x[::2]), np.diff(grid.nodes_y[::2]), np.diff(grid.nodes_z[::2]) ] cgrid = emg3d.TensorMesh(ch, origin=grid.origin) # Compute the weights in a numpy-way, instead of numba-way wl, w0, wr = alternatives.alt_restrict_weights(grid.nodes_x, grid.cell_centers_x, grid.h[0], cgrid.nodes_x, cgrid.cell_centers_x, cgrid.h[0]) # Get the implemented numba-result wxl, wx0, wxr = restrict_weights(grid.nodes_x, grid.cell_centers_x, grid.h[0], cgrid.nodes_x, cgrid.cell_centers_x, cgrid.h[0]) # Compare assert_allclose(wxl, wl) assert_allclose(wx0, w0) assert_allclose(wxr, wr)
def test_all_run(self): hx = [1, 1, 1, 2, 4, 8] grid = emg3d.TensorMesh([hx, hx, hx], (0, 0, 0)) grid2 = emg3d.TensorMesh([[2, 4, 5], [1, 1], [4, 5]], (0, 1, 0)) field = emg3d.Field(grid) field.fx = np.arange(1, field.fx.size+1).reshape( field.fx.shape, order='F') model = emg3d.Model(grid, 1, 2, 3) model.property_x[1, :, :] = 2 model.property_x[2, :, :] = 3 model.property_x[3, :, :] = 4 model.property_x[4, :, :] = np.arange(1, 37).reshape((6, 6), order='F') model.property_x[5, :, :] = 200 xi = (1, [8, 7, 6, 8, 9], [1]) # == NEAREST == # property - grid _ = maps.interpolate(grid, model.property_x, grid2, method='nearest') # field - grid _ = maps.interpolate(grid, field.fx, grid2, method='nearest') # property - points _ = maps.interpolate(grid, model.property_x, xi, method='nearest') # field - points _ = maps.interpolate(grid, field.fx, xi, method='nearest') # == LINEAR == # property - grid _ = maps.interpolate(grid, model.property_x, grid2, method='linear') # field - grid _ = maps.interpolate(grid, field.fx, grid2, method='linear') # property - points _ = maps.interpolate(grid, model.property_x, xi, method='linear') # field - points _ = maps.interpolate(grid, field.fx, xi, method='linear') # == CUBIC == # property - grid _ = maps.interpolate(grid, model.property_x, grid2, method='cubic') # field - grid _ = maps.interpolate(grid, field.fx, grid2, method='cubic') # property - points _ = maps.interpolate(grid, model.property_x, xi, method='cubic') # field - points _ = maps.interpolate(grid, field.fx, xi, method='cubic') # == VOLUME == # property - grid _ = maps.interpolate(grid, model.property_x, grid2, method='volume') # field - grid with pytest.raises(ValueError, match="for cell-centered properties"): maps.interpolate(grid, field.fx, grid2, method='volume') # property - points with pytest.raises(ValueError, match="only implemented for TensorM"): maps.interpolate(grid, model.property_x, xi, method='volume') # field - points with pytest.raises(ValueError, match="only implemented for TensorM"): maps.interpolate(grid, field.fx, xi, method='volume')
def test_all_alternatives_mag(self): h = np.ones(20) * 20 grid = emg3d.TensorMesh([h, h, h], (-200, -200, -200)) h = [2, 1, 1, 2] grid = emg3d.TensorMesh([h, h, h], (-3, -3, -3)) vfield = fields._point_vector_magnetic(grid, (0, 0, 0, 0, 0), None) src = emg3d.electrodes.TxMagneticPoint((0, 0, 0, 0, 0)) sfield = fields.get_source_field(grid, src, frequency=None) assert_allclose(sfield.field, vfield.field)
def test_interpolate_to_grid(self): # We only check here that it gives the same as calling the function # itself; the rest should be tested in interpolate(). grid1 = emg3d.TensorMesh( [np.ones(8), np.ones(8), np.ones(8)], (0, 0, 0)) grid2 = emg3d.TensorMesh([[2, 2, 2, 2], [3, 3], [4, 4]], (0, 0, 0)) ee = fields.Field(grid1) ee.field = np.ones(ee.field.size) + 2j * np.ones(ee.field.size) e2 = ee.interpolate_to_grid(grid2) assert_allclose(e2.field, 1 + 2j)
def test_decimals(self): h1 = [2, 1, 1, 2] h2 = [2, 1.04, 1.04, 2] grid1 = emg3d.TensorMesh([h1, h1, h1], (-3, -3, -3)) grid2 = emg3d.TensorMesh([h2, h2, h2], (-3, -3, -3)) source = np.array([[-0.5, 0, 0], [0.5, 0, 0]]) sfield1 = fields._dipole_vector(grid1, source) sfield2a = fields._dipole_vector(grid2, source, decimals=1) sfield2b = fields._dipole_vector(grid2, source) assert_allclose(sfield1.fx, sfield2a.fx) with pytest.raises(AssertionError, match='Not equal to tolerance'): assert_allclose(sfield1.fx, sfield2b.fx)
def test_get_magnetic_field(): # Check it does still the same (pure regression). dat = REGRES['reg_2'] model = dat['model'] efield = dat['result'] hfield = dat['hresult'] hout = fields.get_magnetic_field(model, efield) assert_allclose(hfield.field, hout.field) # Add some mu_r - Just 1, to trigger, and compare. dat = REGRES['res'] efield = dat['Fresult'] model1 = emg3d.Model(**dat['input_model']) model2 = emg3d.Model(**dat['input_model'], mu_r=1.) hout1 = fields.get_magnetic_field(model1, efield) hout2 = fields.get_magnetic_field(model2, efield) assert_allclose(hout1.field, hout2.field) # Test division by mu_r. model3 = emg3d.Model(**dat['input_model'], mu_r=2.) hout3 = fields.get_magnetic_field(model3, efield) assert_allclose(hout1.field, hout3.field * 2) # Comparison to alternative. # Using very unrealistic value, unrealistic stretching, to test. grid = emg3d.TensorMesh(h=[[1, 100, 25, 33], [1, 1, 33.3, 0.3, 1, 1], [2, 4, 8, 16]], origin=(88, 20, 9)) model = emg3d.Model(grid, mu_r=np.arange(1, grid.n_cells + 1) / 10) new = 10**np.arange(grid.n_edges) - grid.n_edges / 2 efield = fields.Field(grid, data=new, frequency=np.pi) hfield_nb = fields.get_magnetic_field(model, efield) hfield_np = alternatives.alt_get_magnetic_field(model, efield) assert_allclose(hfield_nb.fx, hfield_np.fx) assert_allclose(hfield_nb.fy, hfield_np.fy) assert_allclose(hfield_nb.fz, hfield_np.fz) # Test using discretize if discretize: h = np.ones(4) grid = emg3d.TensorMesh([h * 200, h * 300, h * 400], (0, 0, 0)) model = emg3d.Model(grid, property_x=3.24) sfield = fields.get_source_field(grid, (350, 550, 750, 30, 30), frequency=10) efield = emg3d.solve(model, sfield, plain=True, verb=0) mfield = fields.get_magnetic_field(model, efield).field dfield = grid.edge_curl * efield.field / sfield.smu0 assert_allclose(mfield, dfield)
def test_get_restriction_weights(): x = [500, 700, 800, 1000] cx = [1200, 1800] y = [2, 2, 2, 2] cy = [4, 4] grid = emg3d.TensorMesh([x, y, x], (0, 0, 0)) cgrid = emg3d.TensorMesh([cx, cy, cx], (0, 0, 0)) # 1. Simple example following equation 9, [Muld06]_. wxl = np.array([350 / 250, 250 / 600, 400 / 900]) wx0 = np.array([1., 1., 1.]) wxr = np.array([350 / 600, 500 / 900, 400 / 500]) wyl = np.array([1, 0.5, 0.5]) wy0 = np.array([1., 1., 1.]) wyr = np.array([0.5, 0.5, 1]) wdl = np.array([0., 0., 0., 0., 0.]) # dummy wd0 = np.array([1., 1., 1., 1., 1.]) # dummy wdr = np.array([0., 0., 0., 0., 0.]) # dummy for i in [0, 5, 6]: wx, wy, wz = solver._get_restriction_weights(grid, cgrid, i) if i not in [5, 6]: assert_allclose(wxl, wx[0]) assert_allclose(wx0, wx[1]) assert_allclose(wxr, wx[2]) else: assert_allclose(wdl, wx[0]) assert_allclose(wd0, wx[1]) assert_allclose(wdr, wx[2]) if i != 6: assert_allclose(wyl, wy[0]) assert_allclose(wy0, wy[1]) assert_allclose(wyr, wy[2]) else: assert_allclose(wdl, wy[0]) assert_allclose(wd0, wy[1]) assert_allclose(wdr, wy[2]) if i != 5: assert_allclose(wxl, wz[0]) assert_allclose(wx0, wz[1]) assert_allclose(wxr, wz[2]) else: assert_allclose(wdl, wz[0]) assert_allclose(wd0, wz[1]) assert_allclose(wdr, wz[2])
def test_errors(self): mesh = emg3d.TensorMesh([[2, 2], [2, 2], [2, 2]], origin=(-1, -1, -1)) survey = emg3d.Survey( sources=emg3d.TxElectricDipole((-1.5, 0, 0, 0, 0)), receivers=emg3d.RxElectricPoint((1.5, 0, 0, 0, 0)), frequencies=1.0, relative_error=0.01, ) sim_inp = { 'survey': survey, 'gridding': 'same', 'receiver_interpolation': 'linear' } # Anisotropic models. simulation = simulations.Simulation(model=emg3d.Model(mesh, 1, 2, 3), **sim_inp) with pytest.raises(NotImplementedError, match='for isotropic models'): simulation.gradient # Model with electric permittivity. simulation = simulations.Simulation(model=emg3d.Model(mesh, epsilon_r=3), **sim_inp) with pytest.raises(NotImplementedError, match='for el. permittivity'): simulation.gradient # Model with magnetic permeability. simulation = simulations.Simulation(model=emg3d.Model( mesh, mu_r=np.ones(mesh.shape_cells) * np.pi), **sim_inp) with pytest.raises(NotImplementedError, match='for magn. permeabili'): simulation.gradient
def test_2d_arrays(self): hx = [1, 1, 1, 2, 4, 8] grid = emg3d.TensorMesh([hx, hx, hx], (0, 0, 0)) field = emg3d.Field(grid) field.fx = np.arange(1, field.fx.size+1).reshape( field.fx.shape, order='F') model = emg3d.Model(grid, 1, 2, 3) model.property_x[1, :, :] = 2 model.property_x[2, :, :] = 3 model.property_x[3, :, :] = 4 model.property_x[4, :, :] = np.arange(1, 37).reshape((6, 6), order='F') model.property_x[5, :, :] = 200 xi = (np.ones((3, 2)), 5, np.ones((3, 2))) # == NEAREST == # property - points _ = maps.interpolate(grid, model.property_x, xi, method='nearest') # field - points _ = maps.interpolate(grid, field.fx, xi, method='nearest') # == LINEAR == # property - points _ = maps.interpolate(grid, model.property_x, xi, method='linear') # field - points _ = maps.interpolate(grid, field.fx, xi, method='linear') # == CUBIC == # property - points _ = maps.interpolate(grid, model.property_x, xi, method='cubic') # field - points _ = maps.interpolate(grid, field.fx, xi, method='cubic')
def test_basics_diag(self): h = [2, 1, 1, 2] grid = emg3d.TensorMesh([h, h, h], (-3, -3, -3)) # Diagonal source in the middle source = np.array([[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]]) vfield = fields._dipole_vector(grid, source) # x: exact in the middle on the two edges assert_allclose(vfield.fx[1:-2, 1:-2, 1:-2].ravel(), [0.03125, 0.09375, 0.09375, 0.28125]) # compare lower-left-front with upper-right-back assert_allclose(vfield.fx[1:-2, 1:-2, 1:-2].ravel(), vfield.fx[2:-1, 2:-1, 2:-1].ravel()[::-1]) # Source is 3D symmetric, compare all fields are the same assert_allclose(vfield.fx[1:-2, 1:-2, 1:-2].ravel(), vfield.fy[1:-2, 1:-2, 1:-2].ravel()) assert_allclose(vfield.fx[1:-2, 1:-2, 1:-2].ravel(), vfield.fz[1:-2, 1:-2, 1:-2].ravel()) assert_allclose(vfield.fx[2:-1, 2:-1, 2:-1].ravel(), vfield.fy[2:-1, 2:-1, 2:-1].ravel()) assert_allclose(vfield.fx[2:-1, 2:-1, 2:-1].ravel(), vfield.fz[2:-1, 2:-1, 2:-1].ravel())
def test_broadcasting(self): grid = emg3d.TensorMesh( [np.ones(4), np.ones(2), np.ones(6)], (0, 0, 0)) model = models.Model(grid, 1, 1, 1, 1, 1) assert_allclose(model.property_x, model.property_y) assert_allclose(model.property_x, model.property_z) assert_allclose(model.property_x, model.mu_r) assert_allclose(model.property_x, model.epsilon_r) model.property_x = [[[1.]], [[2.]], [[3.]], [[4.]]] assert_allclose(model.property_x[:, 0, 0], [1, 2, 3, 4]) model.property_y = [[[ 1, ], [ 2, ]]] assert_allclose(model.property_y[0, :, 0], [1, 2]) model.property_z = [[[1, 2., 3., 4., 5., 6.]]] assert_allclose(model.property_z[0, 0, :], [1, 2, 3, 4, 5, 6]) model.mu_r = 3.33 assert_allclose(model.mu_r, 3.33) data = np.arange(1, 4 * 2 * 6 + 1).reshape((4, 2, 6), order='F') model.epsilon_r = data assert_allclose(model.epsilon_r, data)
def test_interpolate(self): # Create some dummy data grid = emg3d.TensorMesh( [np.array([2, 2]), np.array([4, 4]), np.array([5, 5])], np.zeros(3)) grid2 = emg3d.TensorMesh([np.array( [2]), np.array([4]), np.array([5])], np.array([1, 2, 2.5])) property_x = helpers.dummy_field(*grid.shape_cells, False) property_y = property_x / 2.0 property_z = property_x * 1.4 mu_r = property_x * 1.11 epsilon_r = property_x * 3.33 model1inp = models.Model(grid, property_x) same = model1inp.interpolate_to_grid(model1inp.grid) assert model1inp == same model1out = model1inp.interpolate_to_grid(grid2) assert_allclose(model1out.property_x[0], 10**(np.sum(np.log10(model1inp.property_x)) / 8)) assert model1out.property_y is None assert model1out.property_z is None assert model1out.epsilon_r is None assert model1out.mu_r is None model2inp = models.Model(grid, property_x=property_x, property_y=property_y, property_z=property_z, mu_r=mu_r, epsilon_r=epsilon_r) model2out = model2inp.interpolate_to_grid(grid2) assert_allclose(model2out.property_x[0], 10**(np.sum(np.log10(model2inp.property_x)) / 8)) assert_allclose(model2out.property_y[0], 10**(np.sum(np.log10(model2inp.property_y)) / 8)) assert_allclose(model2out.property_z[0], 10**(np.sum(np.log10(model2inp.property_z)) / 8)) assert_allclose(model2out.epsilon_r, 10**(np.sum(np.log10(model2inp.epsilon_r)) / 8)) assert_allclose(model2out.mu_r, 10**(np.sum(np.log10(model2inp.mu_r)) / 8))
def test_warnings(self): h = np.ones(4) grid = emg3d.TensorMesh([h, h, h], (0, 0, 0)) source = np.array([[5, 2, 2], [2, 2, 2]]) with pytest.raises(ValueError, match='Provided source outside grid'): fields._dipole_vector(grid, source) source = np.array([[2, 2, 2], [2, 2, 2]]) with pytest.raises(ValueError, match='Provided finite dipole'): fields._dipole_vector(grid, source) # This is a warning that should never be raised... hx, x0 = np.ones(4), -2 grid = emg3d.TensorMesh([hx, hx, hx], (x0, x0, x0)) source = np.array([[-2, 2, 0], [0, -2, 0]]) with pytest.warns(UserWarning, match="Normalizing Source: 1.25000000"): fields._dipole_vector(grid, source, 30)
def test_rel_abs_rec(self): # Sources sources = emg3d.surveys.txrx_coordinates_to_dict( emg3d.TxElectricDipole, ([0, 100, 200], 0, 0, 0, 0)) # Abs and rel Receivers a_e_rec = emg3d.surveys.txrx_coordinates_to_dict( emg3d.RxElectricPoint, (1000 + np.arange(3) * 100, 0, -100, 0, 0)) r_e_rec = emg3d.surveys.txrx_coordinates_to_dict(emg3d.RxElectricPoint, (1000, 0, -100, 0, 0), relative=True) a_h_rec = emg3d.surveys.txrx_coordinates_to_dict( emg3d.RxMagneticPoint, (1000 + np.arange(3) * 100, 0, -100, 0, 0)) r_h_rec = emg3d.surveys.txrx_coordinates_to_dict(emg3d.RxMagneticPoint, (1000, 0, -100, 0, 0), relative=True) receivers = emg3d.surveys.txrx_lists_to_dict( [a_e_rec, r_e_rec, a_h_rec, r_h_rec]) # Frequencies frequencies = (1.0) survey = emg3d.Survey(sources, receivers, frequencies, name='TestSurv', noise_floor=1e-15, relative_error=0.05) # Create a simple grid and model grid = emg3d.TensorMesh( [np.ones(32) * 250, np.ones(16) * 500, np.ones(16) * 500], np.array([-1250, -1250, -2250])) model = emg3d.Model(grid, 1) # Create a simulation, compute all fields. simulation = simulations.Simulation(survey, model, name='TestSim', max_workers=1, solver_opts={ 'maxit': 1, 'verb': 0, 'plain': True }, gridding='same') simulation.compute() # Relative receivers must be same as corresponding absolute receivers assert_allclose( [simulation.data.synthetic[i, i, 0].data for i in range(3)], simulation.data.synthetic[:, 3, 0].data) assert_allclose( [simulation.data.synthetic[i, i + 4, 0].data for i in range(3)], simulation.data.synthetic[:, 7, 0].data)
def test_amat_x(njit): if njit: amat_x = core.amat_x else: amat_x = core.amat_x.py_func # 1. Compare to alternative amat_x # Create a grid src = [200, 300, -50., 5, 60] hx = helpers.widths(8, 4, 100, 1.2) hy = np.ones(8) * 800 hz = np.ones(4) * 500 grid = emg3d.TensorMesh(h=[hx, hy, hz], origin=np.array( [-hx.sum() / 2, -hy.sum() / 2, -hz.sum() / 2])) # Create some resistivity model x = np.arange(1, grid.shape_cells[0] + 1) * 2 y = 1 / np.arange(1, grid.shape_cells[1] + 1) z = np.arange(1, grid.shape_cells[2] + 1)[::-1] / 10 property_x = np.outer(np.outer(x, y), z).ravel() freq = 0.319 model = emg3d.Model(grid=grid, property_x=property_x, property_y=0.8 * property_x, property_z=2 * property_x) # Create a source field sfield = emg3d.get_source_field(grid=grid, source=src, frequency=freq) # Get volume-averaged model parameters. vmodel = emg3d.models.VolumeModel(model, sfield) # Run two iterations to get a e-field efield = emg3d.solve(model=model, sfield=sfield, sslsolver=False, semicoarsening=False, linerelaxation=False, maxit=2, verb=1) # amat_x rr1 = emg3d.Field(grid) amat_x(rr1.fx, rr1.fy, rr1.fz, efield.fx, efield.fy, efield.fz, vmodel.eta_x, vmodel.eta_y, vmodel.eta_z, vmodel.zeta, grid.h[0], grid.h[1], grid.h[2]) # amat_x - alternative rr2 = emg3d.Field(grid) alternatives.alt_amat_x(rr2.fx, rr2.fy, rr2.fz, efield.fx, efield.fy, efield.fz, vmodel.eta_x, vmodel.eta_y, vmodel.eta_z, vmodel.zeta, grid.h[0], grid.h[1], grid.h[2]) # Check all fields (ex, ey, and ez) assert_allclose(-rr1.field, rr2.field, atol=1e-23)
def test_grid_provided(self): # Check bad grid hx = np.ones(17) * 20 grid = emg3d.TensorMesh([hx, hx, hx], (0, 0, 0)) with pytest.warns(UserWarning, match='optimal for MG solver. Good n'): simulations.Simulation(self.survey, self.model, gridding='input', gridding_opts=grid)
def test_get_receiver(self): # We only check here that it gives the same as calling the function # itself; the rest should be tested in get_receiver(). grid1 = emg3d.TensorMesh( [np.ones(8), np.ones(8), np.ones(8)], (0, 0, 0)) ee = fields.Field(grid1) ee.field = np.arange(ee.field.size) + 2j * np.arange(ee.field.size) resp = ee.get_receiver((4, 4, 4, 0, 0)) assert_allclose(resp, 323.5 + 647.0j)
def test_linear(self): igrid = emg3d.TensorMesh( [np.array([1, 1]), np.array([1, 1, 1]), np.array([1, 1, 1])], [0, -1, -1]) ogrid = emg3d.TensorMesh( [np.array([1]), np.array([1]), np.array([1])], [0.5, 0, 0]) values = np.r_[9*[1.0, ], 9*[2.0, ]].reshape(igrid.shape_cells) # Simple, linear example. out = maps.interpolate( grid=igrid, values=values, xi=ogrid, method='linear') assert_allclose(out[0, 0, 0], 1.5) # Provide ogrid.gridCC. ogrid._gridCC = np.array([[0.5, 0.5, 0.5]]) out2 = maps.interpolate(igrid, values, ogrid, 'linear') assert_allclose(out2[0, 0, 0], 1.5)
def test_sc_0(self): sc = 0 # Simple test with restriction followed by prolongation. src = [150, 150, 150, 0, 45] grid = emg3d.TensorMesh( [np.ones(4) * 100, np.ones(4) * 100, np.ones(4) * 100], origin=np.zeros(3)) # Create dummy model and fields, parameters don't matter. model = emg3d.Model(grid, 1, 1, 1, 1) sfield = emg3d.get_source_field(grid, src, 1) # Get volume-averaged model parameters. vmodel = emg3d.models.VolumeModel(model, sfield) rx = np.arange(sfield.fx.size, dtype=np.complex128).reshape(sfield.fx.shape) ry = np.arange(sfield.fy.size, dtype=np.complex128).reshape(sfield.fy.shape) rz = np.arange(sfield.fz.size, dtype=np.complex128).reshape(sfield.fz.shape) field = np.r_[rx.ravel('F'), ry.ravel('F'), rz.ravel('F')] rr = emg3d.Field(grid, field) # Restrict it cmodel, csfield, cefield = solver.restriction(vmodel, sfield, rr, sc_dir=sc) assert_allclose(csfield.fx[:, 1:-1, 1], np.array([[196. + 0.j], [596. + 0.j]])) assert_allclose(csfield.fy[1:-1, :, 1], np.array([[356. + 0.j, 436. + 0.j]])) assert_allclose(csfield.fz[1:-1, 1:-1, :], np.array([[[388. + 0.j, 404. + 0.j]]])) assert cmodel.grid.shape_nodes[0] == cmodel.grid.shape_nodes[1] == 3 assert cmodel.grid.shape_nodes[2] == 3 assert cmodel.eta_x[0, 0, 0] / 8. == vmodel.eta_x[0, 0, 0] assert np.sum(grid.h[0]) == np.sum(cmodel.grid.h[0]) assert np.sum(grid.h[1]) == np.sum(cmodel.grid.h[1]) assert np.sum(grid.h[2]) == np.sum(cmodel.grid.h[2]) # Add pi to the coarse e-field efield = emg3d.Field(grid) cefield.field += np.pi # Prolong it solver.prolongation(efield, cefield, sc_dir=sc) assert np.all(efield.fx[:, 1:-1, 1:-1] == np.pi) assert np.all(efield.fy[1:-1, :, 1:-1] == np.pi) assert np.all(efield.fz[1:-1, 1:-1, :] == np.pi)
def test_source(): p1 = [[0, 0, 0], [1, 0, 0]] strength = np.pi freq = 1.234 s1 = electrodes.Source(strength, coordinates=p1) assert s1.strength == strength assert s1._prefix == 'So' grid = emg3d.TensorMesh([[1, 1], [1, 1], [1, 1]], (0, 0, 0)) sfield = emg3d.fields.get_source_field(grid, s1, freq) assert s1.get_field(grid, freq) == sfield
def test_print_gs_info(capsys): var = solver.MGParameters(verb=5, cycle='F', sslsolver=False, linerelaxation=False, semicoarsening=False, shape_cells=(16, 8, 2)) grid = emg3d.TensorMesh([[1, 1], [1, 1], [1, 1]], (0, 0, 0)) solver._print_gs_info(var, 1, 2, 3, grid, 0.01, 'test') out, _ = capsys.readouterr() assert out == " 1 2 3 [ 2, 2, 2]: 1.000e-02 test\n"
def test_basics_xdir_on_x(self): h = [2, 1, 1, 2] grid = emg3d.TensorMesh([h, h, h], (-3, -3, -3)) # x-directed source in the middle vfield = fields._point_vector(grid, (0, 0, 0, 0, 0)) # x: exact in the middle on the two edges assert_allclose(vfield.fx[1:-1, 2:-2, 2:-2].ravel(), [0.5, 0.5]) # y: as exact "on" x-grid, falls to the right assert_allclose(vfield.fy[1:-1, 2:-1, 2:-2].ravel(), 0) # z: as exact "on" x-grid, falls to top assert_allclose(vfield.fz[1:-1, 2:-2, 2:-1].ravel(), 0)
def test_basics_xdir_on_x(self): h = [2, 1, 1, 2] grid = emg3d.TensorMesh([h, h, h], (-3, -3, -3)) # x-directed source in the middle vfield = fields._point_vector_magnetic(grid, (0, 0, 0, 0, 0), None) # x: exact in the middle on the two edges assert_allclose(vfield.fx, 0) # y: as exact "on" x-grid, falls to the right assert_allclose(abs(vfield.fy[2:-2, 1:-1, 1:-1:2]), 0.25) # z: as exact "on" x-grid, falls to top assert_allclose(abs(vfield.fz[2:-2, 1:-1:2, 1:-1]), 0.25)
def test_equal_mapping(self): # Create some dummy data grid = emg3d.TensorMesh( [np.array([2, 2]), np.array([3, 4]), np.array([0.5, 2])], np.zeros(3)) model1 = models.Model(grid) model2 = models.Model(grid, mapping='Conductivity') check = model1 == model2 assert check is False