def test_src_rec_coordinates(self): survey = surveys.Survey( sources=[ emg3d.TxElectricDipole((0, 0, 0, 0, 0)), emg3d.TxElectricDipole((100, 200, 300, 400, 500, 600)) ], receivers=[ emg3d.RxElectricPoint((1000, 0, 2000, 10, 0)), emg3d.RxElectricPoint((1000, 0, 2000, 0, 0), relative=True), emg3d.RxMagneticPoint((3000, 0, 2000, 0, 20)), ], frequencies=1, ) assert_allclose(survey.source_coordinates(), [[0, 150], [0, 350], [0, 550]]) assert_allclose(survey.receiver_coordinates(), [[1000, 1000, 1150, 3000], [0, 0, 350, 0], [2000, 2000, 2550, 2000]]) assert_allclose(survey.receiver_coordinates('TxED-2'), [[1000, 1150, 3000], [0, 350, 0], [2000, 2550, 2000]]) erec, _ = survey._irec_types assert_allclose(erec, [0, 1]) assert_allclose(survey._imrec, [2]) ecoo, mcoo = survey._rec_types_coord('TxED-1') assert_allclose( ecoo, ([1000., 1000.], [0., 0.], [2000., 2000.], [10., 0.], [0., 0.])) assert_allclose(mcoo, ([3000.], [0.], [2000.], [0.], [20.]))
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_copy(self, tmpdir): sources = emg3d.TxElectricDipole((0, 0, 0, 0, 0)) receivers = emg3d.RxElectricPoint((1000, 0, 0, 0, 0)) # This also checks to_dict()/from_dict(). srvy1 = surveys.Survey(sources, receivers, 1.0) # Set observed and standard deviation. srvy1.observed = [[[3 + 3j]]] srvy1.standard_deviation = np.array([[[1.1]]]) srvy2 = srvy1.copy() assert srvy1.sources == srvy2.sources srvy3 = surveys.Survey(sources, receivers, 1.0, [[[3 + 3j]]]) srvy4 = srvy3.copy() srvy4.standard_deviation = np.array([[[1.1]]]) assert srvy3.sources == srvy4.sources # Also check to_file()/from_file(). srvy4.to_file(tmpdir + '/test.npz') srvy5 = surveys.Survey.from_file(tmpdir + '/test.npz') assert srvy4.name == srvy5.name assert srvy4.sources == srvy5.sources assert srvy4.receivers == srvy5.receivers assert srvy4.frequencies == srvy5.frequencies assert_allclose(srvy4.data.observed, srvy5.data.observed) assert_allclose(srvy4.standard_deviation, srvy5.standard_deviation) srvy7 = surveys.Survey.from_file(tmpdir + '/test.npz', verb=-1) assert srvy5.name == srvy7[0].name assert 'Data loaded from' in srvy7[1]
def test_txrx_lists_to_dict(): electric = [emg3d.RxElectricPoint((x, 0, 0, 0, 0)) for x in [1000, 1100]] magnetic = surveys.txrx_coordinates_to_dict( emg3d.RxMagneticPoint, ([950, 1050, 1150], 0, 0, 0, 90)) streamer = emg3d.RxElectricPoint((5, 0, 0, 0, 0), relative=True) # If instance, it should give the instance in a dict. rec1 = surveys.txrx_lists_to_dict(streamer) assert streamer == rec1['RxEP-1'] # If dict, it should yield the same. rec2 = surveys.txrx_lists_to_dict(magnetic) assert magnetic['RxMP-1'] == rec2['RxMP-1'] rec3 = surveys.txrx_lists_to_dict([streamer, electric, magnetic]) assert rec3['RxEP-1'] == streamer assert rec3['RxEP-2'] == electric[0] assert rec3['RxEP-3'] == electric[1] assert rec3['RxMP-4'] == magnetic['RxMP-1'] assert rec3['RxMP-5'] == magnetic['RxMP-2'] assert rec3['RxMP-6'] == magnetic['RxMP-3'] rec4 = surveys.txrx_lists_to_dict((streamer, tuple(electric), magnetic)) assert rec3 == rec4
def test_dict_serialize_deserialize(): frequency = 1.0 grid = emg3d.TensorMesh([[2, 2], [3, 4], [0.5, 2]], (0, 0, 0)) field = emg3d.Field(grid) model = emg3d.Model(grid, 1) tx_e_d = emg3d.TxElectricDipole((0, 1000, 0, 0, -900, -950)) tx_m_d = emg3d.TxMagneticDipole([[0, 0, -900], [1000, 0, -950]]) tx_e_w = emg3d.TxElectricWire(([[0, 0, 0], [1, 1, 1], [1, 0, 1]])) rx_e_p = emg3d.RxElectricPoint((0, 1000, -950, 0, 20)) rx_m_p = emg3d.RxMagneticPoint((0, 1000, -950, 20, 0)) data = { 'Grid': grid, 'Model': model, 'Field': field, } if xarray: survey = emg3d.Survey( emg3d.surveys.txrx_lists_to_dict([tx_e_d, tx_m_d, tx_e_w]), emg3d.surveys.txrx_lists_to_dict([rx_e_p, rx_m_p]), frequency ) simulation = emg3d.Simulation(survey, model, gridding='same') data['Survey'] = survey data['Simulation'] = simulation # Get everything into a serialized dict. out = io._dict_serialize(data) # Get everything back. io._nonetype_to_none(out) keep = deepcopy(out) io._dict_deserialize(out) assert data.keys() == out.keys() assert out['Field'] == field assert out['Grid'] == grid assert out['Model'] == model if xarray: assert out['Survey'].sources == survey.sources assert (out['Simulation'].survey.receivers == simulation.survey.receivers) del keep['Grid']['hx'] with pytest.warns(UserWarning, match="Could not de-serialize"): io._dict_deserialize(keep)
def test_factor(self): sources = emg3d.TxElectricDipole((0, 3000, -950, 0, 0)) receivers = emg3d.RxElectricPoint((0, 3000, -1000, 0, 0)) # Adjusted x-domain. survey = emg3d.Survey( self.sources, receivers, self.frequencies, noise_floor=1e-15, relative_error=0.05) gdict = meshes.estimate_gridding_opts({}, self.model, survey) assert_allclose(gdict['domain']['x'], (-800, 800)) # Adjusted x-domain. survey = emg3d.Survey( sources, self.receivers, self.frequencies, noise_floor=1e-15, relative_error=0.05) gdict = meshes.estimate_gridding_opts({}, self.model, survey) assert_allclose(gdict['domain']['y'], (1500, 3500))
def test_misfit(): data = 1 syn = 5 rel_err = 0.05 sources = emg3d.TxElectricDipole((0, 0, 0, 0, 0)) receivers = emg3d.RxElectricPoint((5, 0, 0, 0, 0)) survey = emg3d.Survey( sources=sources, receivers=receivers, frequencies=100, data=np.zeros((1, 1, 1)) + data, relative_error=0.05, ) grid = emg3d.TensorMesh([np.ones(10) * 2, [2, 2], [2, 2]], (-10, -2, -2)) model = emg3d.Model(grid, 1) simulation = simulations.Simulation(survey=survey, model=model) field = emg3d.Field(grid, dtype=np.float64) field.field += syn simulation._dict_efield['TxED-1']['f-1'] = field simulation.data['synthetic'] = simulation.data['observed'] * 0 + syn misfit = 0.5 * ((syn - data) / (rel_err * data))**2 def dummy(): pass simulation.compute = dummy # => switch of compute() assert_allclose(simulation.misfit, misfit) # Missing noise_floor / std. survey = emg3d.Survey(sources, receivers, 100) simulation = simulations.Simulation(survey=survey, model=model) with pytest.raises(ValueError, match="Either `noise_floor` or"): simulation.misfit
def test_select(self): sources = [ emg3d.TxElectricDipole((x, 0, 0, 0, 0)) for x in [0, 50, 100] ] receivers = [ emg3d.RxElectricPoint((x, 0, 0, 0, 0)) for x in [1000, 1100, 1200, 1300, 1400] ] survey = surveys.Survey( sources, receivers, frequencies=(1.0, 2.0, 3.4, 4.0), data=np.arange(3 * 5 * 4).reshape((3, 5, 4)), noise_floor=np.ones((3, 5, 4)), relative_error=np.ones((3, 5, 4)), name='Test', ) t1 = survey.select('TxED-1', ['RxEP-1', 'RxEP-5'], 'f-1') assert t1.shape == (1, 2, 1) t2 = survey.select(frequencies=[], receivers='RxEP-1') assert t2.shape == (3, 1, 0)
class TestGradient: if xarray is not None: # Create a simple mesh. hx = np.ones(64) * 100 mesh = emg3d.TensorMesh([hx, hx, hx], origin=[0, 0, 0]) # Define a simple survey, including 1 el. & 1 magn. receiver survey = emg3d.Survey( sources=emg3d.TxElectricDipole((1680, 3220, 3210, 20, 5)), receivers=[ emg3d.RxElectricPoint((4751, 3280, 3220, 33, 14)), emg3d.RxMagneticPoint((4758, 3230, 3250, 15, 70)), ], frequencies=1.0, relative_error=0.01, ) # Background Model con_init = np.ones(mesh.shape_cells) # Target Model 1: One Block con_true = np.ones(mesh.shape_cells) con_true[27:37, 27:37, 15:25] = 0.001 model_init = emg3d.Model(mesh, con_init, mapping='Conductivity') model_true = emg3d.Model(mesh, con_true, mapping='Conductivity') # mesh.plot_3d_slicer(con_true) # For debug / QC, needs discretize sim_inp = { 'survey': survey, 'solver_opts': { 'plain': True, 'tol': 5e-5 }, # Red. tol 4 speed 'max_workers': 1, 'gridding': 'same', 'verb': 0, 'receiver_interpolation': 'linear', } # Compute data (pre-computed and passed to Survey above) sim_data = simulations.Simulation(model=model_true, **sim_inp) sim_data.compute(observed=True) 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_as_vs_fd_gradient(self, capsys): # Compute adjoint state misfit and gradient sim = simulations.Simulation(model=self.model_init, **self.sim_inp) data_misfit = sim.misfit grad = sim.gradient # For Debug / QC, needs discretize # from matplotlib.colors import LogNorm, SymLogNorm # mesh.plot_3d_slicer( # grad.ravel('F'), # pcolor_opts={ # 'cmap': 'RdBu_r', # 'norm': SymLogNorm(linthresh=1e-2, base=10, # vmin=-1e1, vmax=1e1)} # ) # We test a random cell from the inline xz slice, where the grad > 3. # # The NRMSD is (should) be below 1 %. However, (a) close to the # boundary, (b) in regions where the gradient is almost zero, and (c) # in regions where the gradient changes sign the NRMSD can become # large. This is mainly due to numerics, our coarse mesh, and the # reduced tolerance (which we reduced for speed). iy = 32 indices = np.argwhere(abs(grad[:, iy, :]) > 3) ix, iz = indices[np.random.randint(indices.shape[0])] nrmsd = alternatives.fd_vs_as_gradient((ix, iy, iz), self.model_init, grad, data_misfit, self.sim_inp) assert nrmsd < 0.3 @pytest.mark.skipif(discretize is None, reason="discretize not installed.") @pytest.mark.skipif(h5py is None, reason="h5py not installed.") def test_adjoint(self, tmpdir): sim = simulations.Simulation(model=self.model_init, file_dir=str(tmpdir), **self.sim_inp) v = np.random.rand(self.mesh.n_cells).reshape(self.mesh.shape_cells) w = np.random.rand(self.survey.size).reshape(self.survey.shape) wtJv = np.vdot(w, sim.jvec(v)).real vtJtw = np.vdot(v, sim.jtvec(w).ravel('F')) assert abs(wtJv - vtJtw) < 1e-10 @pytest.mark.skipif(discretize is None, reason="discretize not installed.") @pytest.mark.skipif(h5py is None, reason="h5py not installed.") def test_misfit(self, tmpdir): sim = simulations.Simulation(model=self.model_init, file_dir=str(tmpdir), **self.sim_inp) m0 = 2 * sim.model.property_x def func2(x): sim.model.property_x[...] = m0 return sim.jvec(x) def func1(x): sim.model.property_x[...] = x.reshape(sim.model.grid.shape_cells) sim.clean('computed') # Quick test that clean() removes the files assert len(os.listdir(tmpdir)) == 0 sim.compute() return sim.data.synthetic.data, func2 assert discretize.tests.check_derivative( func1, m0, plotIt=False, num=3, )
def test_print_solver(self, capsys): grid = emg3d.TensorMesh(h=[[(25, 10, -1.04), (25, 28), (25, 10, 1.04)], [(50, 8, -1.03), (50, 16), (50, 8, 1.03)], [(30, 8, -1.05), (30, 16), (30, 8, 1.05)]], origin='CCC') model = emg3d.Model(grid, property_x=1.5, property_y=1.8, property_z=3.3, mapping='Resistivity') sources = emg3d.TxElectricDipole((0, 0, 0, 0, 0)) receivers = [ emg3d.RxElectricPoint((x, 0, 0, 0, 0)) for x in [-10000, 10000] ] survey = emg3d.Survey( name='Test', sources=sources, receivers=receivers, frequencies=1.0, noise_floor=1e-15, relative_error=0.05, ) inp = { 'name': 'Test', 'survey': survey, 'model': model, 'gridding': 'same' } sol = { 'sslsolver': False, 'semicoarsening': False, 'linerelaxation': False, 'maxit': 1 } # Errors but verb=-1. _, _ = capsys.readouterr() # empty simulation = simulations.Simulation(verb=-1, **inp, solver_opts=sol) simulation.compute() out, _ = capsys.readouterr() assert out == "" # Errors with verb=0. out = simulation.print_solver_info('efield', verb=0, return_info=True) assert "= Source TxED-1; Frequency 1.0 Hz = MAX. ITERATION REAC" in out # Errors with verb=1. _, _ = capsys.readouterr() # empty simulation.print_solver_info('efield', verb=1) out, _ = capsys.readouterr() assert "= Source TxED-1; Frequency 1.0 Hz = 2.6e-02; 1; 0:00:" in out # No errors; solver-verb 3. simulation = simulations.Simulation(verb=1, **inp, solver_opts={'verb': 3}) simulation.compute() out, _ = capsys.readouterr() assert 'MG-cycle' in out assert 'CONVERGED' in out # No errors; solver-verb 0. simulation = simulations.Simulation(verb=1, **inp, solver_opts={'verb': 0}) simulation.compute() out, _ = capsys.readouterr() assert "= Source TxED-1; Frequency 1.0 Hz = CONVERGED" in out # Two sources, only compute 1, assure printing works. sources = [emg3d.TxElectricDipole((x, 0, 0, 0, 0)) for x in [0, 10]] survey = emg3d.Survey( name='Test', sources=sources, receivers=receivers, frequencies=1.0, noise_floor=1e-15, relative_error=0.05, ) inp = { 'name': 'Test', 'survey': survey, 'model': model, 'gridding': 'same' } simulation = simulations.Simulation(**inp, solver_opts={'verb': 0}) _ = simulation.get_efield('TxED-2', 'f-1') simulation.print_solver_info(verb=1) out, _ = capsys.readouterr() assert "= Source TxED-2; Frequency 1.0 Hz = CONVERGED" in out
def test_basics(self): # Coarse check with emg3d.solve and empymod. x = np.array([400, 450, 500, 550]) rec = (x, x * 0, 0, 20, 70) res = 0.3 src = (0, 0, 0, 0, 0) freq = 10 grid = emg3d.construct_mesh( frequency=freq, center=(0, 0, 0), properties=res, domain=[[0, 1000], [-25, 25], [-25, 25]], min_width_limits=20, ) model = emg3d.Model(grid, res) sfield = fields.get_source_field(grid, src, freq) efield = emg3d.solve(model, sfield, plain=True, verb=1) # epm = empymod.bipole(src, rec, [], res, freq, verb=1) epm = np.array([ -1.27832028e-11 + 1.21383502e-11j, -1.90064149e-12 + 7.51937145e-12j, 1.09602131e-12 + 3.33066197e-12j, 1.25359248e-12 + 1.02630145e-12j ]) e3d = fields.get_receiver(efield, rec) # 10 % is still OK, grid is very coarse for fast comp (2s) assert_allclose(epm, e3d, rtol=0.1) # Test with a list of receiver instance. rec_inst = [ emg3d.RxElectricPoint((rec[0][i], rec[1][i], *rec[2:])) for i in range(rec[0].size) ] e3d_inst = fields.get_receiver(efield, rec_inst) assert_allclose(e3d_inst, e3d) # Only one receiver e3d_inst = fields.get_receiver(efield, rec_inst[0]) assert_allclose(e3d_inst, e3d[0]) # Ensure cubic and linear are different; and that 'cubic' is default. e3d_inst2 = fields.get_receiver(efield, rec_inst[0], method='linear') assert abs(e3d_inst) != abs(e3d_inst2) # Ensure responses outside and in the last cell are set to NaN. h = np.ones(4) * 100 grid = emg3d.TensorMesh([h, h, h], (-200, -200, -200)) model = emg3d.Model(grid) sfield = fields.get_source_field(grid=grid, source=[0, 0, 0, 0, 0], frequency=10) out = emg3d.solve(model=model, sfield=sfield, plain=True, verb=0) off = np.arange(11) * 50 - 250 resp = out.get_receiver((off, off, off, 0, 0)) assert_allclose(np.isfinite(resp), np.r_[3 * [ False, ], 5 * [ True, ], 3 * [ False, ]]) # Also if linearly interpolated resp = out.get_receiver((off, off, off, 0, 0), method='linear') assert_allclose(np.isfinite(resp), np.r_[3 * [ False, ], 5 * [ True, ], 3 * [ False, ]])
class TestSaveLoad: frequency = 1.0 grid = emg3d.TensorMesh([[2, 2], [3, 4], [0.5, 2]], (0, 0, 0)) field = emg3d.Field(grid) model = emg3d.Model(grid, 1) tx_e_d = emg3d.TxElectricDipole((0, 1000, 0, 0, -900, -950)) tx_m_d = emg3d.TxMagneticDipole([[0, 0, -900], [1000, 0, -950]]) tx_e_w = emg3d.TxElectricWire(([[0, 0, 0], [1, 1, 1], [1, 0, 1]])) rx_e_p = emg3d.RxElectricPoint((0, 1000, -950, 0, 20)) rx_m_p = emg3d.RxMagneticPoint((0, 1000, -950, 20, 0)) a = np.arange(10.) b = 1+5j data = { 'Grid': grid, 'Model': model, 'Field': field, 'a': a, 'b': b, } if xarray: survey = emg3d.Survey( emg3d.surveys.txrx_lists_to_dict([tx_e_d, tx_m_d, tx_e_w]), emg3d.surveys.txrx_lists_to_dict([rx_e_p, rx_m_p]), frequency ) simulation = emg3d.Simulation(survey, model, gridding='same') data['Survey'] = survey data['Simulation'] = simulation def test_npz(self, tmpdir, capsys): io.save(tmpdir+'/test.npz', **self.data) outstr, _ = capsys.readouterr() assert 'Data saved to «' in outstr assert emg3d.__version__ in outstr # Save it with other verbosity. _, _ = capsys.readouterr() io.save(tmpdir+'/test.npz', **self.data, verb=0) outstr, _ = capsys.readouterr() assert outstr == "" out = io.save(tmpdir+'/test.npz', **self.data, verb=-1) assert 'Data saved to «' in out # Load it. out_npz = io.load(str(tmpdir+'/test.npz'), allow_pickle=True) outstr, _ = capsys.readouterr() assert 'Data loaded from «' in outstr assert 'test.npz' in outstr assert emg3d.__version__ in outstr assert out_npz['Model'] == self.model assert_allclose(out_npz['a'], self.a) assert out_npz['b'] == self.b assert_allclose(self.field.fx, out_npz['Field'].fx) assert_allclose(self.grid.cell_volumes, out_npz['Grid'].cell_volumes) # Load it with other verbosity. _, _ = capsys.readouterr() out = io.load(tmpdir+'/test.npz', verb=0) outstr, _ = capsys.readouterr() assert outstr == "" out, out_str = io.load(tmpdir+'/test.npz', verb=-1) assert 'Data loaded from «' in out_str def test_h5(self, tmpdir): if h5py: io.save(tmpdir+'/test.h5', **self.data) out_h5 = io.load(str(tmpdir+'/test.h5')) assert out_h5['Model'] == self.model assert_allclose(out_h5['a'], self.a) assert out_h5['b'] == self.b assert_allclose(self.field.fx, out_h5['Field'].fx) assert_allclose(self.grid.cell_volumes, out_h5['Grid'].cell_volumes) else: with pytest.warns(UserWarning, match='emg3d: This feature requir'): io.save(tmpdir+'/test.h5', grid=self.grid) def test_json(self, tmpdir): io.save(tmpdir+'/test.json', **self.data) out_json = io.load(str(tmpdir+'/test.json')) assert out_json['Model'] == self.model assert_allclose(out_json['a'], self.a) assert out_json['b'] == self.b assert_allclose(self.field.fx, out_json['Field'].fx) assert_allclose(self.grid.cell_volumes, out_json['Grid'].cell_volumes) def test_warnings(self, tmpdir, capsys): # Check message from loading another file data = io._dict_serialize({'meshes': self.grid}) fdata = io._dict_flatten(data) np.savez_compressed(tmpdir+'/test2.npz', **fdata) _ = io.load(str(tmpdir+'/test2.npz'), allow_pickle=True) outstr, _ = capsys.readouterr() assert "[version/format/date unknown; not created by emg" in outstr # Unknown keyword. with pytest.raises(TypeError, match="Unexpected "): io.load('ttt.npz', stupidkeyword='a') # Unknown extension. with pytest.raises(ValueError, match="Unknown extension '.abc'"): io.save(tmpdir+'/testwrongextension.abc', something=1) with pytest.raises(ValueError, match="Unknown extension '.abc'"): io.load(tmpdir+'/testwrongextension.abc')