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_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_fields(self, capsys): # Check sfield sfield = emg3d.get_source_field(self.grid, self.survey.sources['TxEW-3'], frequency=1.0) # Check efield efield, info = emg3d.solve(self.model, sfield, **self.simulation.solver_opts) assert self.simulation.get_efield('TxEW-3', 'f-1') == efield # See a single one self.simulation._dict_efield['TxEW-3'][1.0] = None _, _ = capsys.readouterr() self.simulation.get_efield('TxEW-3', 1.0) info = self.simulation.get_efield_info('TxEW-3', 1.0) assert 'MAX. ITERATION REACHED, NOT CONVERGED' in info['exit_message'] # Check hfield hfield = emg3d.get_magnetic_field(self.model, efield) assert self.simulation.get_hfield('TxEW-3', 1.0) == hfield s_hfield = self.simulation.get_hfield('TxEW-3', 1.0) assert s_hfield == hfield assert_allclose( self.simulation._dict_efield_info['TxEW-3']['f-1']['abs_error'], info['abs_error']) assert_allclose( self.simulation._dict_efield_info['TxEW-3']['f-1']['rel_error'], info['rel_error']) exit = self.simulation._dict_efield_info['TxEW-3']['f-1']['exit'] assert exit == info['exit'] == 1 # First hfield, ensure efield/hfield get computed. sim = self.simulation.copy(what='all') sim._dict_efield['TxEW-3']['f-1'] = None sim.get_hfield('TxEW-3', 'f-1') assert sim._dict_efield['TxEW-3']['f-1'] is not None
p.show() # %% # Calculate the resistivities # --------------------------- # # %% # Create model model = emg3d.utils.Model(grid, res) # Source field sfield = emg3d.utils.get_source_field(grid, src, freq, 0) # Calculate the efield pfield = emg3d.solve(grid, model, sfield, sslsolver=True, verb=3) # %% cgrid.plot_3d_slicer(pfield.fx[:, :, :-70].ravel('F'), zslice=-1000, view='abs', vType='Ex', clim=[1e-13, 1e-8], pcolorOpts={ 'cmap': 'viridis', 'norm': LogNorm() }) # %% emg3d.__version__
def test_gauss_seidel(njit): if njit: gauss_seidel = core.gauss_seidel gauss_seidel_x = core.gauss_seidel_x gauss_seidel_y = core.gauss_seidel_y gauss_seidel_z = core.gauss_seidel_z else: gauss_seidel = core.gauss_seidel.py_func gauss_seidel_x = core.gauss_seidel_x.py_func gauss_seidel_y = core.gauss_seidel_y.py_func gauss_seidel_z = core.gauss_seidel_z.py_func # At the moment we only compare `gauss_seidel_x/y/z` to `gauss_seidel`. # Better tests would always be welcomed... # Rotate the source, so we have a strong enough signal in all directions src = [0, 0, 0, 45, 45] freq = 0.9 nu = 2 # One back-and-forth for lr_dir in range(1, 4): # `gauss_seidel`/`_x/y/z` loop over z, then y, then x. Together with # `lr_dir`, we have to keep the dimension at 2 in order that they # agree. nx = [1, 4, 4][lr_dir - 1] ny = [4, 1, 4][lr_dir - 1] nz = [4, 4, 1][lr_dir - 1] # Get this grid. hx = helpers.widths(0, nx, 80, 1.1) hy = helpers.widths(0, ny, 100, 1.3) hz = helpers.widths(0, nz, 200, 1.2) grid = emg3d.TensorMesh( [hx, hy, hz], np.array([-hx.sum() / 2, -hy.sum() / 2, -hz.sum() / 2])) # Initialize model with some resistivities. property_x = np.arange(grid.n_cells) + 1 property_y = 0.5 * np.arange(grid.n_cells) + 1 property_z = 2 * np.arange(grid.n_cells) + 1 model = emg3d.Model(grid, property_x, property_y, property_z) # Initialize source field. sfield = emg3d.get_source_field(grid, src, freq) # Get volume-averaged model parameters. vmodel = emg3d.models.VolumeModel(model, sfield) # Run two iterations to get some e-field. efield = emg3d.solve(model, sfield, sslsolver=False, semicoarsening=False, linerelaxation=False, maxit=2, verb=1) inp = (sfield.fx, sfield.fy, sfield.fz, vmodel.eta_x, vmodel.eta_y, vmodel.eta_z, vmodel.zeta, grid.h[0], grid.h[1], grid.h[2], nu) # Get result from `gauss_seidel`. cfield = emg3d.Field(grid, efield.field.copy(), frequency=efield._frequency) gauss_seidel(cfield.fx, cfield.fy, cfield.fz, *inp) # Get result from `gauss_seidel_x/y/z`. if lr_dir == 1: gauss_seidel_x(efield.fx, efield.fy, efield.fz, *inp) elif lr_dir == 2: gauss_seidel_y(efield.fx, efield.fy, efield.fz, *inp) elif lr_dir == 3: gauss_seidel_z(efield.fx, efield.fy, efield.fz, *inp) # Check the resulting field. assert efield == cfield
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, ]])